Android:支持单个APK上的蓝牙应用程序的多个API级别

时间:2016-07-07 03:43:27

标签: java android bluetooth

我开发了一款在Jelly Bean(Android 4.3)上使用蓝牙功能的应用程序。我注意到Lollipop的蓝牙类有一套不同的方法。当我在Lollipop上运行我的应用程序时,它失败了。

我了解到我可以在运行时添加代码以支持不同的API级别,例如:

private void startScanBluetooth(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Method supported in Lollipop
        mLeScanner.stopScan(mScanCallback);
    }
    else {
        // Method for older API level
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }
}

我的代码有 BluetoothAdapter.LeScanCallback ,它位于我的“活动类”中但不在任何方法之内。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar);
    setContentView(R.layout.device_list);

    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    //....
}

private BluetoothAdapter.LeScanCallback mLeScanCallback =
        new BluetoothAdapter.LeScanCallback() {

            @Override
            public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //String targetDevice = MainActivity.targetDevice.getText().toString();
                                //if(targetDevice==null || targetDevice.length()==0 || targetDevice.equals(device.getName()))
                                addDevice(device,rssi);
                            }
                        });

                    }
                });
            }
        };

由于这个回调已被弃用,我需要一个新的回调方法: ScanCallBack 来支持Lollipop,所以我添加了另一个回调:

    mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Log.i("callbackType", String.valueOf(callbackType));
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    Log.i("result", result.toString());
                    BluetoothDevice btDevice = result.getDevice();
                    connectToDevice(btDevice);
                }
            }
        }
     };

它现在可以在Lollipop中运行,但是当我在4.4.2上运行时,应用程序在运行Class DeviceListActivity 时会出现意外情况(以上所有内容都在此类中。)失败的是:

  

