現在、音楽プレーヤーを開発中です。電話機とアクティビティの向きが変更されるたびに、サービスで音楽を再生したいと思っていました。この方法で、ユーザーは音楽を止めることなくアクティビティを離れることができます。 今、私は解決できなかったこの奇妙な問題を...私がアクティビティを作成し、GUIをインフレするたびに、サービスが開始されます。しかし、アクティビティがデータを送信した後に常にサービスが制限されてしまいます...音楽は決して開始しません...データを再送するためにボタンを追加すると、音楽が再生されるため、これが発生します。アクティビティからサービスへの接続に時間がかかりすぎます
public class Player extends Activity{
private Cursor audioCursor;
public static int position=0;
private int count;
private boolean pause = false,
play= false,
stop= false,
next= false,
back= false,
playerActive= true,
dataChanged= false,
finished= false,
playing= true;
private String action;
Messenger mService = null;
boolean mIsBound;
final Messenger mMessenger = new Messenger(new IncomingHandler());
private ServiceConnection mConnection=null;
static final int MSG_SET_BOOLEAN_VALUE = 5;
static final int MSG_SET_STRING_VALUE = 4;
static final int MSG_SET_INT_VALUE = 3;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
Bundle extras = getIntent().getExtras();
action=extras.getString("action");
if(!(Background.isRunning()))
startService(new Intent(Player.this, Background.class));
doBindService();
if(action.equals("play")){
position=extras.getInt("position");
String[] proj = {
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.IS_MUSIC,
MediaStore.Audio.Media.ALBUM_ID};
audioCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, proj,
MediaStore.Audio.Media.IS_MUSIC, null,
MediaStore.Audio.Media.TITLE + " ASC");
startManagingCursor(audioCursor);
count = audioCursor.getCount();
inflatePlayer();
/////////////////////THIS IS THE CODE THAT ACTS BEFORE THE SERVICE CONNECTION
sendBoolToService(playerActive, "playerActive");
sendIntToService(position);
sendStringToService(action);
}
}
//THIS CODE MUST BE FASTER, BUT THE CONNECTION TAKES TOO LONG
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mService = new Messenger(service);
Toast.makeText(getApplicationContext(), "ATTACHED!", Toast.LENGTH_LONG).show();
try {
Message msg = Message.obtain(null, Background.MSG_REGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(msg);
} catch (RemoteException e) {
Toast.makeText(getApplicationContext(), "Connection failed!", Toast.LENGTH_LONG).show();
}
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
Toast.makeText(getApplicationContext(), "UNATTACHED!", Toast.LENGTH_LONG).show();
}
};
private void inflatePlayer(){
//LOTS OF CODE FOR THE GUI, NOTHING TO DO WITH THE SERVICE... SO I OMITTED IT
}
@Override
protected void onStop(){
playerActive=false;
try {
doUnbindService();
} catch (Throwable t) {
}
if(!playing)
stopService(new Intent(Player.this, Background.class));
super.onStop();
}
@Override
protected void onDestroy(){
playerActive=false;
audioCursor.close();
try {
doUnbindService();
} catch (Throwable t) {
}
if(!playing)
stopService(new Intent(Player.this, Background.class));
super.onDestroy();
}
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SET_INT_VALUE:
String str = Integer.toString(msg.getData().getInt("int1"));
Toast.makeText(getApplicationContext(), "Int Message: " + str, Toast.LENGTH_LONG).show();
break;
case MSG_SET_STRING_VALUE:
String str1 = msg.getData().getString("str1");
break;
case MSG_SET_BOOLEAN_VALUE:
dataChanged=msg.getData().getBoolean("dataChanged");
finished=msg.getData().getBoolean("finished");
playing=msg.getData().getBoolean("playing");
if(!playing){
if(finished){
finished=false;
finish();
}
}
default:
super.handleMessage(msg);
}
}
}
private void sendIntToService(int intvaluetosend) {
if (mService != null) {
try {
Bundle b = new Bundle();
b.putInt("int1", intvaluetosend);
Message msg = Message.obtain(null, MSG_SET_INT_VALUE);
msg.setData(b);
mService.send(msg);
} catch (RemoteException e) {
}
}
}
private void sendStringToService(String stringtosend) {
if (mService != null) {
try {
Bundle b = new Bundle();
b.putString("str1", stringtosend);
Message msg = Message.obtain(null, MSG_SET_STRING_VALUE);
msg.setData(b);
mService.send(msg);
} catch (RemoteException e) {
}
}
}
private void sendBoolToService(boolean booltosend, String name) {
if (mService != null) {
try {
Bundle b = new Bundle();
b.putBoolean(name, booltosend);
Message msg = Message.obtain(null, MSG_SET_BOOLEAN_VALUE);
msg.setData(b);
mService.send(msg);
} catch (RemoteException e) {
}
}
}
void doBindService() {
bindService(new Intent(this, Background.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
Toast.makeText(getApplicationContext(), "BOUND!", Toast.LENGTH_LONG).show();
}
void doUnbindService() {
if (mIsBound) {
if (mService != null) {
try {
Message msg = Message.obtain(null, Background.MSG_UNREGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(msg);
} catch (RemoteException e) {
}
}
unbindService(mConnection);
mIsBound = false;
Toast.makeText(getApplicationContext(), "UNBOUND!", Toast.LENGTH_LONG).show();
}
}
}
サービス:活動のため
public class Background extends Service {
private NotificationManager nm;
private Cursor audioCursor;
MediaPlayer mp = new MediaPlayer();
private int count;
private boolean pause = false,
play= false,
stop= false,
next= false,
back= false,
playerActive= true,
dataChanged= false,
finished= false,
playing= false;
private int position;
private String action;
ArrayList<Messenger> mClients = new ArrayList<Messenger>();
static final int MSG_REGISTER_CLIENT = 1;
static final int MSG_UNREGISTER_CLIENT = 2;
static final int MSG_SET_INT_VALUE = 3;
static final int MSG_SET_STRING_VALUE = 4;
static final int MSG_SET_BOOLEAN_VALUE = 5;
final Messenger mMessenger = new Messenger(new IncomingHandler());
private static boolean isRunning = false;
private static final String TAG = "Background";
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
break;
case MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
break;
case MSG_SET_INT_VALUE:
position=msg.getData().getInt("int1");
break;
case MSG_SET_STRING_VALUE:
action=msg.getData().getString("str1");
if(action.equals("play")){
String[] proj = { MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.IS_MUSIC,
MediaStore.Audio.Media.TITLE};
audioCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, proj,
MediaStore.Audio.Media.IS_MUSIC, null,
MediaStore.Audio.Media.TITLE + " ASC");
count = audioCursor.getCount();
audioCursor.moveToPosition(position);
int column_index = audioCursor.getColumnIndex(MediaStore.Audio.Media.DATA);
String path = audioCursor.getString(column_index);
startAudioPlayer(path);
playing=true;
if(playerActive)
sendBool(playing, "playing");
}else{
startAudioPlayer(action);
playing=true;
if(playerActive)
sendBool(playing, "playing");
}
action=null;
break;
case MSG_SET_BOOLEAN_VALUE:
pause=msg.getData().getBoolean("pause");
play=msg.getData().getBoolean("play");
stop=msg.getData().getBoolean("stop");
next=msg.getData().getBoolean("next");
back=msg.getData().getBoolean("back");
playerActive=msg.getData().getBoolean("playerActive");
if(pause){
mp.pause();
play=false;
playing=false;
sendBool(playing, "playing");
pause=false;
}
if(play){
pause=false;
mp.start();
playing=true;
sendBool(playing, "playing");
play=false;
}
default:
super.handleMessage(msg);
}
}
}
private void sendInt(int intvaluetosend) {
for (int i=mClients.size()-1; i>=0; i--) {
try {
Bundle b = new Bundle();
b.putInt("int1", intvaluetosend);
Message msg = Message.obtain(null, MSG_SET_INT_VALUE);
msg.setData(b);
mClients.get(i).send(msg);
} catch (RemoteException e) {
mClients.remove(i);
Log.d(TAG, "Int not send..."+e.getMessage());
}
}
}
private void sendString(String stringtosend) {
for (int i=mClients.size()-1; i>=0; i--) {
try {
Bundle b = new Bundle();
b.putString("str1", stringtosend);
Message msg = Message.obtain(null, MSG_SET_STRING_VALUE);
msg.setData(b);
mClients.get(i).send(msg);
} catch (RemoteException e) {
mClients.remove(i);
Log.d(TAG, "String not send..." +e.getMessage());
}
}
}
private void sendBool(boolean booltosend, String name) {
for (int i=mClients.size()-1; i>=0; i--) {
try {
Bundle b = new Bundle();
b.putBoolean(name, booltosend);
Message msg = Message.obtain(null, MSG_SET_BOOLEAN_VALUE);
msg.setData(b);
mClients.get(i).send(msg);
} catch (RemoteException e) {
mClients.remove(i);
Log.d(TAG, "Bool not send..." +e.getMessage());
}
}
}
@Override
public void onCreate() {
super.onCreate();
showNotification();
isRunning=true;
}
private void showNotification() {
nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
CharSequence text = getText(R.string.maintit);
Notification notification = new Notification(R.drawable.icon, text, System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Player.class), 0);
notification.setLatestEventInfo(this, getText(R.string.app_name), text, contentIntent);
nm.notify(R.string.app_name, notification);
}
@Override
public void onDestroy() {
//REMEMBER TO SAVE DATA!
if(mp.isPlaying())
mp.stop();
mp.release();
isRunning=false;
audioCursor.close();
nm.cancel(R.string.app_name);
super.onDestroy();
}
public static boolean isRunning()
{
return isRunning;
}
public void startAudioPlayer(String path){
try {
if(mp.isPlaying())
mp.reset();
mp.setDataSource(path);
} catch (IllegalArgumentException e) {
e.printStackTrace();
Log.d(TAG,e.getMessage());
} catch (IllegalStateException e) {
e.printStackTrace();
Log.d(TAG,e.getMessage());
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,e.getMessage());
}
try {
mp.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
Log.d(TAG,e.getMessage());
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,e.getMessage());
}
mp.start();
}
}
私は誰かがこれで非常にイライラなって、イムを助けることを願って!また、私はかなりメディアプレーヤーに問題はないと確信して、私はサービスなしで前にそれをテストした...カーソルも正常に動作します...何か...私は必ずGUIからサービスを呼び出す必要がありますか音楽を再生するには?私は間違って何をしていますか?
EDIT:ウェブサイト文句を言わないので、私はここで解決策を投稿し、私は自分の質問に答えることができ:
[OK]を、最終的に解決策を見つけました! 私は...のonCreateメソッドが終了した後のサービスとの相互作用のみが利用可能であることを読んだから、私はタイマーを追加し、私は実行するために必要な方法でそれを満たし:
new Timer().schedule(new TimerTask(){
public void run(){
sendBoolToService(playerActive, "playerActive");
sendIntToService(position);
sendStringToService(action);
}
}, 1000);
出来上がりを!できます! :D誰かに役立つことを願っています!あなたがする必要がどのような
あなたのソリューションが実際に原因を修正しているとは思わない。それはちょうどうまく動作するハックです。サービスライフサイクルの正しい時点でコードを呼び出すことで、これを適切に機能させる方法については、私の答えをご覧ください。 –