2017-08-17 6 views
-2

私は誰かが私にこの問題に関して助言を与えることを願っています。私は運がなければそれを解決しようとしていましたが、これは本当の問題であり、そこには多くの議論があります。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ストアにはビーコンとして機能するアプリがたくさんあります)。

多くの人が同じ問題で苦労しています。herehereなどの質問があります。ちょっと古いかもしれませんが、それでも有効です。

以下の完全なコードをテストすることができます。

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) 
+0

質問デバッグヘルプ(「なぜこのコードは動作しませんか?」)には、目的の動作、特定の問題またはエラー、および質問自体に再現するのに必要な最短コードが含まれている必要があります。明確な問題文がない質問は、他の読者にとって有用ではありません。参照:[最小限で完全で検証可能な例を作成する方法](https://stackoverflow.com/help/mcve) – Bob

+0

ご意見ありがとうございます。私は自分自身を可能な限り明確にしようとしました。プログラムでは、ボタンが押され、アプリケーションがクラッシュしています。 – aecheverri

+0

クラッシュログを投稿してください。 – Bob

答えて

0

あなたBluetoothLeAdvertiser advertiserは、null参照を持っています。おそらく、BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser()がnullを返すためです。

+0

私はログであなたが正しいことを見ました。しかし、私はヌルかそれが有効でないかどうかをチェックする条件を作成することができます: if(mBluetoothAdapter == null || mBluetoothAdapter.isEnabled()) – aecheverri

+0

これを確認してください:https://stackoverflow.com/ a/37938934/4586742 – Bob

+0

私はちょうどコードに次の行を追加しました(私はポストで行われたすべての提案をチェックする更新されたコードを見てください)。まだクラッシュしている、私は私のデバイスが周辺機器としてBluetoothとBLEをサポートしていることを知っています。ただし、BluetoothAdpterは一度オンにしてはいけません。さもないと。 BluetoothAdpterをどのように割り当てる必要がありますか? – aecheverri

関連する問題