Android:添加 ScanCallback 让我 "Unfortunately, App has stopped." 找不到 MainActivity
Android: adding ScanCallback gives me "Unfortunately, App has stopped." can't find MainActivity
我是 android 开发人员的新手。我看过一些 youtube 视频并阅读了一些文档。今天就像第 5 天,所以请耐心等待我。我正在尝试构建一个 BluetoothLE 应用程序。我从 here 窃取了一些代码,但是当我尝试在我的设备上 运行 时。我收到 "Unfortunately, (app name) has stopped" 消息。在注释掉不同的代码块后,我将其固定到声明中:
private ScanCallback mScanCallback = new ScanCallback() {};
如果我包含该行,它就会崩溃。如果我不这样做,它就会活着。这是完整的 Java Class:
package com.tremor.creech.bluetoothExample;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.util.List;
@TargetApi(21)
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 1;
private Handler mHandler;
private static final long SCAN_PERIOD = 10000;
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothGatt mGatt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private ScanCallback mScanCallback = new ScanCallback() { }; //If I include this line, then it crashes. If I take it out, then I see my Hello World activity.
}
LogCat 错误:
09-15 19:16:17.503 1878-1878/com.roberts.croberts.mantis E/dalvikvm﹕ Could not find class 'com.roberts.croberts.mantis.MainActivity', referenced from method com.roberts.croberts.mantis.MainActivity.<init>
09-15 19:16:17.523 1878-1878/com.roberts.croberts.mantis E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.roberts.croberts.mantis, PID: 1878
java.lang.NoClassDefFoundError: com.roberts.croberts.mantis.MainActivity
at com.roberts.croberts.mantis.MainActivity.<init>(MainActivity.java:154)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2119)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2252)
at android.app.ActivityThread.access0(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
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:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
at dalvik.system.NativeStart.main(Native Method)
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ Thread state: conn_id=0, state=RX_THREAD_WAIT_READ
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ Thread state: conn_id=0, state=RX_THREAD_CLIENT_TX
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ qmi_qmux: TX/RX - RX 30 bytes on conn_id=0
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ 01 1D 00 80 03 01 04 00 00 51 00 11 00 10 03 00
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ BA 0E 00 11 08 00 BE 08 00 07 00 00 00 00
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ qmuxd: TX message on fd=29, to qmux_client_id=2, len=64
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ Thread state: conn_id=0, state=RX_THREAD_WAIT_POLL
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
而不是这个
private ScanCallback mScanCallback = new ScanCallback() { };
试试这个
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {};
不幸的是,要在 android 下构建 BLE 应用程序,您必须将 android Jelly Bean MR2(18) + Kitkat(19) 和 Lollipop (21+) 分开。
因为你刚开始,我给你一个大概的检查方法。
首先为 JellyBean/Kitkat and lollipop.
声明这些变量
//For Jelly Bean MR2 and Kitkat
private BluetoothAdapter.LeScanCallback leScanCallback;
//For Lollipop.
private BluetoothLeScanner bluetoothLeScanner;
private ScanCallback scanCallback;
由于它们不是启动程序,因此当您 运行 应用程序时不会出现错误。为了启动目标 api 是什么,您可以使用 Build:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//JellyBean/Kitkat
} else {
//lollipop+
}
另外不要忘记检查 phone 是否真的具有 Ble 功能,是否需要使用清单中的使用功能:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
并检查 PackageManager :
boolean hasBle = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
必须执行此检查,因为一些 phones(如 galaxy nexus)可用于 jelly bean MR2 但没有 BLE 功能)
最后的建议是,要非常小心回调泄漏并 stop/remove 正确回调 ;)
在这个帖子上回复为时已晚,但我想分享我的想法来克服 API 21 以下设备上的崩溃。ScanCallback
class 得到了来自API 21. 所以当你写一个代码在你的扫描代码中实现ScanCallback 时它会导致lover APIs 崩溃。我已经按照以下方式修复它:
我创建了一个新的摘要 class,它扩展了 ScanCallback class,如下所示:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public abstract class AppScanCallback extends ScanCallback {}
现在我在我的 BluetoothService class 中使用这个 class 实例如下:
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private AppScanCallback mScanCallback;
并按如下方式使用此变量:
public void startBleScan() {
if (isEnabled()) {
if (Build.VERSION.SDK_INT < 21) {
_bluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLEScanner = _bluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.build();
filters = new ArrayList<>();
mScanCallback = new AppScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
if (Build.VERSION.SDK_INT >= 21) {
BluetoothDevice btDevice = result.getDevice();
onLeScanResult(btDevice, result.getScanRecord().getBytes());
}
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.i("ScanResult - Results", sr.toString());
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
mLEScanner.startScan(filters, settings, mScanCallback);
}
}
}
并停止扫描
public void stopBLEScan() {;
if (Build.VERSION.SDK_INT < 21) {
_bluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
希望对您有所帮助。
我是 android 开发人员的新手。我看过一些 youtube 视频并阅读了一些文档。今天就像第 5 天,所以请耐心等待我。我正在尝试构建一个 BluetoothLE 应用程序。我从 here 窃取了一些代码,但是当我尝试在我的设备上 运行 时。我收到 "Unfortunately, (app name) has stopped" 消息。在注释掉不同的代码块后,我将其固定到声明中:
private ScanCallback mScanCallback = new ScanCallback() {};
如果我包含该行,它就会崩溃。如果我不这样做,它就会活着。这是完整的 Java Class:
package com.tremor.creech.bluetoothExample;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.util.List;
@TargetApi(21)
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 1;
private Handler mHandler;
private static final long SCAN_PERIOD = 10000;
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothGatt mGatt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private ScanCallback mScanCallback = new ScanCallback() { }; //If I include this line, then it crashes. If I take it out, then I see my Hello World activity.
}
LogCat 错误:
09-15 19:16:17.503 1878-1878/com.roberts.croberts.mantis E/dalvikvm﹕ Could not find class 'com.roberts.croberts.mantis.MainActivity', referenced from method com.roberts.croberts.mantis.MainActivity.<init>
09-15 19:16:17.523 1878-1878/com.roberts.croberts.mantis E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.roberts.croberts.mantis, PID: 1878
java.lang.NoClassDefFoundError: com.roberts.croberts.mantis.MainActivity
at com.roberts.croberts.mantis.MainActivity.<init>(MainActivity.java:154)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2119)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2252)
at android.app.ActivityThread.access0(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
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:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
at dalvik.system.NativeStart.main(Native Method)
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ Thread state: conn_id=0, state=RX_THREAD_WAIT_READ
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ Thread state: conn_id=0, state=RX_THREAD_CLIENT_TX
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ qmi_qmux: TX/RX - RX 30 bytes on conn_id=0
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ 01 1D 00 80 03 01 04 00 00 51 00 11 00 10 03 00
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ BA 0E 00 11 08 00 BE 08 00 07 00 00 00 00
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ qmuxd: TX message on fd=29, to qmux_client_id=2, len=64
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ Thread state: conn_id=0, state=RX_THREAD_WAIT_POLL
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
而不是这个
private ScanCallback mScanCallback = new ScanCallback() { };
试试这个
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {};
不幸的是,要在 android 下构建 BLE 应用程序,您必须将 android Jelly Bean MR2(18) + Kitkat(19) 和 Lollipop (21+) 分开。
因为你刚开始,我给你一个大概的检查方法。
首先为 JellyBean/Kitkat and lollipop.
声明这些变量//For Jelly Bean MR2 and Kitkat
private BluetoothAdapter.LeScanCallback leScanCallback;
//For Lollipop.
private BluetoothLeScanner bluetoothLeScanner;
private ScanCallback scanCallback;
由于它们不是启动程序,因此当您 运行 应用程序时不会出现错误。为了启动目标 api 是什么,您可以使用 Build:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//JellyBean/Kitkat
} else {
//lollipop+
}
另外不要忘记检查 phone 是否真的具有 Ble 功能,是否需要使用清单中的使用功能:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
并检查 PackageManager :
boolean hasBle = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
必须执行此检查,因为一些 phones(如 galaxy nexus)可用于 jelly bean MR2 但没有 BLE 功能)
最后的建议是,要非常小心回调泄漏并 stop/remove 正确回调 ;)
在这个帖子上回复为时已晚,但我想分享我的想法来克服 API 21 以下设备上的崩溃。ScanCallback
class 得到了来自API 21. 所以当你写一个代码在你的扫描代码中实现ScanCallback 时它会导致lover APIs 崩溃。我已经按照以下方式修复它:
我创建了一个新的摘要 class,它扩展了 ScanCallback class,如下所示:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public abstract class AppScanCallback extends ScanCallback {}
现在我在我的 BluetoothService class 中使用这个 class 实例如下:
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private AppScanCallback mScanCallback;
并按如下方式使用此变量:
public void startBleScan() {
if (isEnabled()) {
if (Build.VERSION.SDK_INT < 21) {
_bluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLEScanner = _bluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.build();
filters = new ArrayList<>();
mScanCallback = new AppScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
if (Build.VERSION.SDK_INT >= 21) {
BluetoothDevice btDevice = result.getDevice();
onLeScanResult(btDevice, result.getScanRecord().getBytes());
}
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.i("ScanResult - Results", sr.toString());
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
mLEScanner.startScan(filters, settings, mScanCallback);
}
}
}
并停止扫描
public void stopBLEScan() {;
if (Build.VERSION.SDK_INT < 21) {
_bluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
希望对您有所帮助。