0

我試圖從內部存儲播放音頻文件。 我使用的代碼是..Mediaplayer準備顯示非法狀態異常

package com.abhi.firstapp.firstapp; 
import android.content.Context; 
import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Environment; 
import android.support.design.widget.FloatingActionButton; 
import android.support.design.widget.Snackbar; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 
import android.util.Log; 
import android.view.View; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.widget.Toast; 

import java.io.File; 
import java.io.IOException; 
import java.net.URI; 

public class MainActivity extends AppCompatActivity { 

    MediaPlayer mp; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 



    File f= new File("/sdcard/a.mp3"); 
    if(f.exists()) 
    { 

     Toast toast= Toast.makeText(this, "file exists", Toast.LENGTH_LONG); 
     toast.show(); 
     Log.d("uri","1"); 
     Uri uri= Uri.fromFile(f); 
     Log.d("uri", "2"); 

     mp= new MediaPlayer(); 
     mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     Log.d("uri", "3"); 

     try { 
      mp.setDataSource("/sdcard/a.mp3"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     //mp.setDataSource(getBaseContext(), uri); 
      Log.d("uri", "4"); 


     try { 
      mp.prepare(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      Log.d("uri", "IOException"); 
     } 

     mp.start(); 


    } 
    else { 
     Toast toast1 = Toast.makeText(this, "file does not exist", Toast.LENGTH_LONG); 
     toast1.show(); 
    } 

    //MediaPlayer mp= MediaPlayer.create(getBaseContext(), uri); 
    //mp.start(); 

} 



@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 
} 

通過使用日誌,我可以確定這代碼運行直到mp.prepare(媒體播放器準備)。並在這一步,它給錯誤非法國家例外

Caused by: java.lang.IllegalStateException 
    at android.media.MediaPlayer.prepare(Native Method) 

請幫助!

回答

4

有幾件事情你可能想改變。

第一個:mp.prepare()將阻止您的主線程,這是禁止的,並且會導致Android將關閉您的應用程序的異常。爲了防止這種情況,設計了mp.prepareAsync。改爲使用該方法並實現onPreparedListener和onErrorListener。

第二:在調用prepare()之前,您應該提供一個數據源。

例如,你可以這樣做:

public class MainActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener { 

    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     ... 

     MediaPlayer mp = new MediaPlayer(); 
     mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 

     try { 
      mediaPlayer.setDataSource(streamURL); 
     } catch (IOException e) { 
      // Error, do something 
     } 

     mp.prepareAsync(); 
     ... 
    } 
     @Override 
    public void onPrepared(MediaPlayer player) { 
     mediaPlayer.start(); 
    } 

    ... 

} 
+0

我看到他之前撥打的setDataSource原代碼準備.. 那麼,爲什麼答案接受?非法狀態是由於調用prepare()而不是prepareAsync()?我有一個類似的問題,我仍然在調用prepare(),但是我從後臺線程執行它,所以它應該可以工作,對吧? –