2013-05-06 15 views
16

タイトルはほとんどの場合です。MediaPlayerのsetDataSourceが、ファイルパスで設定された着信音のステータス= 0x80000000で失敗しました。2.3.4

私のアプリケーションはsetDataSource(fileInfo)setDataSource(mContext, Uri.parse(fileInfo))の両方を使用して(SDカード上のカスタム着信音のために、私は信じている)content://media/internal/audio/media/387またはcontent://media/external/audio/media/1655のようなURIで指さ着メロを果たしてきました。

いずれの場合も、Android 4.x(異なるバージョン)を使用している携帯電話では、setDataSource failed.: status=0x80000000の例外についての情報がログに記録されています。エラーが唯一のコンテンツのURIによって指さ着信音にではなく、パスが指す単一のファイルに何が起こる、私は(まだsetDataSource(mContext, Uri.parse(fileInfo))を使用している間)は、上記の携帯電話上の問題を修正だけでなく、着メロのパスを使用することを決定したことを見て

/system/media/audio/ringtones/TwirlAway.oggのようなパスでファイルに対して setDataSource failed.: status=0x80000000:私は例外を除いて、いくつかのログを受け取った

  • は、しかしそれは(ない鉱山2.3.3にかかわらず)のAndroid 2.3.4-2.3.6と携帯電話で問題を開始しました

  • 私はwhat=1extra=-2147483648とのメソッドコールMediaPlayer.onErrorListener.onError(int what, int extra)についてもログを受け取りました。私の知るところでは、ファイルが見つからないか、破損していると思われます。しかし、私は、このような状況で

    File file = new File(fileInfo); 
    if (!file.exists()) 
    

チェックを実行し、それがファイルが存在しないことを返された - それは、破損していますか?内部メモリの音楽ファイルはほとんどありません。要約する