09-02 17:42:46.469 15329-15329/com.conerstoneee2.blecaller D/OLED: Start DeviceListActivity now
09-02 17:42:46.499 15329-15329/com.conerstoneee2.blecaller D/OLED: onPause
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: Unable to resolve superclass of Lcom/conerstoneee2/blecaller/DeviceListActivity$3; (63)
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: Link of class 'Lcom/conerstoneee2/blecaller/DeviceListActivity$3;' failed
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller E/dalvikvm: Could not find class 'com.conerstoneee2.blecaller.DeviceListActivity$3', referenced from method com.conerstoneee2.blecaller.DeviceListActivity.<init>
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: VFY: unable to resolve new-instance 1960 (Lcom/conerstoneee2/blecaller/DeviceListActivity$3;) in Lcom/conerstoneee2/blecaller/DeviceListActivity;
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller D/dalvikvm: VFY: replacing opcode 0x22 at 0x0006
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: VFY: unable to find class referenced in signature (Landroid/bluetooth/le/ScanCallback;)
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller I/dalvikvm: Could not find method android.bluetooth.le.BluetoothLeScanner.startScan, referenced from method com.conerstoneee2.blecaller.DeviceListActivity.scanLeDevice
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: VFY: unable to resolve virtual method 311: Landroid/bluetooth/le/BluetoothLeScanner;.startScan (Landroid/bluetooth/le/ScanCallback;)V
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller D/dalvikvm: VFY: replacing opcode 0x6e at 0x0024
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller I/dalvikvm: Could not find method android.bluetooth.le.BluetoothLeScanner.stopScan, referenced from method com.conerstoneee2.blecaller.DeviceListActivity.scanLeDevice
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: VFY: unable to resolve virtual method 312: Landroid/bluetooth/le/BluetoothLeScanner;.stopScan (Landroid/bluetooth/le/ScanCallback;)V
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller D/dalvikvm: VFY: replacing opcode 0x6e at 0x0041
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller I/dalvikvm: Could not find method android.bluetooth.BluetoothAdapter.getBluetoothLeScanner, referenced from method com.conerstoneee2.blecaller.DeviceListActivity.onCreate
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: VFY: unable to resolve virtual method 283: Landroid/bluetooth/BluetoothAdapter;.getBluetoothLeScanner ()Landroid/bluetooth/le/BluetoothLeScanner;
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller D/dalvikvm: VFY: replacing opcode 0x6e at 0x0071
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller I/dalvikvm: Could not find method android.bluetooth.le.BluetoothLeScanner.stopScan, referenced from method com.conerstoneee2.blecaller.DeviceListActivity.onDestroy
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: VFY: unable to resolve virtual method 312: Landroid/bluetooth/le/BluetoothLeScanner;.stopScan (Landroid/bluetooth/le/ScanCallback;)V
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller D/dalvikvm: VFY: replacing opcode 0x6e at 0x0014
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller I/dalvikvm: Could not find method android.bluetooth.le.BluetoothLeScanner.stopScan, referenced from method com.conerstoneee2.blecaller.DeviceListActivity.onStop
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: VFY: unable to resolve virtual method 312: Landroid/bluetooth/le/BluetoothLeScanner;.stopScan (Landroid/bluetooth/le/ScanCallback;)V
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller D/dalvikvm: VFY: replacing opcode 0x6e at 0x0014
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: Unable to resolve superclass of Lcom/conerstoneee2/blecaller/DeviceListActivity$3; (63)
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: Link of class 'Lcom/conerstoneee2/blecaller/DeviceListActivity$3;' failed
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller D/dalvikvm: DexOpt: unable to opt direct call 0x3ea0 at 0x08 in Lcom/conerstoneee2/blecaller/DeviceListActivity;.<init>
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller D/AndroidRuntime: Shutting down VM
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41f8bda0)
09-02 17:42:46.519 15329-15329/com.conerstoneee2.blecaller E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: com.conerstoneee2.blecaller, PID: 15329
                                                                             java.lang.NoClassDefFoundError: com.conerstoneee2.blecaller.DeviceListActivity$3
                                                                                 at com.conerstoneee2.blecaller.DeviceListActivity.<init>(DeviceListActivity.java:181)
                                                                                 at java.lang.Class.newInstanceImpl(Native Method)
                                                                                 at java.lang.Class.newInstance(Class.java:1208)
                                                                                 at android.app.Instrumentation.newActivity(Instrumentation.java:1067)
                                                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2289)
                                                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2453)
                                                                                 at android.app.ActivityThread.access$900(ActivityThread.java:173)
                                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                 at android.os.Looper.loop(Looper.java:136)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5579)
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
                                                                                 at dalvik.system.NativeStart.main(Native Method)
09-02 17:42:49.959 15329-15329/com.conerstoneee2.blecaller I/Process: Sending signal. PID: 15329 SIG: 9

更新 感谢@Jesse指出我可以在回调中添加用于检查构建版本的代码。它可以成功构建APK,但现在它无法在4.4.2中运行

1 个答案:

答案 0 :(得分:1)

你关闭了。 BluetoothAdapter.LeScanCallback是一个界面。当你这样做时:

private BluetoothAdapter.LeScanCallback mLeScanCallback =
        new BluetoothAdapter.LeScanCallback() {

            @Override
            public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //String targetDevice = MainActivity.targetDevice.getText().toString();
                                //if(targetDevice==null || targetDevice.length()==0 || targetDevice.equals(device.getName()))
                                addDevice(device,rssi);
                            }
                        });

                    }
                });
            }
        };

&#34;它位于[您的]活动类中但不在任何方法之外。&#34;这段代码没有发生任何事情。当你这样称呼时:

mLeScanner.stopScan(mScanCallback);

并将其作为参数传递。如果需要,mLeScanner会使用该回调。

因此,只需创建额外的回调方法(不要检查构建版本)。

 private **typeNameGoesHere** mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            Log.i("callbackType", String.valueOf(callbackType));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Log.i("result", result.toString());
                BluetoothDevice btDevice = result.getDevice();
                connectToDevice(btDevice);
            }
        }
    };

然后保持你的startScanBluetooth方法原样,你应该没事。

private void startScanBluetooth(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Method supported in Lollipop
        mLeScanner.stopScan(mScanCallback);
    }
    else {
        // Method for older API level
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }
}