如何检测Android设备是否与Android佩戴手表配对

我正在创build一个扩展推送通知的Android Wear应用程序。 当推送通知进入时,我的应用程序会从服务器下载约10张图像,并在手表上显示这些附加图像。 这些图像是特定于Android Wear应用程序,并没有显示在手持设备上。

如何判断手持设备是否与Android Wear设备配对,以确定是否需要下载该Wear设备所需的附加图像?

谢谢!

Solutions Collecting From Web of "如何检测Android设备是否与Android佩戴手表配对"

您需要使用NodeApi ,特别是NodeApi.getConnectedNodes()

例如(从后台线程 – 否则使用setResultCallback()而不是await() ):

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

如果返回的节点列表中至less包含一个元素,则表示连接了Android Wear设备,否则不存在。


更新:随着Google Play Services 7.3的发布,同时支持多个Android Wear设备。 您可以使用CapabilityApi来请求具有特定function的节点。

这里已经有2个选项了。 根据您的使用情况,它们都是有效的。 我想添加第三个选项,但不完整。

选项1:使用NodeApi查找连接的节点

NodeApi类有一个检索连接节点的方法。 有了这个,你可以肯定的是,用户过去不是只有一只手表,或者有一次testing过。 他真的有附近的手表和连接。

这种方法的缺点是,如果蓝牙未启用或手表目前未连接,则您将得不到结果。

方法是:

 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应用程序

这是第二个选项的优点。 如果您要看手表,首先要做的就是在掌上电脑上安装Android Wear应用程序。 所以你可以使用PackageManager来validation这个Android 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:检查配对的设备

不知道这是否可能,但在某些情况下,这将是一个完美的解决scheme,因为您可以检查用户手表与他的设备配对,而当时不必连接。

下面是一个代码示例,但是这不包括检查配对设备是否可穿戴设备。 这只是一个起点。

下面的代码示例: getbondeddevices()不返回配对的蓝牙设备

 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(); } 

请注意,此代码需要您的清单中的蓝牙权限。

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

如果手持设备仅连接Android手表,以上所有答案都是正确的。 如果手持设备连接到Android Watch,HealthBand,Beacon等多个设备(多可用),那么上面的答案可能无法正常工作。

以下部分将向您展示如何通告可以处理活动请求的设备节点,发现能够满足所请求需求的节点,并将消息发送到这些节点,

广告function

要从可穿戴设备启动手持设备上的活动,请使用MessageApi类发送请求。 由于多个可穿戴设备可以连接到手持设备,所以可穿戴应用需要确定连接的节点能够启动该活动。 在您的掌上应用程序中,广告它运行的节点提供特定的function。

宣传掌上电脑应用程序的function:

  1. 在项目的res / values /目录中创build一个XMLconfiguration文件,并将其命名为wear.xml。
  2. 将名为android_wear_capabilities的资源添加到wear.xml。
  3. 定义设备提供的function。

 <resources> <string-array name="android_wear_capabilities"> <item>android_wear</item> </string-array> </resources> 

检索具有所需function的节点

最初,您可以通过调用CapabilityApi.getCapability()方法来检测有能力的节点。 以下示例显示如何使用android_wearfunction手动检索可达节点的结果。 在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

我正在使用适合我的用例的更简单的方法,检查是否安装了android Wear应用程序:

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

检查配对的设备

您可以检查用户是否有与手表配对的手表,而当时不需要连接手表。 这样做更好,因为手表在检测时不需要连接。

 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(); } 

请注意,此代码需要您的清单中的蓝牙权限。

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