web-dev-qa-db-ja.com

AndroidデバイスがAndroid時計とペアリングされている)かどうかを検出する方法

私はAndroidプッシュ通知を拡張するWearアプリを作成しています。私のアプリは、プッシュ通知が来たときにサーバーから約10枚の画像をダウンロードし、これらの追加の画像を時計に表示します。これらの画像は、 Android Wearアプリであり、ハンドヘルドデバイスには表示されません。

ハンドヘルドデバイスがAndroid Wearデバイスとペアリングされているかどうかを確認して、Wearアプリに必要な追加の画像をダウンロードする必要があるかどうかを判断できるようにするにはどうすればよいですか?

ありがとう!

21
TWilly

NodeApi、特に NodeApi.getConnectedNodes() を使用する必要があります。

たとえば(バックグラウンドスレッドから-それ以外の場合はsetResultCallback()ではなくawait()を使用します):

List<Node> connectedNodes =
    Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await().getNodes();

返されたノードのリストに少なくとも1つの要素が含まれている場合、接続されたAndroid Wearデバイスがあります。それ以外の場合はありません。


更新: Google Play Services 7. のリリースで、複数のAndroid同時に接続されたWearデバイスのサポートが追加されました。 CapabilityApi 特定の機能を持つノードを要求します。

17
matiash

ここにはすでに2つのオプションがリストされています。どちらもユースケースに応じて有効です。 3番目のオプションを追加したいのですが、不完全です。

オプション1:NodeApiを使用して接続されたノードを見つける

NodeApiクラスには、接続されたノードを取得するためのメソッドがあります。これにより、ユーザーは過去に時計を持っていなかったか、またはいつか時計をテストしたことがなかったことを確信しています。彼は本当に近くに時計を持っています。

このアプローチの欠点は、Bluetoothが有効になっていないか、現時点で時計が接続されていない場合、結果が得られないことです。

メソッドは次のとおりです。

List<Node> connectedNodes =
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await().getNodes();

より完全なコード例は次のようになります。

private GoogleApiClient client;
private static final long CONNECTION_TIME_OUT_MS = 1000;

public void checkIfWearableConnected() {

    retrieveDeviceNode(new Callback() {
        @Override
        public void success(String nodeId) {
            Toast.makeText(this, "There was at least one wearable found", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void failed(String message) {
            Toast.makeText(this, "There are no wearables found", Toast.LENGTH_SHORT).show();
        }
    });

}

private GoogleApiClient getGoogleApiClient(Context context) {
        if (client == null)
            client = new GoogleApiClient.Builder(context)
                    .addApi(Wearable.API)
                    .build();
        return client;
    }

private interface Callback {
        public void success(final String nodeId);
        public void failed(final String message);
    }

private void retrieveDeviceNode(final Callback callback) {
        final GoogleApiClient client = getGoogleApiClient(this);
        new Thread(new Runnable() {

            @Override
            public void run() {
                client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
                NodeApi.GetConnectedNodesResult result =
                        Wearable.NodeApi.getConnectedNodes(client).await();
                List<Node> nodes = result.getNodes();
                if (nodes.size() > 0) {
                    String nodeId = nodes.get(0).getId();
                    callback.success(nodeId);
                } else {
                    callback.failed("no wearables found");
                }
                client.disconnect();
            }
        }).start();
    }

オプション2:Android Wearアプリを確認します

これが2番目のオプションの利点です。時計を入手した場合、接続するために最初に行うことは、ハンドヘルドにAndroid Wearアプリをインストールすることです。したがって、PackageManagerを使用してこれを確認できますAndroid Wearアプリがインストールされています。

ここでの欠点は、時計がなくてもWearアプリをインストールできることです。

コード例:

try {
    getPackageManager().getPackageInfo("com.google.Android.wearable.app", PackageManager.GET_META_DATA);

    Toast.makeText(this, "The Android Wear App is installed", Toast.LENGTH_SHORT).show();
} catch (PackageManager.NameNotFoundException e) {
    //Android wear app is not installed
    Toast.makeText(this, "The Android Wear App is NOT installed", Toast.LENGTH_SHORT).show();
}

オプション3:ペアリングされたデバイスを確認する

これが可能かどうかはわかりませんが、ユーザーが時計を自分のデバイスとペア設定していて、同時に接続する必要がないことを確認できるため、これが最適な解決策になる場合があります。

以下はコード例ですが、ペアリングされたデバイスがウェアラブルかどうかの確認は含まれていません。これは単なる出発点です。

コード例: getbondeddevices()がペアリングされたBluetoothデバイスを返さない

BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();

Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
     Toast.makeText(this, "At least one paired bluetooth device found", Toast.LENGTH_SHORT).show();
    // TODO at this point you'd have to iterate these devices and check if any of them is a wearable (HOW?)
    for (BluetoothDevice device : pairedDevices) {
        Log.d("YOUR_TAG", "Paired device: "+ device.getName() + ", with address: " + device.getAddress());
    }
} else {
    Toast.makeText(this, "No paired bluetooth devices found", Toast.LENGTH_SHORT).show();
}

このコードにはマニフェストでのBluetooth権限が必要です。

<uses-permission Android:name="Android.permission.BLUETOOTH" />
<uses-permission Android:name="Android.permission.BLUETOOTH_ADMIN"/>
20
hcpl

とりわけ、ハンドヘルドデバイスのみが接続されている場合は正解ですAndroid Watch。ハンドヘルドデバイスが複数のデバイス(マルチウェアラブル)に接続されている場合は、Android Watch、 HealthBand、Beaconなど、上記の回答が機能しない場合があります。

次のセクションでは、アクティビティ要求を処理できるデバイスノードをアドバタイズし、要求されたニーズを満たすことができるノードを発見し、それらのノードにメッセージを送信する方法を示します。

アドバタイズ機能

ウェアラブルデバイスからハンドヘルドデバイスでアクティビティを起動するには、MessageApiクラスを使用してリクエストを送信します。複数のウェアラブルをハンドヘルドデバイスに接続できるため、ウェアラブルアプリは、接続されたノードがアクティビティを起動できることを確認する必要があります。ハンドヘルドアプリで、アプリが実行されているノードが特定の機能を提供していることを宣伝します。

ハンドヘルドアプリの機能を宣伝するには:

  1. プロジェクトのres/values /ディレクトリにXML構成ファイルを作成し、wear.xmlという名前を付けます。
  2. Android_wear_capabilitiesという名前のリソースをwear.xmlに追加します。
  3. デバイスが提供する機能を定義します。

<resources>
    <string-array name="Android_wear_capabilities">
        <item>Android_wear</item>
    </string-array> 
</resources>

必要な機能を持つノードを取得します

最初に、CapabilityApi.getCapability()メソッドを呼び出すことにより、対応するノードを検出できます。次の例は、Android_wear機能を使用して、到達可能なノードの結果を手動で取得する方法を示しています。 Wearモジュールで次のコードを使用します。

public abstract class BaseActivity extends Activity implements MessageApi.MessageListener, NodeApi.NodeListener,
    DataApi.DataListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private static final String
        SMART_WEAR_CAPABILITY_NAME = "Android_wear";

protected GoogleApiClient mGoogleApiClient;
protected ArrayList<String> results;
private String TAG = "BaseActivity::Wear";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Wearable.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();
}

