2016-09-23 6 views
0

オーディオトラックをバックグラウンドで再生しようとしているため、ユーザーがホームボタンを押しても実行を継続します。java.lang.IllegalStateExceptionサービスでバックグラウンドでサウンドを再生しようとしています

私のアプローチは、このような動作を実現する最も最適化された方法であると思われるサービスを使用することです。

私のコードは、活動やサービスのファイルに分割されます。

AudioPlaybackActivity.java

//.... 
Intent serviceIntent; 
@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.audio_playback_activity); 
try 
{ 
    serviceIntent = new Intent(this, AudioPlaybackService.class); 
}catch (Exception e) 
{ 
    e.printStackTrace(); 
} 
} 

    @Override 
    public void onClick (View view) 
    { 
     switch (view.getId()) 
     { 
      // ........ 
      case R.id.play: 
      { 
       try 
       { 
       startService(serviceIntent); // Start the service when click on the play button 
       }catch(Exception e) 
       { 
        e.printStackTrace(); 
       } 
       break; 
      } 
     } 
    } 

AudioPlaybackService.java

public class AudioPlaybackService extends Service implements MediaPlayer.OnCompletionListener, 
     MediaPlayer.OnPreparedListener, 
     MediaPlayer.OnErrorListener 
{ 
    private MediaPlayer mediaPlayer; 

    @Override 
    public void onCreate() 
    { 

     mediaPlayer = new MediaPlayer(); 
     mediaPlayer.setOnPreparedListener(this); 
     mediaPlayer.setOnCompletionListener(this); 
     mediaPlayer.setOnErrorListener(this); 
     mediaPlayer.reset(); 
    } 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     if (!mediaPlayer.isPlaying()) 
     { 
      mediaPlayer.reset(); 
      mediaPlayer = MediaPlayer.create(this.getApplicationContext(), R.raw.poi1); 
      mediaPlayer.prepareAsync(); 
     } 
     return START_STICKY; 
    } 
    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     if (mediaPlayer != null) 
     { 
      if (mediaPlayer.isPlaying()) 
      { 
       mediaPlayer.stop(); 
      } 
      mediaPlayer.release(); 
     } 
    } 
    @Override 
    public void onCompletion(MediaPlayer mp) 
    { 
     stopAudio(); 
     stopSelf(); // Stop the Service itself 
    } 
    @Override 
    public void onPrepared(MediaPlayer arg0) 
    { 
     playAudio(); 
    } 
    @Override 
    public boolean onError(MediaPlayer mp, int what, int extra) 
    { 
     return false; 
    } 

    @Override 
    public IBinder onBind(Intent arg0) 
    { 
     return null; 
    } 


    public void playAudio() 
    { 
     if (!mediaPlayer.isPlaying()) 
     { 
      mediaPlayer.start(); 
     } 
    } 
    public void stopAudio() 
    { 
     if(mediaPlayer.isPlaying()) 
     { 
      mediaPlayer.stop(); 
     } 
    } 

AndroidManifest.xmlをファイル:

//......... 
<service android:name="com.medigarage.audioguide.AudioPlaybackService" 
     android:enabled="true"> 
</service> 

再生ボタンをクリックしてオーディオ再生を開始すると、アプリがクラッシュする。バックトレースは次のとおりです。

09-23 20:41:11.960 32753-32753/com.xxxxx.xxxxx E/AndroidRuntime: FATAL EXCEPTION: main 
Process: com.xxxxx.xxxxxx, PID: 32753 
    java.lang.RuntimeException: Unable to start service [email protected] with Intent { cmp=com.xxxx.xxxxxx/.AudioPlaybackService }: java.lang.IllegalStateException 
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2872) 
    at android.app.ActivityThread.access$2100(ActivityThread.java:155) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1341) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:136) 
    at android.app.ActivityThread.main(ActivityThread.java:5433) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.IllegalStateException 
    at android.media.MediaPlayer.prepareAsync(Native Method) 
    at com.xxxxx.xxxxxx.AudioPlaybackService.onStartCommand(AudioPlaybackService.java:35) 
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2855) 
    at android.app.ActivityThread.access$2100(ActivityThread.java:155)  
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1341)  
    at android.os.Handler.dispatchMessage(Handler.java:102)  
    at android.os.Looper.loop(Looper.java:136)  
    at android.app.ActivityThread.main(ActivityThread.java:5433)  
    at java.lang.reflect.Method.invokeNative(Native Method)  
    at java.lang.reflect.Method.invoke(Method.java:515)  
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)  
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)  
    at dalvik.system.NativeStart.main(Native Method)  

サービスが開始されない理由は何ですか?

あなたの問題は

mediaPlayer = MediaPlayer.create(this.getApplicationContext(), R.raw.poi1); 
mediaPlayer.prepareAsync(); 

Android Docs for MediaPlayer.create()

Convenience method to create a MediaPlayer for a given resource id. On success, prepare() will already have been called and must not be called again.

によると、あなたは非同期MediaPlayerを準備したくない場合がMediaPlayer.create()

を呼び出した後mediaPlayer.prepareAsync()を呼び出すべきではありませんされて

答えて

0

、便利なを使用する代わりに、直接データソースを設定することができますメソッドのように:

mediaPlayer.setDataSource(getResources().openRawResourceFd(R.raw.poi1)); 
+0

Uri UriOfFile = Uri.parse("android.resource://com.my.package/raw/audioFileName"); 

2)そして、このコードは、ファイルを再生するにはコンパイルエラーが発生しました: 'メソッドのsetDataSource(android.content.res.AssetFileDescriptor')を解決できません – Malloc

+0

そのメソッドが[API 24](https://developer.android.com/reference/android/media/MediaPlayer)に追加されたようです。html#setDataSource(android.content.res.AssetFileDescriptor))、代わりにこの 'mediaPlayer.setDataSource(getResources()。openRawResourceFd(R)のように' getFileDescriptor() 'メソッドを使用して' AssetFileDescriptor'を 'FileDescriptor'に変換してください。 raw.poi1).getFileDescriptor()); ' –

0

はい。あなたのサービスは実際に始まっていますが、メディアプレーヤーは準備中にハングアップしています。

ファイルをローカルで再生するときは、mediaPlayer.prepareAsync();を使用しないで、自動的にプレーヤーを準備したようにメディアプレーヤーを作成してください。 mediaPlayer.prepareAsync();行を削除するだけで問題なく動作します。

EDIT:

あなたはそれをやっているようにあなたがそれを行うことができますが、あるいはこのようなprepareAsync()ラインなし:

1)URIにあなたの生のオーディオソースの場所を入れて、そのように:私はFを取得しています今

MediaPlayer mediaPlayer = new MediaPlayer(); 
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
mediaPlayer.setDataSource(getApplicationContext(), UriOfFile); 
mediaPlayer.prepare(); // or prepareAsync() 
mediaPlayer.start(); 
関連する問題