2012-09-05 42 views
23

我想了解有界服务。在我尝试遵循http://developer.android.com/guide/components/bound-services.html的示例程序下方。该服务的功能,只要我可以播放,暂停和停止音频,但当我切换到另一个应用程序,我得到以下服务未注册错误。安卓服务 - 错误:服务未注册

java.lang.RuntimeException: Unable to stop activity {com.example.dd_services_audio_01/com.example.dd_services_audio_01.MainActivity}: java.lang.IllegalArgumentException: Service not registered: [email protected] 
09-05 14:04:32.625: E/AndroidRuntime(5810):  at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:2451) 
09-05 14:04:32.625: E/AndroidRuntime(5810):  at android.app.ActivityThread.handleStopActivity(ActivityThread.java:2496) 

由于编码似乎紧跟在文档示例中,所以我不知道哪里出了问题。我在线路运行此应用minSdk水平8. MainActivity.onStop发生错误

mService.unbindService(mConnection); 

任何建议,以解决这个问题将是巨大的。

感谢

马丁

package com.example.dd_services_audio_01; 

import android.app.Activity; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.Environment; 
import android.os.IBinder; 
import android.util.Log; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

import com.example.dd_services_audio_01.AudioPlayerService.AudioPlayerBinder; 

public class MainActivity extends Activity { 

private final String TAG = "MainActivity"; 

AudioPlayerService mService; 
boolean mBound = false; 

Button mPlay, mPause, mStop; 

String audioFile = Environment.getExternalStorageDirectory() 
     + "/justdzongsar/DJKR_AboutToGetIt.mp3"; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Log.d(TAG,"onCreate"); 
    setContentView(R.layout.activity_main); 

    mPlay = (Button) findViewById(R.id.buttonPlay); 
    mPause = (Button) findViewById(R.id.buttonPause); 
    mStop = (Button) findViewById(R.id.buttonStop); 

    mPlay.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      mService.play(audioFile); 
     } 
    }); 

    mPause.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      mService.pause(); 
     } 
    }); 

    mStop.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      mService.stop(); 
     } 
    }); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

@Override 
protected void onStart() { 
    super.onStart(); 
    // Bind to LocalService 
    Intent intent = new Intent(this, AudioPlayerService.class); 
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 


} 

@Override 
protected void onStop() { 
    super.onStop(); 

    if (mBound) { 
     mService.unbindService(mConnection); 
     mBound=false; 
    } 
} 

/** Defines callbacks for service binding, passed to bindService() */ 
private ServiceConnection mConnection = new ServiceConnection() { 

    @Override 
    public void onServiceConnected(ComponentName className, IBinder service) { 
     // We've bound to LocalService, cast the IBinder and get 
     // LocalService instance 
     AudioPlayerBinder binder = (AudioPlayerBinder) service; 
     mService = binder.getService(); 
     mBound = true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName arg0) { 
     mService = null; 
     mBound = false; 
    } 
}; 

} 

package com.example.dd_services_audio_01; 

import java.io.IOException; 

import android.app.Service; 
import android.content.Intent; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnCompletionListener; 
import android.media.MediaPlayer.OnPreparedListener; 
import android.os.Binder; 
import android.os.IBinder; 
import android.util.Log; 

