使用 BroadcastReceiver 获取 rssi 值
Get rssi value with BroadcastReceiver
我想用 BroadcastReceiver 获取 rssi 值。当我在 Android 4 上实现下面的代码时效果很好(代码也只有 BroadcastReceiver 并注册了 broadcastReceiver 并且没有权限请求)但没有在 Android 6 中回答和上层。我读到 BroadcastReceiver 已针对 Android 6+ 进行更改,它需要 ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION permission.I 在 android 清单中添加此内容并在 MainActivity 中请求权限但是当我运行 phone 上的代码具有 Android 7 并在蓝牙设备靠近该按钮时单击该按钮会引发异常,而当我单击该按钮时附近没有任何东西时它什么也不显示。
这是我的代码:
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" />
我从这个 link 获得了权限方面的帮助:
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@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.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)
如您的异常所述,问题出在调用
Toast.makeText(MainActivity.this,action, Toast.LENGTH_LONG).show();
如文档所述,Toast.makeText
需要字符串资源标识符 (R.string.<something>
) 作为一个重载中的第二个参数,或者在另一个重载中使用 String
,同时传递 action
,这导致 Toast 查找具有 action
值标识符的资源,但找不到。
如果要Toast
action
值,您必须先将其转换为字符串。最简单的方法是将其用作 action + ""
:
Toast.makeText(MainActivity.this,action + "", Toast.LENGTH_LONG).show();
我想用 BroadcastReceiver 获取 rssi 值。当我在 Android 4 上实现下面的代码时效果很好(代码也只有 BroadcastReceiver 并注册了 broadcastReceiver 并且没有权限请求)但没有在 Android 6 中回答和上层。我读到 BroadcastReceiver 已针对 Android 6+ 进行更改,它需要 ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION permission.I 在 android 清单中添加此内容并在 MainActivity 中请求权限但是当我运行 phone 上的代码具有 Android 7 并在蓝牙设备靠近该按钮时单击该按钮会引发异常,而当我单击该按钮时附近没有任何东西时它什么也不显示。
这是我的代码:
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" />
我从这个 link 获得了权限方面的帮助:
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@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.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)
如您的异常所述,问题出在调用
Toast.makeText(MainActivity.this,action, Toast.LENGTH_LONG).show();
如文档所述,Toast.makeText
需要字符串资源标识符 (R.string.<something>
) 作为一个重载中的第二个参数,或者在另一个重载中使用 String
,同时传递 action
,这导致 Toast 查找具有 action
值标识符的资源,但找不到。
如果要Toast
action
值,您必须先将其转换为字符串。最简单的方法是将其用作 action + ""
:
Toast.makeText(MainActivity.this,action + "", Toast.LENGTH_LONG).show();