我正在创建一个扩展推送通知的Android服装应用。当推送通知进入时,我的应用程序从服务器下载大约10张图像,并在手表上显示这些附加图像。这些图像特定于Android Wear应用程序,并且未显示在手持设备上。
如何判断手持设备是否与Android磨损设备配对,以便我可以确定是否需要下载磨损应用所需的其他图像?
谢谢!
答案 0 :(得分:20)
这里列出了2个选项。根据您的使用情况,它们都有效。我想添加第三个选项,但不完整。
NodeApi类有一个检索连接节点的方法。有了这个,你就可以确保用户不仅拥有过去的手表,还有某个时候测试过的手表。他附近有一块手表并且连接起来。
这种方法的缺点是,如果未启用蓝牙或此时手表未连接,您将无法获得任何结果。
方法是:
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();
}
这就是第二种选择的优势。如果你得到一块手表,你要做的第一件事就是在掌上电脑上安装Android Wear应用程序。因此,您可以使用PackageManager
来验证是否已安装此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();
}
不确定这是否可行,但在某些情况下,这将是一个完美的解决方案,因为您可以检查用户是否有一个手表与他的设备配对,而当时不需要连接。
下面是一个代码示例,但是这不包括检查配对设备是否是可穿戴设备。这只是一个起点。
代码示例来自:getbondeddevices() not returning paired bluetooth devices
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"/>
答案 1 :(得分:16)
您需要使用NodeApi
,尤其是NodeApi.getConnectedNodes()
。
例如(来自后台线程 - 否则使用setResultCallback()
而不是await()
):
List<Node> connectedNodes =
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await().getNodes();
如果返回的节点列表包含至少一个元素,则表示已连接Android Wear设备,否则没有。
更新:随着Google Play Services 7.3的发布,添加了对同时连接的多个Android Wear设备的支持。您可以使用CapabilityApi
来请求具有特定功能的节点。
答案 2 :(得分:7)
如果手持设备仅连接Android Watch,则所有答案都是正确的。如果手持设备连接到多个设备(多种设备),如Android Watch,HealthBand,Beacon等,那么上面的答案可能无效。
以下部分介绍如何通告可处理活动请求的设备节点,发现能够满足所请求需求的节点,以及向这些节点发送消息,
广告功能
要从可穿戴设备在手持设备上启动活动,请使用MessageApi类发送请求。由于可以将多个可穿戴设备连接到手持设备,因此可穿戴应用需要确定连接的节点能够启动活动。在掌上电脑应用程序中,宣传其运行的节点提供特定功能。
宣传掌上电脑应用的功能:
<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
答案 3 :(得分:2)
我正在使用一个更简单的方法,适合我的用例,检查是否安装了android wear app:
try {
getPackageManager().getPackageInfo("com.google.android.wearable.app", PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
//android wear app is not installed
}
答案 4 :(得分:0)
您可以检查用户是否有与其设备配对的手表,但此时无需连接。这样做更好,因为在检测时不必连接手表。
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"/>