Получите значение rssi с BroadcastReceiver

Я хочу получить значение rssi с BroadcastReceiver. Когда я реализовал приведенный ниже код на Android 4, он работал хорошо (также код имел только BroadcastReceiver и был зарегистрирован на broadcastReceiver и не имел таких запросов на разрешения), но не отвечал в Android 6 и выше. Я прочитал, что BroadcastReceiver изменился для Android 6+ и требует разрешения ACCESS_FINE_LOCATION и ACCESS_COARSE_LOCATION. Я добавил это в манифест Android и запросил разрешения в MainActivity, но когда я запускаю код на телефоне с Android 7 и нажимаю кнопку, когда устройство Bluetooth рядом с ним выдается исключение, а когда рядом нет ничего, когда я нажимаю кнопку, он ничего не показывает. Вот мой код:

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter BTAdapter = BluetoothAdapter.getDefaultAdapter();
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout);
    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v) {
        checkLocationPermission();
        proceedDiscovery();
        }
        });
        }



private final BroadcastReceiver receiver = new BroadcastReceiver(){
        @Override
        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();
            Toast.makeText(MainActivity.this,action, Toast.LENGTH_LONG).show();
            if(BluetoothDevice.ACTION_FOUND.equals(action)) {
                int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
                String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
                TextView rssi_msg = (TextView) findViewById(R.id.textView);
                rssi_msg.setText(rssi_msg.getText() + name + " => " + rssi + "dBm"+"\n");
            }
        }
    };

protected void checkLocationPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 0);
                int MY_PERMISSIONS_REQUEST = 200;
                int permissions=ContextCompat.checkSelfPermission (this,Manifest.permission.ACCESS_FINE_LOCATION);
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST);
        }}
    }
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 0: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    proceedDiscovery();
                } 
else{}
                break;
            }
        }}
    protected void proceedDiscovery() {
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothDevice.ACTION_NAME_CHANGED);
        registerReceiver(receiver, filter);
        BTAdapter.startDiscovery();
    }}

и мой манифест Android имеет эти разрешения:

<uses-feature android:name="android.hardware.bluetooth" />
    <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" />

Я получил помощь по разрешениям по этой ссылке: правильная процедура обнаружения устройства BT на Зефире

Исключения в logcat:

08-16 14:33:16.341 6630-6630/com.example.hanane.rssi E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.hanane.rssi, PID: 6630
    java.lang.RuntimeException: Error receiving broadcast Intent { act=android.bluetooth.device.action.FOUND flg=0x10 launchParam=MultiScreenLaunchParams { mDisplayId=0 mBaseDisplayId=0 mFlags=0 } bqHint=1 (has extras) } in com.example.hanane.rssi.MainActivity$2@a1e9394
        at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1195)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6816)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1565)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1453)
     Caused by: android.content.res.Resources$NotFoundException: String resource ID #0xffffffd4
        at android.content.res.Resources.getText(Resources.java:1184)
        at android.widget.Toast.makeText(Toast.java:460)
        at com.example.hanane.rssi.MainActivity$2.onReceive(MainActivity.java:75)
        at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1185)
        at android.os.Handler.handleCallback(Handler.java:751) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6816) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1565) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1453) 

1 ответ

Решение

Как говорит ваше исключение, проблема заключается в вызове

Toast.makeText(MainActivity.this,action, Toast.LENGTH_LONG).show();

Как сказано в документации, Toast.makeText требуется идентификатор ресурса строки (R.string.<something>) как 2-й параметр в одной перегрузке, или String в другом, пока вы проходите action, что заставляет Toast искать ресурс с идентификатором action значение, которое он не может найти.

Если хотите Toast action значение, вы должны сначала преобразовать его в строку. Самый простой способ - использовать его как action + "":

Toast.makeText(MainActivity.this,action + "", Toast.LENGTH_LONG).show();
Другие вопросы по тегам