2012-06-10 12 views
8

Sto provando a riprodurre un suono dalla cartella delle risorse quando un utente fa clic su un tag sulla vista Web della mia applicazione. Ho scoperto che posso utilizzare una nuova classe che estende WebViewClient per rilevare l'estensione di un collegamento e se è un file mp3 può riprodurlo tramite il lettore audio predefinito. Ma voglio che giochi all'interno dell'attività senza iniziare una nuova attività.Android: riproduzione di un suono della risorsa tramite WebView

ho usato i seguenti link come riferimenti: Sound in Webview e Error creating MediaPlayer with Uri or file in assets

Ma non ha funzionato.

Ho provato ad utilizzare i seguenti codici per farlo:

package com.rangga.test.webview.sound; 

import android.content.Intent; 
import android.content.res.AssetFileDescriptor; 
import android.media.MediaPlayer; 
import android.net.Uri; 
import android.webkit.WebView; 
import android.webkit.WebViewClient; 

public class MyWebViewClient extends WebViewClient{ 

    public MediaPlayer mp; 

    @Override 
    public boolean shouldOverrideUrlLoading(WebView view, String url){ 
     if(url.endsWith(".mp3")){ 
      mp = new MediaPlayer(); 
      AssetFileDescriptor afd = getAssets().openFd(url); 
      mp.setDataSource(afd.getFileDescriptor()); 
      mp.start(); 

      return true; 
     }else{ 
      return true; 
     } 


    } 

} 

ottengo un errore metodo non definito sulle getAssets(), ho provato googleing e dice qualcosa che riguarda il superamento di un contesto. Sono molto nuovo per Android e programmazione orientata agli oggetti, quindi mi chiedo se questo è il modo giusto per farlo e se c'è una semplice spiegazione su cosa sia un contesto. Grazie.

Qui di seguito sono i miei codici completi:

MainActivity.class

package com.rangga.test.webview.sound; 

import android.app.Activity; 
import android.os.Bundle; 
import android.webkit.WebView; 

public class MainActivity extends Activity { 

    WebView webMain; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     webMain = (WebView) findViewById(R.id.webMain); 

     webMain.loadUrl("file:///android_asset/webpages/test.html"); 
     webMain.setWebViewClient(new MyWebViewClient()); 
    } 


} 

EDIT

Così i codici funziona grazie a https://stackoverflow.com/users/488241/squonk ma ora un altro problema si verifica, ho aggiornato il MyWebViewClient nella seguenti:

package com.rangga.test.webview.sound; 

import java.io.IOException; 

import android.content.Context; 
import android.content.res.AssetFileDescriptor; 
import android.media.MediaPlayer; 
import android.webkit.WebView; 
import android.webkit.WebViewClient; 

public class MyWebViewClient extends WebViewClient{ 

    public MediaPlayer mp; 
    private Context context = null; 

    public MyWebViewClient(Context c){ 
     this.context = c; 
    } 

    @Override 
    public boolean shouldOverrideUrlLoading(WebView view, String url){ 
     if(url.endsWith(".mp3")){ 

      mp = new MediaPlayer(); 
      try { 
       AssetFileDescriptor afd = context.getAssets().openFd(url); 
       mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
       afd.close(); 
       mp.prepare(); 
       mp.start(); 
      } catch (IllegalArgumentException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IllegalStateException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


      return true; 
     }else{ 
      return true; 
     } 
    } 
} 

Ma ottengo un java.io.FileNotFoundException, il percorso sembra giusto. Ho messo 2 file mp3 in attività/pagine web/suoni/1.mp3 e delle attività/pagine web/1.mp3 e utilizzati i seguenti codici HTML per testarlo:

<html> 
    <head> 
     <title>Test Audio</title> 
    </head> 
    <body> 
     <a href="file:///android_asset/webpages/sounds/1.mp3">File Asset</a><br/> 
     <a href="1.mp3">Same Folder</a> 
    </body> 
</html> 

Ma ottengo il seguente errore su LogCat :

06-11 06:20:37.955: W/System.err(377): java.io.FileNotFoundException: file:///android_asset/webpages/1.mp3 
06-11 06:20:37.966: W/System.err(377): at android.content.res.AssetManager.openAssetFd(Native Method) 
06-11 06:20:37.974: W/System.err(377): at android.content.res.AssetManager.openFd(AssetManager.java:314) 
06-11 06:20:37.974: W/System.err(377): at com.rangga.test.webview.sound.MyWebViewClient.shouldOverrideUrlLoading(MyWebViewClient.java:30) 
06-11 06:20:37.985: W/System.err(377): at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:193) 
06-11 06:20:38.000: W/System.err(377): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:304) 
06-11 06:20:38.005: W/System.err(377): at android.os.Handler.dispatchMessage(Handler.java:99) 
06-11 06:20:38.005: W/System.err(377): at android.os.Looper.loop(Looper.java:123) 
06-11 06:20:38.014: W/System.err(377): at android.app.ActivityThread.main(ActivityThread.java:4363) 
06-11 06:20:38.014: W/System.err(377): at java.lang.reflect.Method.invokeNative(Native Method) 
06-11 06:20:38.024: W/System.err(377): at java.lang.reflect.Method.invoke(Method.java:521) 
06-11 06:20:38.024: W/System.err(377): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
06-11 06:20:38.024: W/System.err(377): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
06-11 06:20:38.054: W/System.err(377): at dalvik.system.NativeStart.main(Native Method) 

