我希望有人可以給我一個關於這個問題的建議。我一直試圖解決它沒有任何運氣,我也看到這是一個真正的問題,並有很多討論。BLE應用程序崩潰,當應用程序檢查藍牙是否enablea和mBluetoothAdapter.isMultipleAdvertisementSupported()返回false
這是一個簡單的應用程序,只有一個按鈕。該按鈕將使設備在按下時作爲信標工作,並且釋放按鈕時它將停止發送數據。開始時,應用程序將檢查此question中建議的藍牙和BLE是否受支持。
當設備沒有打開藍牙並要求用戶將其打開時,應用程序崩潰。但是,當設備啓用藍牙時,它不會崩潰。
做了進一步的分析,我看到下面的代碼片段被執行,向我顯示消息,該設備不支持BLE。
if (mBluetoothAdapter.isEnabled()==false) {
mBluetoothAdapter.enable();
Toast.makeText(getApplicationContext(),"Enabling Bluetooth", Toast.LENGTH_SHORT).show();
Log.e("BLE_code", "State: " + mBluetoothAdapter.getState());
}
if(!mBluetoothAdapter.isMultipleAdvertisementSupported()){
Toast.makeText(getApplicationContext(),"Device does not support BLE", Toast.LENGTH_SHORT).show();
}
我也搜索過此website,看看如果設備不支持BLE,它可能不會有(我用三星Galaxy S7工作),但我已經試過了,建議應用檢查設備是否允許在外設模式下使用BLE,並且可以發現它。 (在谷歌商店有很多應用程序作爲信標工作)。
還有更多的人在同一問題here,here和其他一些問題上掙扎。它可能有點舊,但仍然有效。
你可以在下面找到完整的代碼來測試。
EDITED:
MainActivity.java
package com.ble_app.aecheverri.ble_app;
import android.bluetooth.le.AdvertiseSettings;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.content.Intent;
import android.util.Log;
import java.nio.charset.Charset;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.os.ParcelUuid;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseCallback;
import android.widget.EditText;
import java.util.UUID;
import android.content.Context;
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter mBluetoothAdapter;
private final static int REQUEST_ENABLE_BT = 1;
private Button btn;
private BluetoothLeAdvertiser mBluetoothLeAdvertiser;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.BLE_CHECK_button);
final EditText edit = (EditText) findViewById(R.id.Data_Sent);
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
mBluetoothAdapter.setName("APEX");
//Check if bluetooth is on, otherwise, turn it on!
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
Log.e("BLE_code", "State: " + mBluetoothAdapter.getBluetoothLeAdvertiser());
//getBluetoothLeScanner
if (mBluetoothAdapter.isEnabled()==false) {
mBluetoothAdapter.enable();
Toast.makeText(getApplicationContext(),"Enabling Bluetooth", Toast.LENGTH_SHORT).show();
Log.e("BLE_code", "State: " + mBluetoothAdapter.getState());
}
if(!mBluetoothAdapter.isMultipleAdvertisementSupported()){
Toast.makeText(getApplicationContext(),"Device does not support BLE", Toast.LENGTH_SHORT).show();
}
final BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
//Set the advertise settings and the power of the signal
final AdvertiseSettings settings = new AdvertiseSettings.Builder()
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
.setConnectable(false)
.build();
final AdvertiseCallback advertisingCallback = new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
}
@Override
public void onStartFailure(int errorCode) {
Log.e("BLE_code", "Advertising onStartFailure: " + errorCode);
super.onStartFailure(errorCode);
}
};
//BLE Button
btn.setOnTouchListener(new View.OnTouchListener() {
private Handler mHandler;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction())
{
case MotionEvent.ACTION_DOWN:
Log.e("BLE_code","Button is being pressed");
Log.e("BLE_code", "State ble: " + mBluetoothAdapter.getState());
ParcelUuid pUuid = new ParcelUuid(UUID.fromString(getString(R.string.ble_uuid)));
AdvertiseData data = new AdvertiseData.Builder()
.setIncludeDeviceName(true)
.addServiceUuid(pUuid)
.addServiceData(pUuid,edit.getText().toString().getBytes(Charset.forName("UTF-8")))
.build();
Log.e("BLE_code", "Sent Data: " + edit.getText().toString());
String macAddress = android.provider.Settings.Secure.getString(getContentResolver(),"bluetooth_address");
Toast.makeText(getApplicationContext(),"Device: " + macAddress, Toast.LENGTH_SHORT).show();
mBluetoothLeAdvertiser.startAdvertising(settings, data, advertisingCallback);
//advertiser.startAdvertising(settings, data, advertisingCallback);
if (mHandler!=null) return true;
mHandler = new Handler();
mHandler.postDelayed(btn_pressed,10);
break;
case MotionEvent.ACTION_UP:
if(mHandler==null) return true;
mHandler.removeCallbacks(btn_pressed);
mHandler = null;
advertiser.stopAdvertising(advertisingCallback);
Toast.makeText(getApplicationContext(),"Stoping Advertising", Toast.LENGTH_SHORT).show();
Log.e("BLE_code","Button was released");
break;
}
return false;
}
Runnable btn_pressed = new Runnable() {
public void run(){
Log.e("BLE_code","Button while pressed");
mHandler.postDelayed(this,10);
}
};
});
}
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ble_app.aecheverri.ble_app.MainActivity">
<Button
android:id="@+id/BLE_CHECK_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="195dp"
android:text="Authenticate"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.474" />
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
app:layout_constraintGuide_begin="20dp"
android:orientation="vertical" />
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline2"
android:orientation="vertical"
app:layout_constraintGuide_end="340dp" />
<EditText
android:id="@+id/Data_Sent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:text="Data"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/BLE_CHECK_button"
app:layout_constraintVertical_bias="0.683"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.503" />
</android.support.constraint.ConstraintLayout>
的AndroidManifest.xml
個<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ble_app.aecheverri.ble_app">
<!-- Declare this required feature if you want to make the app available to BLE-capable
devices only. If you want to make your app available to devices that don't support BLE,
you should omit this in the manifest. Instead, determine BLE capability by using
PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) -->
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
的strings.xml
<resources>
<string name="app_name">BLE_app</string>
<string name="ble_uuid">00000218-0000-1000-8000-00805f9b34fb</string>
</resources>
記錄錯誤
08-17 13:55:25.533 13469-13469/com.ble_app.aecheverri.ble_app E/BoostFramework: BoostFramework() : Exception_1 = java.lang.ClassNotFoundException: Didn't find class "com.qualcomm.qti.Performance" on path: DexPathList[[],nativeLibraryDirectories=[/system/lib64, /vendor/lib64]]
08-17 13:55:25.566 13469-13469/com.ble_app.aecheverri.ble_app E/InputEventReceiver: Exception dispatching input event.
08-17 13:55:25.567 13469-13469/com.ble_app.aecheverri.ble_app E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
08-17 13:55:25.569 13469-13469/com.ble_app.aecheverri.ble_app E/MessageQueue-JNI: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.le.BluetoothLeAdvertiser.startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback)' on a null object reference
at com.ble_app.aecheverri.ble_app.MainActivity$2.onTouch(MainActivity.java:101)
at android.view.View.dispatchTouchEvent(View.java:10727)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:509)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1863)
at android.app.Activity.dispatchTouchEvent(Activity.java:3226)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:471)
at android.view.View.dispatchPointerEvent(View.java:10960)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5075)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4927)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4511)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4477)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4610)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4485)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4667)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4511)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4477)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4485)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6960)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6899)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6860)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7070)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:323)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
08-17 13:55:25.571 13469-13469/com.ble_app.aecheverri.ble_app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ble_app.aecheverri.ble_app, PID: 13469
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.le.BluetoothLeAdvertiser.startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback)' on a null object reference
at com.ble_app.aecheverri.ble_app.MainActivity$2.onTouch(MainActivity.java:101)
at android.view.View.dispatchTouchEvent(View.java:10727)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:509)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1863)
at android.app.Activity.dispatchTouchEvent(Activity.java:3226)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:471)
at android.view.View.dispatchPointerEvent(View.java:10960)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5075)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4927)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4511)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4477)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4610)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4485)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4667)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4511)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4477)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4485)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6960)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6899)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6860)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7070)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:323)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
尋求調試幫助的問題(「爲什麼不是這個代碼工作?」)必須包含所需的行爲,特定的問題或錯誤以及在問題本身中重現問題所需的最短代碼。沒有明確問題陳述的問題對其他讀者無益。請參閱:[如何創建最小,完整和可驗證的示例。](https://stackoverflow.com/help/mcve) – Bob
感謝您的建議。我試圖讓自己儘可能清楚。在程序中,有一個按鈕被按下,應用程序崩潰。 – aecheverri
然後請發佈您的崩潰日誌。 – Bob