Android 11 APIレベル30 からペアリングしたBluetoothデバイスの自分でつけた「名前」が取得できるメソッドが追加されていた

Androidの`BluetoothDevice`のメソッドには、アドレスを取得する`getAddress()`と`getName()`があって、接続に必要なアドレスはAPIレベル5からあったようですが、`getName()`の方はデバイスに元々つけられた名前しか返ってきませんでした。いくつかのBluetoothデバイスを切り替えたいときに、元々の名前が同じデバイスもあり、いちいちアドレスの番号を覚えていられないので自分で付け替えた後の名前が取得できないかな、と思っていたところ、「[ペアリングしたBluetoothデバイスの「名前」を取得する方法](https://qiita.com/tkt989/items/24b7721515d2864c97c5)」を見つけ、使っていました。

https://qiita.com/tkt989/items/24b7721515d2864c97c5

記事中に、

> `@hide`なメソッドなので使用する際は注意。

と書いてあったので、使えなくなったりするのかな、と思っていたのですが、最近Qiita記事を書く時に何気に見たら、API レベル30から使えるようになっていました。

![Added in API Level 30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335076/e3b8431a-50d3-ca07-caec-8fbe1ab56f79.png)

https://developer.android.com/reference/android/bluetooth/BluetoothDevice#getAlias()

ペア設定済みのデバイスをリスト化する場合に使うと、こんな感じでしょうか。
```java:DeviceListActivity.java

	...
        // Initialize array adapters. One for already paired devices and
        // one for newly discovered devices
        ArrayAdapter<String> pairedDevicesArrayAdapter = new ArrayAdapter<>(this, R.layout.device_name);
        // Find and set up the ListView for paired devices
        ListView pairedListView = findViewById(R.id.paired_devices);
        pairedListView.setAdapter(pairedDevicesArrayAdapter);
        pairedListView.setOnItemClickListener(mDeviceClickListener);

        // Get the local Bluetooth adapter
        // Member fields
        BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();

        // Get a set of currently paired devices
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
        // If there are paired devices, add each one to the ArrayAdapter
        if (pairedDevices.size() > 0) {
            findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
            for (BluetoothDevice device : pairedDevices) {
//                pairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
//                Log.d(TAG, "deviceName = " + device.getName() + ",Address = " + device.getAddress());
                String deviceName;
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R){
                    deviceName = device.getAlias() == null ? device.getName() : getAlias(device);
                } else {
                    deviceName = getAlias(device) == null ? device.getName() : getAlias(device);
                }
                pairedDevicesArrayAdapter.add(deviceName + "\n" + device.getAddress());
                Log.d(TAG, "deviceName = " + deviceName);
            }
        } else {
            String noDevices = getResources().getText(R.string.none_paired).toString();
            pairedDevicesArrayAdapter.add(noDevices);
        }

	...

    // https://qiita.com/tkt989/items/24b7721515d2864c97c5
    // ペアリングしたBluetoothデバイスの「名前」を取得する方法 より
    private String getAlias(BluetoothDevice device) {
        try {
            Method getAlias = BluetoothDevice.class.getMethod("getAlias");
            return (String) getAlias.invoke(device);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            return null;
        }
    }
```

車の故障診断コネクターに取り付けるOBDアダプターをいくつか試していますが、名前が同じだったりするので、`getAlias()`を使うと自分が変更した名前で表示されるので便利です。実機デバッグをAndroid10 API level 29とAndroid 12 APIレベル31で試しましたが、どちらも自分で変更した名前が表示されました。
![getNameとgetAliasの違い.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335076/92153208-513e-9cb3-aafa-cbf0646c2d2b.png)

試したアプリは「[Android端末とOBD2スキャンツールを使って車の内部データを取得するアプリに車のキー操作(電源接続)と連動してデータを取得する機能を追加](https://qiita.com/naoto_deuxchats/items/f95df655b32f64afc51c)」で作ったものです。

https://qiita.com/naoto_deuxchats/items/f95df655b32f64afc51c