2011-10-12 102 views
2

我想要在Android 2.0+中使用BluetoothHeadset類的方法。這裏是我的代碼:如何通過反射使用BluetoothHeadset類

Class bluetoothHeadsetClass = Class.forName("android.bluetooth.BluetoothHeadset"); 
    Constructor constructor = bluetoothHeadsetClass.getConstructors()[0]; 
    Object bluetoothHeadset = constructor.newInstance(this, null); 
    Method getState = bluetoothHeadsetClass.getMethod("getState", null); 
    Object retVal = getState.invoke(bluetoothHeadset, null); 

執行此代碼時我一直都想與日誌消息:

10-12 13:29:48.360:WARN/BluetoothHeadset(3379):代理不附到 服務

我也試圖等待幾秒鐘,然後調用我的方法,但它仍然是相同的。 感謝您的幫助!

回答

4

這是我如何使用反射做到的。我沒有檢查過這段代碼現在是否工作了一段時間,所以它可能不是:

class BluetoothHeadset      
{ 
    private static final String TAG = Tags.getTag(BluetoothHeadset.class); 
    private static final String BLUETOOTH_HEADSET_CLASS_NAME = "android.bluetooth.IBluetoothHeadset"; 
    private static final String BLUETOOTH_HEADSET_STUB_CLASS_NAME = BLUETOOTH_HEADSET_CLASS_NAME+"$Stub"; 

    public static final String ACTION_BLUETOOTH_HEADSET_SERVICE = BLUETOOTH_HEADSET_CLASS_NAME; 
    public static final String ACTION_STATE_CHANGED = "android.bluetooth.headset.action.STATE_CHANGED"; 
    public static final String ACTION_AUDIO_STATE_CHANGED = "android.bluetooth.headset.action.AUDIO_STATE_CHANGED"; 
    public static final String EXTRA_AUDIO_STATE = "android.bluetooth.headset.extra.AUDIO_STATE"; 

    /** A SCO audio channel is not established */ 
    public static final int AUDIO_STATE_DISCONNECTED = 0; 
    /** A SCO audio channel is established */ 
    public static final int AUDIO_STATE_CONNECTED = 1; 

    private static final String AS_INTERFACE_METHOD_NAME = "asInterface"; 
    private static final String IS_CONNECTED_METHOD_NAME = "isConnected"; 

    final Object m_service; 
    private BluetoothHeadset(Object service) 
    { 
     m_service = service; 
    } 

    static public BluetoothHeadset getBluetoothHeadset(IBinder service) 
    { 
     if (service == null) 
     { 
      return null; 
     } 

     Object proxy = null; 
     try 
     { 
      Class<?> clazz = Class.forName(BLUETOOTH_HEADSET_STUB_CLASS_NAME); 
      Method asInterfaceMethod = clazz.getMethod(AS_INTERFACE_METHOD_NAME, IBinder.class); 
      proxy = asInterfaceMethod.invoke(null, service);    
     } 
     catch(ClassNotFoundException ex) 
     { 
      String msg = String.format("Was not able to find %s class.", 
             BLUETOOTH_HEADSET_STUB_CLASS_NAME); 
      Log.e(TAG, msg, ex); 
     } 
     catch(NoSuchMethodException ex) 
     { 
      String msg = String.format("Was not able to find %s method in %s class.", 
             AS_INTERFACE_METHOD_NAME, 
             BLUETOOTH_HEADSET_STUB_CLASS_NAME); 
      Log.e(TAG, msg, ex); 
     }  
     catch(InvocationTargetException ex) 
     { 
      String msg = String.format("Was not able to invoke %s method in %s class.", 
             AS_INTERFACE_METHOD_NAME, 
             BLUETOOTH_HEADSET_STUB_CLASS_NAME); 
      Log.e(TAG, msg, ex); 
     } 
     catch(IllegalAccessException ex) 
     { 
      String msg = String.format("Illegal access while invoking %s method in %s class.", 
             AS_INTERFACE_METHOD_NAME, 
             BLUETOOTH_HEADSET_STUB_CLASS_NAME); 
      Log.e(TAG, msg, ex); 
     } 

     if(proxy == null) return null;  
     return new BluetoothHeadset(proxy); 
    } 

    public Boolean isDeviceConnected(BluetoothDevice device) 
    { 
     //invoke: boolean isConnected(BluetoothDevice device); 
     try 
     { 
      Class<?> clazz = m_service.getClass(); 
      Method isConnectedMethod = clazz.getMethod(IS_CONNECTED_METHOD_NAME, BluetoothDevice.class); 
      Object result = isConnectedMethod.invoke(m_service, device); 

      return (Boolean)result; 
     } 
     catch(NoSuchMethodException ex) 
     { 
      String msg = String.format("Failed to find %s method in class %s.", 
             IS_CONNECTED_METHOD_NAME, m_service.getClass().getName()); 
      Log.e(TAG, msg, ex); 
     } 
     catch(InvocationTargetException ex) 
     { 
      String msg = String.format("Failed to invoke %s method in class %s.", 
             IS_CONNECTED_METHOD_NAME, m_service.getClass().getName()); 
      Log.e(TAG, msg, ex); 
     } 
     catch(IllegalAccessException ex) 
     { 
      String msg = String.format("Illegal access when invoking %s method in class %s.", 
             IS_CONNECTED_METHOD_NAME, m_service.getClass().getName());   
      Log.e(TAG, msg, ex); 
     } 
     catch(Exception ex) 
     { 
      Log.e(TAG, "Unknown exception was thrown.", ex); 
     } 

     return null; 
    } 
} 
0

也嘗試通過反射來調用它。 最終放棄並使用了broadcastReceiver。

聲明如下意圖過濾

 <intent-filter > 
      <action android:name="android.bluetooth.headset.action.AUDIO_STATE_CHANGED" /> 
     </intent-filter> 

和接收機中的onReceive檢查:

if ("android.bluetooth.headset.action.AUDIO_STATE_CHANGED".equals(intent.getAction())) { 
    headsetAudioState = intent.getIntExtra("android.bluetooth.headset.extra.AUDIO_STATE", -2); 
} 

和INT保存爲靜態變量。只要您想知道BT音頻是否連接(1)/斷開連接(0),就可以隨時訪問它。不漂亮,但完成工作。

也可參閱: https://github.com/android/platform_frameworks_base/blob/gingerbread/core/java/android/bluetooth/BluetoothHeadset.java