setDataSource("content://media/internal/audio/media/52")

    • 作品は例外をスロー:setDataSource(mContext, "/system/media/audio/ringtones/TwirlAway.ogg")

    ためsetDataSource failed.: status=0x80000000興味深いことに、setDataSource(Context context, Uri uri)によって呼び出されるsetDataSource(Context context, Uri uri, Headers headers)方法の最初の数行は、(from GrepCode source for 2.3.4)です。

    String scheme = uri.getScheme(); 
        if(scheme == null || scheme.equals("file")) { 
         setDataSource(uri.getPath()); 
         return; 
        } 
    

    結局のところ、setDataSource("/system/media/audio/ringtones/TwirlAway.ogg")で失敗します。私はurisからringtonesへの道を取ってきました:

    private static String getRingtonePathFromContentUri(Context context, 
         Uri contentUri) { 
    
        String[] proj = { MediaStore.Audio.Media.DATA }; 
        Cursor ringtoneCursor = context.getContentResolver().query(contentUri, 
          proj, null, null, null); 
        ringtoneCursor.moveToFirst(); 
        return ringtoneCursor.getString(ringtoneCursor 
          .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); 
    } 
    

    何がエラー投げの原因になりますか?たぶん、これらは読み込み権限の不足によって引き起こされるいくつかの問題ですか? ネイティブのsetDataSource(文字列パス)関数のソースコードが大いに役立つと思いますが、それを見つけることができませんでした。

  • 答えて

    9

    回答が最も役に立ちました。

    これに苦労している人は、ここでは6ヶ月以上使用していて、もうエラーはほとんど報告されていないコードがあります。明示的なセットにあなたが持っている

    /system/media/audio/alarms/Walk_in_the_forest.ogg

    content://media/internal/audio/media/20

    public static void setMediaPlayerDataSource(Context context, 
         MediaPlayer mp, String fileInfo) throws Exception { 
    
        if (fileInfo.startsWith("content://")) { 
         try { 
          Uri uri = Uri.parse(fileInfo); 
          fileInfo = getRingtonePathFromContentUri(context, uri); 
         } catch (Exception e) { 
         } 
        } 
    
        try { 
         if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) 
          try { 
           setMediaPlayerDataSourcePreHoneyComb(context, mp, fileInfo); 
          } catch (Exception e) { 
           setMediaPlayerDataSourcePostHoneyComb(context, mp, fileInfo); 
          } 
         else 
          setMediaPlayerDataSourcePostHoneyComb(context, mp, fileInfo); 
    
        } catch (Exception e) { 
         try { 
          setMediaPlayerDataSourceUsingFileDescriptor(context, mp, 
            fileInfo); 
         } catch (Exception ee) { 
          String uri = getRingtoneUriFromPath(context, fileInfo); 
          mp.reset(); 
          mp.setDataSource(uri); 
         } 
        } 
    } 
    
    private static void setMediaPlayerDataSourcePreHoneyComb(Context context, 
         MediaPlayer mp, String fileInfo) throws Exception { 
        mp.reset(); 
        mp.setDataSource(fileInfo); 
    } 
    
    private static void setMediaPlayerDataSourcePostHoneyComb(Context context, 
         MediaPlayer mp, String fileInfo) throws Exception { 
        mp.reset(); 
        mp.setDataSource(context, Uri.parse(Uri.encode(fileInfo))); 
    } 
    
    private static void setMediaPlayerDataSourceUsingFileDescriptor(
         Context context, MediaPlayer mp, String fileInfo) throws Exception { 
        File file = new File(fileInfo); 
        FileInputStream inputStream = new FileInputStream(file); 
        mp.reset(); 
        mp.setDataSource(inputStream.getFD()); 
        inputStream.close(); 
    } 
    
    private static String getRingtoneUriFromPath(Context context, String path) { 
        Uri ringtonesUri = MediaStore.Audio.Media.getContentUriForPath(path); 
        Cursor ringtoneCursor = context.getContentResolver().query(
          ringtonesUri, null, 
          MediaStore.Audio.Media.DATA + "='" + path + "'", null, null); 
        ringtoneCursor.moveToFirst(); 
    
        long id = ringtoneCursor.getLong(ringtoneCursor 
          .getColumnIndex(MediaStore.Audio.Media._ID)); 
        ringtoneCursor.close(); 
    
        if (!ringtonesUri.toString().endsWith(String.valueOf(id))) { 
         return ringtonesUri + "/" + id; 
        } 
        return ringtonesUri.toString(); 
    } 
    
    public static String getRingtonePathFromContentUri(Context context, 
         Uri contentUri) { 
        String[] proj = { MediaStore.Audio.Media.DATA }; 
        Cursor ringtoneCursor = context.getContentResolver().query(contentUri, 
          proj, null, null, null); 
        ringtoneCursor.moveToFirst(); 
    
        String path = ringtoneCursor.getString(ringtoneCursor 
          .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); 
    
        ringtoneCursor.close(); 
        return path; 
    } 
    
    +0

    私はこの問題をほぼ1か月間解決しようとしました。私たちのアプリは**アラームアプリ**です。これは音楽や着メロを完全に午前中に再生するはずですが、今まで音楽を再生するときに非常に多くのクラッシュがあります。 –

    +1

    私はこの問題のためにイライラされていて、私の**月**を救った! –

    +0

    /storage/emulated/0/IDM/Music/xxx.mp3のようにパスを使って作業するには?これでもこれは失敗しています。 – jeevs

    4

    Android 4.1.1のバグ修正により、setDataSource(String path)の動作に変更がありました。 4.1.1以降では、ローカルパス(プロトコルなし)を使用する必要があります。ただし、4.0.4以前では、URI(例:file://プロトコル)を使用する必要がありました。ここで

    は、回避策を説明しなければならない、不完全なコードスニペットです:

    // as of 4.1.1 (JELLY_BEAN) we need to use a local path (without protocol) 
    // on 4.0.4 and earlier we needed a URI (with file:// protocol) 
    final String cachedFile = android.os.Build.VERSION.SDK_INT >= 16 // android.os.Build.VERSION_CODES.JELLY_BEAN 
             ? getCacheFilePath(file) 
             : getCacheFileUri(file); 
    
    
    // for the purpose of this example 
    // assume cacheFolder is a String and getCacheFile returns a String 
    
    public String getCacheFilePath(String file) { 
        return cacheFolder + getCacheFile(file); 
    } 
    
    public String getCacheFileUri(String file) { 
        return "file://" + cacheFolder + getCacheFile(file); 
    } 
    
    0

    私は.wavファイルを再生しようとしていたとき、私は、同じエラーが発生しました。例を挙げてみましょう:ステータス= 0x80000000エラーもあります。例を挙げましょう:

    private void start_player(){ 
    // create raw folder inside the res folder if not present 
    MediaPlayer mPlayer = MediaPlayer.create(activity, R.raw.your_wave_audio_file); 
         mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
         mPlayer.setOnCompletionListener(new OnCompletionListener() { 
    
          @Override 
          public void onCompletion(MediaPlayer mp) { 
           mp.release(); 
           // Your Stuff 
          } 
         }); 
         mPlayer.start(); 
        } 
        } 
    

    私の場合、解決策は、オーディオファイル(例えば.wavファイル用の16-BIT PCM)を再エンコードすることで、すべてが期待通りに機能しました。

    0

    準備が作成関数で呼び出されたため、できません。そのあとで、オーディオストリームタイプを変更することはできません。コードの下

    は私のためにうまく働いている。この問題に対処するとき、以下のローンによって

    sMediaPlayer = new MediaPlayer(); 
    sMediaPlayer.setAudioStreamType(AudioManager.STREAM_RING); 
    AssetFileDescriptor assetFileDescriptor = context.getResources(). 
         openRawResourceFd(R.raw.cool_song); 
    
    if(assetFileDescriptor == null) return; 
    
    try { 
        sMediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(), 
               assetFileDescriptor.getStartOffset(), 
               assetFileDescriptor.getLength()); 
        assetFileDescriptor.close(); 
    
        sMediaPlayer.setOnCompletionListener(new OnCompletionListener() {   
         @Override 
         public void onCompletion(MediaPlayer mp) { 
          if(sMediaPlayer != null){ 
           sMediaPlayer.release(); 
           sMediaPlayer = null; 
          } 
         } 
        }); 
    
        sMediaPlayer.setOnPreparedListener(new OnPreparedListener() {    
         @Override 
         public void onPrepared(MediaPlayer mp) { 
          sMediaPlayer.start();     
         } 
        }); 
        sMediaPlayer.prepare(); 
    
    } catch (IllegalArgumentException e) { 
        HelpFunctions.showLog("ERROR = " + e); 
    } catch (IllegalStateException e) { 
        HelpFunctions.showLog("ERROR = " + e); 
    } catch (IOException e) { 
        HelpFunctions.showLog("ERROR = " + e); 
    } 
    
    1

    ファイルの長さ:

    fileinfoは、以下の両方(例)することができます。オーバーロードされたメソッドを使用してください:
    AssetFileDescriptor afd = ctx.getAssets().openFd([your asset name]); mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());

    +0

    ありがとう、これはエラーの原因とは思わなかった!私は上記のオーバーロードされたメソッドを呼び出していましたが、今回は単純なものを考えずに呼び出しました。 – Jenix

    関連する問題