private Collection<String> getNodes() {
    results = new ArrayList<>();
    NodeApi.GetConnectedNodesResult nodes =
            Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();

    for (Node node : nodes.getNodes()) {
        Log.d(TAG, node.getId());
        results.add(node.getId());
    }

    return results;
}

@Override
protected void onResume() {
    super.onResume();
    mGoogleApiClient.connect();
}

@Override
protected void onPause() {
    super.onPause();
    Wearable.MessageApi.removeListener(mGoogleApiClient, this);
    Wearable.NodeApi.removeListener(mGoogleApiClient, this);
    Wearable.DataApi.removeListener(mGoogleApiClient, this);
    mGoogleApiClient.disconnect();
}

@Override
public void onConnected(Bundle bundle) {
    Log.d(TAG, "onConnected(): Successfully connected to Google API client");
    Wearable.MessageApi.addListener(mGoogleApiClient, this);
    Wearable.DataApi.addListener(mGoogleApiClient, this);
    Wearable.NodeApi.addListener(mGoogleApiClient, this);
    results = new ArrayList<>();

    getNodeIdOfHandheldDevice();
}

@Override
public void onConnectionSuspended(int i) {
    Log.d(TAG, "onConnectionSuspended(): Connection to Google API client was suspended");
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.e(TAG, "onConnectionFailed(): Failed to connect, with result: " + connectionResult);
}

@Override
public void onPeerConnected(Node node) {
    Log.e(TAG, "onPeerConnected():");
}

@Override
public void onPeerDisconnected(Node node) {
    Log.e(TAG, "onPeerDisconnected():");
}

private void getNodeIdOfHandheldDevice() {
    Wearable.CapabilityApi.getCapability(
            mGoogleApiClient, SMART_WEAR_CAPABILITY_NAME,
            CapabilityApi.FILTER_REACHABLE).setResultCallback(
            new ResultCallback<CapabilityApi.GetCapabilityResult>() {
                @Override
                public void onResult(CapabilityApi.GetCapabilityResult result) {
                    if (result.getStatus().isSuccess()) {
                        updateFindMeCapability(result.getCapability());
                    } else {
                        Log.e(TAG,
                                "setOrUpdateNotification() Failed to get capabilities, "
                                        + "status: "
                                        + result.getStatus().getStatusMessage());
                    }
                }
            });
}

private void updateFindMeCapability(CapabilityInfo capabilityInfo) {
    Set<Node> connectedNodes = capabilityInfo.getNodes();
    if (connectedNodes.isEmpty()) {
        results.clear();
    } else {
        for (Node node : connectedNodes) {
            // we are only considering those nodes that are directly connected
            if (node.isNearby()) {
                results.add(node.getId());
            }
        }
    }
}

}

詳細については、 Android Dev を確認してください。

7
Umang Kothari

私の使用例に適したはるかに単純な方法を使用しています。Android Wearアプリがインストールされているかどうかを確認してください。

    try {
        getPackageManager().getPackageInfo("com.google.Android.wearable.app", PackageManager.GET_META_DATA);
    } catch (PackageManager.NameNotFoundException e) {
        //Android wear app is not installed
    }
2
Oded Breiner

ペアリングされたデバイスを確認する

ユーザーが時計とデバイスをペア設定していることを確認できますが、現時点では接続する必要はありません。これにより、検出時に時計を接続する必要がなくなります。

BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();

Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
    for (BluetoothDevice device : pairedDevices) {
        if(device.getDeviceClass()==BluetoothClass.Device.WEARABLE_WRIST_WATCH){
            Log.d("Found", "Paired wearable: "+ device.getName() + ", with address: " + device.getAddress());
        {
    {
} else {
    Toast.makeText(this, "No paired wearables found", Toast.LENGTH_SHORT).show();
}

このコードにはマニフェストでのBluetooth権限が必要です。

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