私は誰かが私にこの問題に関して助言を与えることを願っています。私は運がなければそれを解決しようとしていましたが、これは本当の問題であり、そこには多くの議論があります。Bluetoothが有効で、mBluetoothAdapter.isMultipleAdvertisementSupported()がfalseを返すかどうかをアプリがチェックすると、BLEアプリがクラッシュする
これはボタンだけを持つ簡単なアプリです。ボタンを押すとビーコンとして機能するようになり、ボタンが離されるとデータの送信が停止されます。最初に、このアプリはBluetoothとBLEがこのquestionで提案されているかどうかをチェックします。
デバイスがBluetoothをオンにしていないときにアプリがクラッシュし、ユーザーに電源をオンにするように要求されます。しかし、デバイスがBluetoothを既にオンにしているときにクラッシュすることはありません。
さらに分析を行うと、デバイスが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();
}
私はまた、デバイスが(私はサムスンギャラクシーS7で働いている)BLEサポートしない場合、それはそこではないかもしれませんが、私は提案されているアプリを試してみました表示するには、このwebsiteで検索デバイスがペリフェラルモードでBLEを許可しているかどうかを確認し、検出できます。 (Googleストアにはビーコンとして機能するアプリがたくさんあります)。
多くの人が同じ問題で苦労しています。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