2012-06-10 38 views
8

Tôi đang cố gắng phát âm thanh từ thư mục nội dung khi người dùng nhấp vào một thẻ trên WebView của ứng dụng của tôi. Tôi thấy rằng tôi có thể sử dụng một lớp mới mở rộng WebViewClient để phát hiện phần mở rộng của một liên kết và nếu nó là một tập tin mp3 nó có thể chơi nó thông qua mặc định Audio Player. Nhưng tôi muốn nó chơi trong hoạt động mà không bắt đầu một hoạt động mới.Android: Phát Âm thanh Tài sản Sử dụng WebView

tôi đã sử dụng các liên kết sau đây là tài liệu tham khảo: Sound in WebviewError creating MediaPlayer with Uri or file in assets

Nhưng nó đã không làm việc.

tôi đã cố gắng sử dụng các mã sau đây để làm như vậy:

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; 
     } 


    } 

} 

tôi nhận được một lỗi không xác định phương pháp trên getAssets(), tôi đã cố gắng googleing nó và nó nói điều gì đó về đi qua một bối cảnh. Tôi rất mới với Android và lập trình hướng đối tượng, vì vậy tôi tự hỏi nếu điều này đúng cách để làm điều đó và nếu có một lời giải thích đơn giản về những gì một bối cảnh là. Cảm ơn bạn.

Dưới đây là mã hoàn chỉnh của tôi:

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

Vì vậy, các mã làm việc nhờ https://stackoverflow.com/users/488241/squonk nhưng bây giờ vấn đề khác xảy ra, tôi cập nhật các MyWebViewClient vào như sau:

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; 
     } 
    } 
} 

Nhưng tôi nhận được một java.io.FileNotFoundException, đường dẫn có vẻ đúng mặc dù. Tôi đã đặt 2 file mp3 vào tài sản/trang web/âm thanh/1.mp3 và tài sản/trang web/1.mp3 và sử dụng các mã html sau đây để kiểm tra nó:

<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> 

Nhưng tôi nhận được lỗi sau trên 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ó điều gì sai với cách tôi gọi tệp không? Cam ơn trươc.

SOLVED

Thx để gợi ý squonk, tôi đã thử các mã sau đây để làm cho nó hoạt động và nó làm việc tốt, cảm ơn bạn 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; 
     } 
    } 
} 

Và html để kiểm tra nó:

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

Mặc dù tôi đã nhận được một lỗi nếu tôi liên tục nhấp vào nó, nhưng đó là một câu hỏi khác: D như thế nào câu hỏi một chặt chẽ của một người? >. <

Trả lời

3

đâu bạn khai báo của bạn MediaPLayer trong MyWebViewClient, thêm dòng sau ...

public class MyWebViewClient extends WebViewClient{ 

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

    ... 
} 

Sau đó thêm một constructor để MyWebViewClient như sau ...

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

Sau đó, trong shouldOverrideUrlLoading(...) có được tài sản của bạn như sau ...

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

Trong MainActivity bạn thiết lập các WebViewClient bằng cách thông qua this (đó là Hoạt động Context) như sau ...

webMain.setWebViewClient(new MyWebViewClient(this)); 

Bạn cũng phải trả lại false từ shouldOverrideUrlLoading(...) nếu t url của anh ta kết thúc bằng '.mp3' - điều này cho thấy WebView của bạn đang xử lý mọi thứ và ứng dụng 'máy chủ' không được bắt đầu một phiên bản của trình duyệt web chứng khoán.

EDIT: Để phát tệp âm thanh từ thư mục nội dung, bạn cần đặt nguồn dữ liệu khác nhau - xem câu trả lời được chấp nhận cho play-audio-file-from-the-assets-directory.

Ngoài ra, bạn nên gọi mp.prepare() trước khi gọi mp.start().

+0

Chà, cảm ơn ít nhất là chạy ngay bây giờ, thưa bạn là huyền thoại .. hãy chờ nó .. dary! Nhưng khi tôi nhấp vào liên kết 1 và 3 nó sẽ nhận được một java.oi.FileNotFoundException, có vẻ như đường dẫn trên liên kết sai>. Trong khi liên kết 2 nó chỉ mở trang web không có sẵn. Có cách nào để phát âm thanh trong tệp nội dung hoặc phải ở trong tệp thô hoặc sdcard không? –

+0

@RanggaWiratno: Xem EDIT ở cuối câu trả lời của tôi. – Squonk

+0

Vâng thực sự tôi đã thử những điều sau đây quá. Tôi đã thêm các tham số trên afd và thêm mp.prepare() và afd.close() trước mp.start() sau khi đọc http://droidapp.co.uk/?p=272 nhưng điều kỳ lạ là, tôi vẫn nhận được java.io.FileNotFoundException mặc dù đường dẫn là đúng. Tôi đã cố gắng rối tung với html nhưng vẫn không thể có được nó ngay File Asset
Same Folder. Tôi đã đặt 2 tệp để thử nghiệm, trong nội dung> trang web> 1.mp3 và nội dung> trang web> âm thanh> 1.mp3 –

Các vấn đề liên quan