C'è qualcosa di sbagliato nel modo in cui ho chiamato il file? Grazie in anticipo.

risolto

Thx ai suggerimenti di Squonk, ho provato i seguenti codici per farlo funzionare e ha funzionato bene, grazie Squonk!

package com.rangga.test.webview.sound; 

import java.io.IOException; 

import android.content.Context; 
import android.content.res.AssetFileDescriptor; 
import android.media.MediaPlayer; 
import android.util.Log; 
import android.webkit.WebView; 
import android.webkit.WebViewClient; 

public class MyWebViewClient extends WebViewClient{ 

    public MediaPlayer mp; 
    private Context context = null; 

    public MyWebViewClient(Context c){ 
     this.context = c; 
     mp = new MediaPlayer(); 
    } 

    @Override 
    public boolean shouldOverrideUrlLoading(WebView view, String url){ 
     if(url.endsWith(".mp3")){ 
      url = url.replace("file:///android_asset/webpages/", ""); 
      Log.i("MyWebViewClient", url); 
      try { 
       AssetFileDescriptor afd = context.getAssets().openFd(url); 
       mp = new MediaPlayer(); 
       mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
       afd.close(); 
       mp.prepare(); 
       mp.start(); 
      } catch (IllegalArgumentException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IllegalStateException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


      return true; 
     }else{ 
      return true; 
     } 
    } 
} 

E il codice html per testarlo:

<html> 
    <head> 
     <title>Test Audio</title> 
    </head> 
    <body> 
     <a href="webpages/1.mp3">File Asset</a><br/> 
    </body> 
</html> 

Anche se ho avuto un errore se più volte lo scatto, ma questa è un'altra domanda: D Come si fa a chiusura di una domanda? >. <

risposta

3

Dove si dichiara la MediaPLayer in MyWebViewClient, aggiungere il seguente ...

public class MyWebViewClient extends WebViewClient{ 

    public MediaPlayer mp; 
    private Context context = null; // Add this line 

    ... 
} 

quindi aggiungere un costruttore per MyWebViewClient come segue ...

public MyWebViewClient(Context context) { 
    this.context = context; 
} 

Poi, nel shouldOverrideUrlLoading(...) ottenere le vostre attività, come segue ...

AssetFileDescriptor afd = context.getAssets().openFd(url); 

Nella tua MainActivity impostare l'WebViewClient passando this (che è l'attività Context) nel modo seguente ...

webMain.setWebViewClient(new MyWebViewClient(this)); 

Anche si dovrebbe restituire false da shouldOverrideUrlLoading(...) se t l'URL termina con ".mp3" - questo mostra che il tuo WebView sta gestendo le cose e l'applicazione "host" non dovrebbe avviare un'istanza del browser web di riserva.

MODIFICA: Per riprodurre file audio dalla directory delle risorse, è necessario impostare l'origine dati in modo diverso - vedere la risposta accettata allo play-audio-file-from-the-assets-directory.

Inoltre, è necessario chiamare mp.prepare() prima di chiamare mp.start().

+0

Wow, grazie, almeno corri adesso, signore, sei una leggenda .. aspetta .. Dario! Ma quando faccio clic sui link 1 e 3 ottiene un java.oi.FileNotFoundException, sembra che il percorso sul link sia sbagliato>.

+0

@RanggaWiratno: vedere l'EDIT alla fine della mia risposta. – Squonk

+0

Sì, in realtà ho provato anche quanto segue. Ho aggiunto i parametri su afd e aggiunto mp.prepare() e afd.close() prima di mp.start() dopo aver letto questo http://droidapp.co.uk/?p=272 ma la cosa strana è, ho ancora il java.io.FileNotFoundException anche se il percorso è giusto. Ho provato a fare scherzi con l'html, ma non riesco ancora a farlo bene. File Asset
e Same Folder. Ho messo 2 file per testarlo, in risorse> pagine web> 1.mp3 e risorse> pagine web> suoni> 1.mp3 –

Problemi correlati