public class AudioPlayerService extends Service implements OnPreparedListener, 
    OnCompletionListener { 

private final String TAG = "AudioPlayerService"; 

private final IBinder mBinder = new AudioPlayerBinder(); 

private MediaPlayer mMediaPlayer; 

private String currentDataSource; 

public class AudioPlayerBinder extends Binder { 
    public AudioPlayerService getService() { 
     Log.v(TAG, "AudioPlayerBinder: getService() called"); 
     return AudioPlayerService.this; 
    } 
} 

@Override 
public IBinder onBind(Intent intent) { 
    // TODO Auto-generated method stub 
    return mBinder; 
} 

@Override 
public boolean onUnbind(Intent intent) { 
    // All clients have unbound with unbindService() 
    return false; 
} 

@Override 
public void onStart(Intent intent, int startId) { 
    Log.i(TAG, 
      "AudioPlayerService: onStart() called, instance=" 
        + this.hashCode()); 
} 

@Override 
public void onDestroy() { 
    Log.i(TAG, "AudioPlayerService: onDestroy() called"); 
    releaseMediaPlayer(); 
} 

// ----- 

public void play(String audioFile) { 
    Log.d(TAG, "audio play called with file " + audioFile); 
    if (mMediaPlayer != null && audioFile.compareTo(currentDataSource) == 0) { 
     if (mMediaPlayer.isPlaying() == true) { 
      return; 
     } 
     mMediaPlayer.start(); 

     return; 
    } 
    releaseMediaPlayer(); 

    try { 

     mMediaPlayer = new MediaPlayer(); 
     mMediaPlayer.setDataSource(audioFile); 


     mMediaPlayer.setOnPreparedListener(this); 
     mMediaPlayer.setOnCompletionListener(this); 
     currentDataSource = audioFile; 

        mMediaPlayer.prepareAsync(); 


    } catch (IOException ioe) { 
     Log.e(TAG, "error trying to play " + audioFile, ioe); 
    } 

} 

public void pause() { 

    Log.d(TAG, "audio pause"); 
    if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { 
     mMediaPlayer.pause(); 
    } 
} 

public void seek(int timeInMillis) { 
    if (mMediaPlayer != null) { 
     mMediaPlayer.seekTo(timeInMillis); 
    } 
} 

public int elapsed() { 
    if (mMediaPlayer == null) { 
     return 0; 
    } 
    return mMediaPlayer.getCurrentPosition(); 
} 

public void stop() { 
    Log.d(TAG, "audio stop"); 
    releaseMediaPlayer(); 
} 

// -- 

private void releaseMediaPlayer() { 
    if (mMediaPlayer == null) { 
     return; 
    } 

    if (mMediaPlayer.isPlaying()) { 
     mMediaPlayer.stop(); 
    } 
    mMediaPlayer.release(); 
    mMediaPlayer = null; 
} 

@Override 
public void onCompletion(MediaPlayer arg0) { 
    // TODO Auto-generated method stub 
    releaseMediaPlayer(); 
} 

@Override 
public void onPrepared(MediaPlayer mp) { 
    if (mp != null) { 
     mp.start(); 
    } 

    // TODO Auto-generated method stub 

} 

} 
+0

它会在mediaplayer运行时抛出错误,然后您切换主要活动? – waqaslam

+0

在这两种情况下,运行或不运行... – dorjeduck

+0

你可以做一些日志** onServiceDisconnected **,看看它是否意外提出... – waqaslam

回答

47

缺失也有类似的问题,但接受的答案是不适合我的解决方案。幸运的是,意见的人给我的答案:

onServiceDisconnected is not supposed to be raised when you unbind your service, so don't rely on it. It is supposed to inform you in case the connection between your Service and ServiceConnection is dropped.

感谢@Waqas我发现了错误:我更新boolean binded标志只有内部onServiceConnected()onServiceDisconnected()。现在,我每次拨打unbindService()都会添加“绑定= false”,并且问题消失了。就是这样,不要依赖onServiceDisconnected

+3

这是正确的答案! ++++ – ComputerEngineer88

+1

谢谢!我的想法与onServiceDisconnected在unbindService上的调用方式相同。我已将所有服务停止在那里,现在我已将其移至按钮单击事件。 – EvilTak

16

啊,这些天

mService.unbindService(mConnection); 

一个显然是无稽之谈,呼吁取消绑定在错误的上下文。它应该是

unbindService(mConnection); 

在投稿编码附加的错误是

@Override 
public boolean onUnbind(Intent intent) { 
    // All clients have unbound with unbindService() 

    releaseMediaPlayer(); 

    return false; 
} 
+2

帮助了我。我做了同样愚蠢的事情。 –

+0

谢谢,也帮助了我。明显的错误,但不容易调试恕我直言。 –

+1

花了我一下,弄清楚为什么这不起作用。如果'Fragment'中调用了'unbindService','getActivity().'必须在前面,所以它是'getActivity()。unbindService(mConnection)'。 – craned

2

您可能需要确保mService不为空。下面这行给我的“服务未注册”错误:

if (mContext != null) mContext.unbindService(mServiceConn);

这是非常令人困惑,因为mContext和mServiceConn都没有空。

这个固定:

if (mContext != null && mService != null) mContext.unbindService(mServiceConn);

+0

这没有帮助(IabHelper代码) – fillobotto

0

MediaPlayer将停止当我杀了应用程序,但5分钟层以下,将重新启动所有备份自身。

要解决这个问题,除了@ dorjeduck的回答,我还必须在致电mediaPlayer.release()之前致电mediaPlayer.stop()

6

作为旁注,由于没有其他答案有帮助,我发现我的错误是使用不同的Context绑定和解除绑定。我的绑定来自Application上下文,但我的解除绑定来自Activity上下文。

为了解决这个错误,我确保使用bindService()unbindService()的相同上下文。