31

境界のあるサービスを理解しようとしています。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: com.example.dd_services_audio_01.MainActivity$1@2afca5d8
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

}

}
4

5 に答える 5

20

ああ、最近の 1 つ

mService.unbindService(mConnection);

unbind を間違ったコンテキストで呼び出すのは明らかにナンセンスです。そのはず

unbindService(mConnection); 

投稿されたコーディングの追加の間違いは、の欠落です

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

    releaseMediaPlayer();

    return false;
}
于 2012-09-05T13:02:35.033 に答える
3

mService が null でないことを確認する必要がある場合があります。次の行で「サービスが登録されていません」というエラーが表示されました。

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

mContext と mServiceConn の両方が null ではないため、これは非常に紛らわしいものでした。

これで修正されました:

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

于 2014-06-30T22:30:08.733 に答える
0

アプリを強制MediaPlayer終了すると停止しますが、5 分以内にレイヤーが自動的に再起動します。

これを修正するには、@dorjeduck の回答に加えて、呼び出すmediaPlayer.stop()前に呼び出す必要がありmediaPlayer.release()ました。

于 2014-11-14T19:02:03.533 に答える