Android 如何通过反射使用蓝牙耳机类

Android 如何通过反射使用蓝牙耳机类,android,reflection,bluetooth,Android,Reflection,Bluetooth,我想在Android 2.0+中使用BluetoothHeadset类的方法。这是我的密码: Class bluetoothHeadsetClass = Class.forName("android.bluetooth.BluetoothHeadset"); Constructor constructor = bluetoothHeadsetClass.getConstructors()[0]; Object bluetoothHeadset = constructor.

我想在Android 2.0+中使用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:警告/蓝牙耳机(3379):代理未连接到 服务

我也尝试过在调用我的方法之前等待几秒钟,但它仍然是一样的。
谢谢你的帮助

下面是我如何使用反射完成的。我已经有一段时间没有检查这段代码是否有效了,所以很可能不是:

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;
    }   
}
class蓝牙耳机
{
私有静态最终字符串TAG=Tags.getTag(BluetoothHeadset.class);
私有静态最终字符串BLUETOOTH\u HEADSET\u CLASS\u NAME=“android.BLUETOOTH.IBluetoothHeadset”;
专用静态最终字符串BLUETOOTH\u HEADSET\u STUB\u CLASS\u NAME=BLUETOOTH\u HEADSET\u CLASS\u NAME+“$STUB”;
公共静态最终字符串操作\蓝牙\耳机\服务=蓝牙\耳机\类别\名称;
公共静态最终字符串ACTION\u STATE\u CHANGED=“android.bluetooth.headset.ACTION.STATE\u CHANGED”;
公共静态最终字符串ACTION\u AUDIO\u STATE\u CHANGED=“android.bluetooth.headset.ACTION.AUDIO\u STATE\u CHANGED”;
公共静态最终字符串EXTRA\u AUDIO\u STATE=“android.bluetooth.headset.EXTRA.AUDIO\u STATE”;
/**没有建立SCO音频通道*/
公共静态最终int音频\u状态\u断开=0;
/**建立SCO音频通道*/
公共静态最终int音频状态连接=1;
私有静态最终字符串作为\u接口\u方法\u NAME=“asInterface”;
私有静态最终字符串是\u CONNECTED\u METHOD\u NAME=“isConnected”;
最终目标m_服务;
私人蓝牙耳机(对象服务)
{
m_服务=服务;
}
静态公共蓝牙耳机getBluetoothHeadset(IBinder服务)
{
if(服务==null)
{
返回null;
}
对象代理=null;
尝试
{
Class clazz=Class.forName(蓝牙耳机存根类名称);
方法asInterfaceMethod=clazz.getMethod(作为接口方法名称,IBinder.class);
proxy=asInterfaceMethod.invoke(null,服务);
}
捕获(ClassNotFoundException ex)
{
String msg=String.format(“无法找到%s类。”,
蓝牙(耳机、存根、类别、名称);
Log.e(标签、消息、ex);
}
catch(NoSuchMethodException-ex)
{
String msg=String.format(“在%s类中找不到%s方法。”,
作为\u接口\u方法\u名称,
蓝牙(耳机、存根、类别、名称);
Log.e(标签、消息、ex);
}       
捕获(调用TargetException ex)
{
String msg=String.format(“无法调用%s类中的%s方法。”,
作为\u接口\u方法\u名称,
蓝牙(耳机、存根、类别、名称);
Log.e(标签、消息、ex);
}
捕获(非法访问例外)
{
String msg=String.format(“调用%s类中的%s方法时进行非法访问。”,
作为\u接口\u方法\u名称,
蓝牙(耳机、存根、类别、名称);
Log.e(标签、消息、ex);
}
if(proxy==null)返回null;
归还新的蓝牙耳机(代理);
}
公共布尔值isDeviceConnected(蓝牙设备)
{
//调用:布尔值未连接(BluetoothDevice);
尝试
{
Class clazz=m_service.getClass();
方法isConnectedMethod=clazz.getMethod(IS_CONNECTED_Method_NAME,BluetoothDevice.class);
对象结果=isConnectedMethod.invoke(m_服务,设备);
返回(布尔)结果;
}
catch(NoSuchMethodException-ex)
{
String msg=String.format(“在类%s中找不到%s方法”),
已连接方法名称,m_service.getClass().getName());
Log.e(标签、消息、ex);
}
捕获(调用TargetException ex)
{
String msg=String.format(“调用类%s中的%s方法失败”),
已连接方法名称,m_service.getClass().getName());
Log.e(标签、消息、ex);
}   
捕获(非法访问例外)
{
String msg=String.format(“调用类%s中的%s方法时非法访问”),
已连接方法名称,m_service.getClass().getName());
Log.e(标签、消息、ex);
}
捕获(例外情况除外)
{
Log.e(标记“抛出未知异常”,ex);
}
返回null;
}   
}

也尝试通过反射调用此函数。 最终放弃了,改用了广播接收机

声明以下意图过滤器

        <intent-filter >
            <action android:name="android.bluetooth.headset.action.AUDIO_STATE_CHANGED" />
        </intent-filter>
并将int保存为静态变量。只要您想知道BT音频是否已连接(1)/已断开连接(0),请随时访问它。虽然不漂亮,但是完成了任务

另外,请查看:

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