2012-09-24 18 views
7

एक ACTION_MEDIA_BUTTON इरादे के साथ एक SendOrderedBroadcast भेजते समय (मैं अनुकरण कर रहा हूं कि उपयोगकर्ता ब्लूटूथ हेडसेट पर प्ले बटन पर क्लिक कर रहा है), Google Play Music अग्रभूमि संगीत बजाने वाले ऐप के बजाय खेला गया अंतिम एल्बम खुलता है और बजाता है।क्या Google Play Music सभी ACTION_MEDIA_BUTTON इरादों को हॉगिंग कर रहा है?

यदि मैं इसे Google Play Music और वर्तमान संगीत बजाने वाला ऐप (मेरे मामले में पेंडोरा) दोनों को भेजने के लिए बदलता हूं, तो प्ले बटन को लागू करेगा।

यह केवल एंड्रॉइड 4.0 और से अधिक होता है। क्या इस मकसद को एक मज़ेदार संगीत (एक बग) है? क्या आपको संदेह है कि इस सलाह के बाद पेंडोरा खुद को मौजूदा मीडिया बटन हैंडलर के रूप में पंजीकृत नहीं कर रहा है: http://android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html

क्या कोई तरीका है कि मैं इस उद्देश्य को वर्तमान संगीत बजाने वाले ऐप पर ही निर्देशित कर सकता हूं?

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

उत्तर

2

एक API आप उन उद्देश्यों के पसंदीदा रिसीवर होने के लिए उपयोग करने के लिए है कि नहीं है, लेकिन निश्चित रूप से है कि कर सकते हैं प्रणाली चाबियों का इस के द्वारा नियंत्रित किया:

यहाँ मेरी कोड है। this post, और the docs पर देखें। लेकिन यह इस मामले में पैंडोरा और Google संगीत तक है, इसलिए शायद यह आपके ऊपर नहीं है। आप निश्चित रूप से अपने प्रसारण को एक विशेष पैकेज (इरादे में घटक नाम निर्दिष्ट करके) भेज सकते हैं, लेकिन फिर आप तय करते हैं कि कौन सा ऐप प्राप्त करता है। मैंने ऑडियोमैनेजर में एक छिपी हुई एपीआई की त्वरित खोज की लेकिन वह वादा करने की प्रतीत नहीं कर रहा है।

क्या आपने एक्सेसरी के साथ प्रयास किया है? अगर यह काम करता है तो मैं देखता हूं कि यह इरादा कैसे भेजा जाता है। यदि ऐसा नहीं होता है तो मैं देखता हूं कि कौन से एप्लिकेशन इंस्टॉल किए गए हैं और या तो "बुद्धिमान" अनुमान लगाते हैं या उपयोगकर्ता से पूछते हैं कि किस ऐप को इरादा भेजना है। यह काम कर सकता था, लेकिन यह भी अनुमतियों द्वारा सुरक्षित किया जा सकता है: हो सकता है कि पिछले एक के बाद से यह सार्वजनिक API का उपयोग करता है और गलत अनुमान लगा :)

संपादित करें द्वारा उपयोगकर्ता परेशान नहीं करेगा या तो मामले में जाने के लिए सबसे अच्छा तरीका है और प्रमाण पत्र। लॉकस्क्रीन में यह कैसे मीडिया कुंजी नियंत्रित किया जाता है है:

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"); 
    } 
} 

हालांकि, एपीआई ताकि आप उस के आसपास काम करने के लिए होता छिपा हुआ है। शायद यह सबसे अच्छा है कि मैं आपकी मदद कर सकता हूं। विकल्प घटनाओं को इंजेक्ट करना है। ऐसा करने का एक तरीका इनपुट पद्धति बनना है, लेकिन यह आगे बढ़ने की संभावना नहीं है। अपनी गतिविधि में घटनाओं को इंजेक्ट करने के कई तरीके हैं, लेकिन मुझे सिस्टम के इंजेक्ट करने वाले किसी भी व्यक्ति के बारे में पता नहीं है। हो सकता है कि आप यह देख सकें कि उपकरण परीक्षण कैसे कर रहे हैं।

+0

मैं एक सहायक के साथ प्रयास नहीं किया है क्योंकि मैं एक नहीं है। इच्छा है मैंने किया। क्या कोई तरीका है कि मैं वर्तमान संगीत बजाने वाले ऐप का घटक नाम ढूंढ सकता हूं? मुझे नहीं पता कि आदेश दिया गया प्रसारण भेजने के बाद से एक बुद्धिमान अनुमान बनाना संभव है, ऐप की प्राथमिकता पर निर्भर करता है। मुझे लगता है कि अंततः पेंडोरा जैसे अन्य ऐप्स नए एपीआई में अपडेट हो जाएंगे ... – joepetrakovich

+0

आप हमेशा देख सकते हैं कि कौन से अनुप्रयोग चल रहे हैं [ActivityManager.getRunningTasks (int)] (http://developer.android.com/reference/android/ ऐप/ActivityManager.html # getRunningTasks (int)) लेकिन एक उपयोगकर्ता के रूप में मैं सेटिंग्स पसंद करता हूं (शायद सुझावों और/या डिफ़ॉल्ट प्रदान करने के लिए कुछ "एआई" के साथ बैक अप लेता हूं। लॉग में देखने का विकल्प भी है, लेकिन मैं इसका प्रस्ताव नहीं दूंगा क्योंकि यह बहुत अविश्वसनीय है। एक्सेसरी के बिना परीक्षण के लिए आप [यहां] देख सकते हैं (http://code.google.com/p/media-button-router/wiki/TestingWithoutBluetooth) हालांकि मैंने इन स्वयं का परीक्षण नहीं किया है। –

+0

तो मैं एक असली सहायक के साथ प्रयास करने में सक्षम था। यह एक सैमसंग ब्लूटूथ हेडसेट का उपयोग कर ठीक से काम करता है। वर्तमान फोरग्राउंड ऐप, पेंडोरा, प्ले पॉज़ और हेडसेट पर अगले बटन का जवाब देता है। क्या हेडसेट्स में किसी विशेष प्रकार की विशेष पहुंच है? मैं हेडसेट से आया जैसे कार्य करने के लिए अपना इरादा कैसे बना सकता हूं? – joepetrakovich

5

निम्नलिखित चाल चलनी चाहिए। बीटीडब्ल्यू, आपको लॉक स्क्रीन के लिए स्रोत कोड कहां मिला?

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

इस से संबंधित एक उत्तर है जो प्रतिबिंब नहीं करता है। यह बस AudioManager का उपयोग करता है। http://stackoverflow.com/a/40493319/1713704 – MojAmiri