2011-06-07 12 views
0

現在、音楽プレーヤーを開発中です。電話機とアクティビティの向きが変更されるたびに、サービスで音楽を再生したいと思っていました。この方法で、ユーザーは音楽を止めることなくアクティビティを離れることができます。 今、私は解決できなかったこの奇妙な問題を...私がアクティビティを作成し、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誰かに役立つことを願っています!あなたがする必要がどのような

+0

あなたのソリューションが実際に原因を修正しているとは思わない。それはちょうどうまく動作するハックです。サービスライフサイクルの正しい時点でコードを呼び出すことで、これを適切に機能させる方法については、私の答えをご覧ください。 –

答えて

0

は、あなたのServiceConnectionの実装で、あなたのonServiceConnected()メソッドを利用可能サービスに依存しているのonCreate()内のコードを移動することです:私も見てます

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); 
      sendBoolToService(playerActive, "playerActive"); 
      sendIntToService(position); 
      sendStringToService(action);  
     } 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(); 
    } 
}; 

あなたなぜあなたはmService = new Messenger(サービス)を呼び出しているのか理解できません。 IBinderインスタンスは、サービスインスタンスへの参照を取得するためのメカニズムを提供する必要があります。

+0

しかし、私は再生する音楽に応じてさまざまな種類のデータを送信する必要があります。データを一度だけ送信すれば完璧です...また、画面の向きが変わった場合は、接続が再作成されます..サービスが再びデータを受け取ることを意味します... – CodeKrieger

+0

私の実装について、真実は...私はそれらに関する多くの経験がなく、私は多くの人から自分のコードを作成しました。効率的ですか? – CodeKrieger

+0

あなたの活動よりも長生きするサービスを持つことを検討する必要があるかもしれません。サービスからアンバインドしても、必ずしもサービスが停止するとは限りません。アプリをどのような機能が果たそうとしているのか分からないときは、より正確にすることや、最適化する方法を考えるのが難しいです。しかし、あなたの「解決策」は時折クラッシュし、追跡が難しい場合があります。サービスを効率的に使用する方法をよりよく理解するために、サービスのライフサイクルに精通していることを強くお勧めします。 –

関連する問題