2012-09-24 19 views
7

bir ACTION_MEDIA_BUTTON niyet (I kullanıcı bluetooth kulaklık oynat düğmesini tıklayarak olduğunu taklit ediyorum), Google Müzik açılır ve yerine ön plan müziği çalmaya uygulamanın oynanan son albümü oynar Play'den bir sendOrderedBroadcast gönderme. Ben sendBroadcast olarak değiştirin, hem Google Müzik VE akım müzik çalmaya uygulaması (benim durumumda Pandora) Play EğerGoogle Play Müzik tüm ACTION_MEDIA_BUTTON amaçlarını mı işaret ediyor?

, oynat düğmesini yürürlüğe olacaktır.

Bu yalnızca Android 4.0 ve yukarıda oluşur. Play Müzik, bu amacı (bir hata) hogging mi? Bu tavsiyeden sonra Pandora'nın kendisini güncel medya düğmesi işleyicisi olarak kaydetmediğinden şüpheleniyor musunuz: http://android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html

Bu amacı yalnızca geçerli müzik çalma uygulamasına yönlendirmenin bir yolu var mı?

public void broadcastMediaIntent(MediaIntent intentType){ 

     long eventtime = SystemClock.uptimeMillis(); 

     Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); 
     Intent upIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); 

     KeyEvent downEvent = null; 
     KeyEvent upEvent = null; 

    switch(intentType){ 
    case NEXT: 

      downEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT, 0); 

      upEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT, 0); 

     break; 
    case PLAY_PAUSE: 

      downEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0); 

      upEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0); 

     break; 
    case PREVIOUS: 

      downEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS, 0); 

      upEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PREVIOUS, 0); 
     break; 
    case FAST_FORWARD: 

      downEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, 0); 

      upEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, 0); 
     break; 
    case REWIND: 

      downEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_REWIND, 0); 

      upEvent = new KeyEvent(eventtime, eventtime, 
      KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_REWIND, 0); 
     break; 

    default: 
     break; 
    } 

     downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent); 
     sendOrderedBroadcast(downIntent, null); 

     upIntent.putExtra(Intent.EXTRA_KEY_EVENT, upEvent); 
     sendOrderedBroadcast(upIntent, null); 

} 
+0

http://code.google.com/p/android/issues/detail?id=23272 – joepetrakovich

cevap

2

Orada o niyet tercih alıcısı olmak kullanmak zorunda bir API olduğunu, ama tabii ki o kutunun sistemi tuşlarının gönderici tarafından ele alınması:

İşte benim kodudur. this post ve the docs'a bakın. Ancak bu, pandora ve google müzik için geçerli, bu yüzden muhtemelen size bağlı değil. Tabii ki yayınlarınızı belirli bir pakete de gönderebilirsiniz (amaçtaki bileşen ismini belirterek), ancak hangi uygulamanın alınacağına siz karar verirsiniz. AudioManager'da gizli bir API için hızlı bir arama yaptım, ancak bu umut verici görünmüyor.

Eğer bir aksesuar ile denediniz mi? Eğer çalışırsa, o niyetin nasıl gönderileceğine bakarım. Eğer yapmazsam hangi uygulamaların kurulduğuna bakıp "akıllı" bir tahminde bulunacağım ya da hangi uygulamanın niyetini göndermesi gerektiğini soruyorum. Bu işe yarayabilir , ama aynı zamanda izinler tarafından korunan edilebilir: Belki sonuncusu kamu API'leri kullanır ve yanlış tahmin :)

Düzenleme kullanıcıyı rahatsız etmemesi nedeniyle her iki durumda da gitmek için en iyi yoldur ve sertifikalar. lockscreen bu medya tuşları nasıl işlendiğini şudur: O geçici bir çözüm olurdu böylece

void handleMediaKeyEvent(KeyEvent keyEvent) { 
    IAudioService audioService = IAudioService.Stub.asInterface(
      ServiceManager.checkService(Context.AUDIO_SERVICE)); 
    if (audioService != null) { 
     try { 
      audioService.dispatchMediaKeyEvent(keyEvent); 
     } catch (RemoteException e) { 
      Log.e("KeyguardViewBase", "dispatchMediaKeyEvent threw exception " + e); 
     } 
    } else { 
     Slog.w("KeyguardViewBase", "Unable to find IAudioService for media key event"); 
    } 
} 

