2012-09-24 18 views
7

Khi gửi sendOrderedBroadcast với mục đích ACTION_MEDIA_BUTTON (Tôi bắt chước người dùng đang nhấp vào nút phát trên tai nghe bluetooth), Google Play Âm nhạc sẽ mở và phát album cuối cùng thay vì ứng dụng phát nhạc nền trước.Google Play Âm nhạc có đang lưu trữ tất cả ý định ACTION_MEDIA_BUTTON không?

Nếu tôi thay đổi nó để gửiBroadcast, cả Google Play Âm nhạc VÀ ứng dụng chơi nhạc hiện tại (Pandora trong trường hợp của tôi), sẽ ban hành nút phát.

Điều này chỉ xảy ra trong Android 4.0 trở lên. Play Âm nhạc có hogging mục đích này không (một lỗi)? Bạn có nghi ngờ rằng Pandora không tự đăng ký là trình xử lý nút phương tiện hiện tại theo lời khuyên này: http://android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html

Có cách nào tôi có thể hướng mục đích này đến ứng dụng chơi nhạc hiện tại không?

Đây là mã của tôi:

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

Trả lời

2

Có một API mà bạn phải sử dụng để được nhận ưu tiên của những ý đồ, nhưng điều đó tất nhiên có thể được xử lý bởi người gửi trong những chìa khóa hệ thống. Hãy xem this postthe docs. Nhưng đó là lên đến pandora và google âm nhạc trong trường hợp này để có lẽ là không tùy thuộc vào bạn. Bạn cũng có thể gửi các chương trình phát sóng của bạn đến một gói cụ thể (bằng cách chỉ định tên thành phần trong mục đích), nhưng sau đó bạn quyết định ứng dụng nào nhận được nó. Tôi đã thực hiện tìm kiếm nhanh một API ẩn trong AudioManager nhưng không có vẻ hứa hẹn.

Bạn đã thử với phụ kiện chưa? Nếu điều đó làm việc thì tôi sẽ xem xét mục đích đó được gửi đi như thế nào. Nếu không, tôi sẽ xem xét các ứng dụng nào được cài đặt và đưa ra dự đoán "thông minh" hoặc yêu cầu người dùng cho ứng dụng gửi ý định. Có lẽ người cuối cùng là cách tốt nhất để đi trong cả hai trường hợp kể từ khi nó sử dụng các API công cộng và sẽ không làm phiền người dùng bằng cách đoán sai :)

Edit: Điều này có thể làm việc, nhưng nó cũng có thể được bảo vệ bởi quyền và chứng chỉ. Trong lockscreen đây là cách các phím truyền thông được xử lý:

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

Tuy nhiên, các API được ẩn, do đó bạn sẽ phải làm việc xung quanh đó. Đó có lẽ là điều tốt nhất tôi có thể giúp bạn. Cách khác là tiêm các sự kiện. Một cách để làm điều đó là trở thành phương thức nhập liệu, nhưng đó không phải là cách để tiến lên. Có một số cách để chèn các sự kiện vào hoạt động của riêng bạn, nhưng tôi không biết có bất kỳ cách nào để tiêm vào hệ thống. Có lẽ bạn có thể xem xét cách thử nghiệm thiết bị đo đạc đang thực hiện nó.

+0

Tôi chưa thử với phụ kiện vì tôi không có. Ước gì tôi đã làm. Có cách nào tôi có thể tìm ra tên thành phần của ứng dụng chơi nhạc hiện tại không? Tôi không biết liệu có thể đoán được thông minh vì việc gửi chương trình phát sóng theo thứ tự tùy thuộc vào mức ưu tiên của ứng dụng hay không. Tôi cho rằng cuối cùng các ứng dụng khác như Pandora sẽ cập nhật lên API mới ... – joepetrakovich

+0

Bạn luôn có thể xem ứng dụng nào đang chạy bằng cách sử dụng [ActivityManager.getRunningTasks (int)] (http://developer.android.com/reference/android/ app/ActivityManager.html # getRunningTasks (int)) nhưng với tư cách là người dùng, tôi thích cài đặt (có thể sao lưu với một số "AI" để cung cấp các đề xuất và/hoặc mặc định. Ngoài ra còn có cách thay thế để tìm trong nhật ký, nhưng tôi sẽ không đề xuất rằng vì nó rất không đáng tin cậy. Để thử nghiệm mà không cần phụ kiện, bạn có thể xem [ở đây] (http://code.google.com/p/media-button-router/wiki/TestingWithoutBluetooth) Tôi chưa thử nghiệm bản thân mình. –

+0

Vì vậy, tôi đã có thể thử với một phụ kiện thực sự. Nó hoạt động đúng cách sử dụng tai nghe bluetooth samsung. Ứng dụng tiền cảnh hiện tại, Pandora, trả lời tạm dừng phát và các nút tiếp theo trên tai nghe. Tai nghe có một số loại quyền truy cập đặc biệt không? Làm thế nào tôi có thể xây dựng ý định của tôi để hành động như thể nó đến từ một tai nghe? – joepetrakovich

5

Sau đây nên thực hiện thủ thuật. BTW, bạn đã tìm thấy mã nguồn cho màn hình khóa ở đâu?

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

Có một câu trả lời liên quan đến câu trả lời này không phản ánh. nó chỉ đơn giản là sử dụng AudioManager. http://stackoverflow.com/a/40493319/1713704 – MojAmiri

Các vấn đề liên quan