【问题标题】:How to get Bluetooth MAC Address on Android如何在 Android 上获取蓝牙 MAC 地址
【发布时间】:2014-10-28 11:22:46
【问题描述】:

我已经使用以下代码在Android上获取蓝牙的MAC地址:

BluetoothAdapter ba;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
    ba = (BluetoothAdapter) getSystemService(Context.BLUETOOTH_SERVICE);
} else {
    ba = BluetoothAdapter.getDefaultAdapter();
}
Log.i("TEST", ba.getAddress());

另外,我在 Manifest 中添加了权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>

但是,我的应用程序意外停止了。我的代码有什么问题?

使用 Android 2.3.6(三星 Galaxy mini)

更新:我在Class扩展AsyncTask中使用了这段代码。

堆栈跟踪

09-04 01:09:43.671: E/AndroidRuntime(12372): FATAL EXCEPTION: AsyncTask #1
09-04 01:09:43.671: E/AndroidRuntime(12372): java.lang.RuntimeException: An error occured while executing doInBackground()
09-04 01:09:43.671: E/AndroidRuntime(12372):    at android.os.AsyncTask$3.done(AsyncTask.java:200)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at java.lang.Thread.run(Thread.java:1019)
09-04 01:09:43.671: E/AndroidRuntime(12372): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-04 01:09:43.671: E/AndroidRuntime(12372):    at android.os.Handler.<init>(Handler.java:121)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at android.bluetooth.BluetoothAdapter$1.<init>(BluetoothAdapter.java:1117)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at android.bluetooth.BluetoothAdapter.<init>(BluetoothAdapter.java:1117)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at android.bluetooth.BluetoothAdapter.getDefaultAdapter(BluetoothAdapter.java:437)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at org.radyabi.app.StepActivity$CollectDeviceCodes.doInBackground(StepActivity.java:119)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at org.radyabi.app.StepActivity$CollectDeviceCodes.doInBackground(StepActivity.java:1)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at android.os.AsyncTask$2.call(AsyncTask.java:185)
09-04 01:09:43.671: E/AndroidRuntime(12372):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
09-04 01:09:43.671: E/AndroidRuntime(12372):    ... 4 more

【问题讨论】:

  • 发布堆栈跟踪。

标签: android bluetooth


【解决方案1】:

由于Android 6之后的限制,无法通过上述解决方案获得蓝牙MAC。我遇到了这个并且可以正常工作。

 private String getBluetoothMac(final Context context) {

    String result = null;
    if (context.checkCallingOrSelfPermission(Manifest.permission.BLUETOOTH)
            == PackageManager.PERMISSION_GRANTED) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // Hardware ID are restricted in Android 6+
            // https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id
            // Getting bluetooth mac via reflection for devices with Android 6+
            result = android.provider.Settings.Secure.getString(context.getContentResolver(),
                    "bluetooth_address");
        } else {
            BluetoothAdapter bta = BluetoothAdapter.getDefaultAdapter();
            result = bta != null ? bta.getAddress() : "";
        }
    }
    return result;
}

【讨论】:

  • 在 Android 8 和 9 上,这只会产生 null。
  • @AndreasSchildbach 你有 8/9 的替代方法吗?
  • @JohnKoz 不,对不起。 Google 似乎有信心终止所有 P2P 蓝牙通信。
  • 谢谢@AndreasSchildbach,我现在正在研究WifiP2pManager,这似乎是对等通信的战略方向。如果我错了,请纠正我。
【解决方案2】:

This answer 建议您在活动的onCreate 中调用BluetoothAdapter.getDefaultAdapter();,这样它就会被初始化,任何后续调用都会正常进行。

但是,要使用AsynTask,您必须使用runOnUiThread

runOnUiThread(new Runnable() {
    public void run() {
        BluetoothAdapter ba;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            ba = (BluetoothAdapter) getSystemService(Context.BLUETOOTH_SERVICE);
        } else {
            ba = BluetoothAdapter.getDefaultAdapter();
        }
        Log.i("TEST", ba.getAddress());
    }
});

【讨论】:

    猜你喜欢
    • 2022-06-13
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 2012-08-25
    • 1970-01-01
    • 2015-12-30
    • 2020-10-27
    相关资源
    最近更新 更多