Ancak API gizlenir. Muhtemelen size yardımcı olabileceğim en iyisi budur. Alternatif olayları enjekte etmektir. Bunu yapmanın bir yolu, bir giriş yöntemi olmaktır, ancak bu ileriye doğru bir yol değildir. Etkinliklerinizi kendi aktivitelerinize eklemenin çeşitli yolları vardır, ancak sisteme enjekte eden herhangi bir şey bilmiyorum. Belki de enstrümantasyon testlerinin nasıl yürüdüğünü öğrenebilirsiniz.

+0

Ben bir aksesuar ile denemedim. Keşke yapsaydım. Mevcut müzik çalma uygulamasının bileşen adını öğrenebilmemin bir yolu var mı? Sıralı bir yayın göndermenin, uygulamanın önceliğine bağlı olduğundan akıllı bir tahminde bulunmanın mümkün olup olmadığını bilmiyorum. Sonunda Pandora gibi diğer uygulamaların yeni API'ye güncelleyeceğini tahmin ediyorum ... – joepetrakovich

+0

[ActivityManager.getRunningTasks (int)] (http://developer.android.com/reference/android/) kullanarak hangi uygulamaların çalıştığını her zaman görebilirsiniz. app/ActivityManager.html # getRunningTasks (int)) ama bir kullanıcı olarak ayarları tercih ediyorum (belki önerileri ve/veya varsayılanları sağlamak için bazı "AI" ile yedeklenmiş. Aynı zamanda kütüklere bakmanın alternatifi de var, ama çok güvenilmez olduğu için önermem. Bir aksesuar olmadan test etmek için [buraya] bakabilirsiniz (http://code.google.com/p/media-button-router/wiki/TestingWithoutBluetooth) Bunları kendi kendime test etmedim. –

+0

Bu yüzden gerçek bir aksesuarla deneyebiliyordum. Bir samsung bluetooth kulaklık kullanarak düzgün çalışıyor. Mevcut ön plan uygulaması Pandora, oynatma duraklatmasına ve kulaklıktaki sonraki düğmelere yanıt verir. Kulaklıkların bir çeşit özel erişimi var mı? Bir kulaklıktan geldiği gibi davranma niyetimi nasıl kurabilirim? – joepetrakovich

5

Aşağıdakiler hile yapmalıdır. BTW, kilit ekranının kaynak kodunu nereden buldunuz? Ben bir tane yok çünkü

public void handleMediaKeyEvent(KeyEvent keyEvent) { 

    /* 
    * Attempt to execute the following with reflection. 
    * 
    * [Code] 
    * IAudioService audioService = IAudioService.Stub.asInterface(b); 
    * audioService.dispatchMediaKeyEvent(keyEvent); 
    */ 
    try { 

     // Get binder from ServiceManager.checkService(String) 
     IBinder iBinder = (IBinder) Class.forName("android.os.ServiceManager") 
     .getDeclaredMethod("checkService",String.class) 
     .invoke(null, Context.AUDIO_SERVICE); 

     // get audioService from IAudioService.Stub.asInterface(IBinder) 
     Object audioService = Class.forName("android.media.IAudioService$Stub") 
       .getDeclaredMethod("asInterface",IBinder.class) 
       .invoke(null,iBinder); 

     // Dispatch keyEvent using IAudioService.dispatchMediaKeyEvent(KeyEvent) 
     Class.forName("android.media.IAudioService") 
     .getDeclaredMethod("dispatchMediaKeyEvent",KeyEvent.class) 
     .invoke(audioService, keyEvent);    

    } catch (Exception e1) { 
     e1.printStackTrace(); 
    } 
} 
+0

Bunun yansıması olmayan bir cevap var. sadece AudioManager kullanır. http://stackoverflow.com/a/40493319/1713704 – MojAmiri

İlgili konular