11

ユーザーがアプリケーションの WebView のタグをクリックしたときに、assets フォルダーからサウンドを再生しようとしています。リンクの拡張子を検出するために WebViewClient を拡張する新しいクラスを使用できることがわかりました。リンクの拡張子が mp3 ファイルの場合は、デフォルトの Audio Player を介して再生できます。しかし、新しいアクティビティを開始せずに、アクティビティ内で再生したいのです。

次のリンクを参照として使用しました: Webview のサウンド および資産内の Uri またはファイルを使用して MediaPlayer を作成中にエラーが発生しました

しかし、うまくいきませんでした。

そのために次のコードを使用してみました。

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


    }

}

getAssets() で未定義のメソッド エラーが発生しました。Google で調べてみたところ、Context の受け渡しについて何かが表示されています。私はAndroidとオブジェクト指向プログラミングに非常に慣れていないので、これが正しい方法であるかどうか、そしてコンテキストとは何かについての簡単な説明があるかどうか疑問に思っています. ありがとうございました。

以下は私の完全なコードです:

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


}

編集

したがって、コードはhttps://stackoverflow.com/users/488241/squonkのおかげで機能しますが、別の問題が発生したため、MyWebViewClient を次のように更新しました。

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

しかし、java.io.FileNotFoundException が発生しますが、パスは正しいようです。assets/webpages/sounds/1.mp3 と assets/webpages/1.mp3 に 2 つの mp3 ファイルを配置し、次の html コードを使用してテストしました。

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

しかし、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)

ファイルの呼び出し方法に何か問題がありますか? 前にありがとう。

解決した

squonk の提案に感謝します。次のコードを試してみましたが、うまくいきました。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;
        }   
    }
}

そしてそれをテストするためのhtml:

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

繰り返しクリックするとエラーが発生しましたが、それは別の質問です:D 質問を閉じるにはどうすればよいですか? >.<

4

1 に答える 1

3

MediaPLayerinを宣言する場所MyWebViewClientに、次を追加します...

public class MyWebViewClient extends WebViewClient{

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

    ...
}

次に、次のようにコンストラクターを追加MyWebViewClientします...

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

次に、shouldOverrideUrlLoading(...)次のようにアセットを取得します...

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

あなたのMainActivityセットでは、次のようWebViewClientに渡しますthis(これは ActivityContextです)...

webMain.setWebViewClient(new MyWebViewClient(this));

また、URL が '.mp3' で終わる場合は、falseから戻る必要があります。これは、処理していることを示しており、'ホスト' アプリケーションはストック Web ブラウザーのインスタンスを開始するべきではありません。shouldOverrideUrlLoading(...)WebView

編集:アセット ディレクトリからオーディオ ファイルを再生するには、データ ソースを別の方法で設定する必要があります

mp.prepare()また、電話する前に電話する必要がありますmp.start()

于 2012-06-10T06:08:45.983 に答える