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

时间:2014-07-22 00:46:37

标签: android wear-os

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

如何判断手持设备是否与Android磨损设备配对,以便我可以确定是否需要下载磨损应用所需的其他图像?

谢谢!

5 个答案:

答案 0 :(得分:20)

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

选项1:使用NodeApi

查找连接的节点

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

选项2:检查Android Wear应用

这就是第二种选择的优势。如果你得到一块手表,你要做的第一件事就是在掌上电脑上安装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();
}

选项3:检查配对设备

不确定这是否可行,但在某些情况下,这将是一个完美的解决方案,因为您可以检查用户是否有一个手表与他的设备配对,而当时不需要连接。

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

代码示例来自: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类发送请求。由于可以将多个可穿戴设备连接到手持设备,因此可穿戴应用需要确定连接的节点能够启动活动。在掌上电脑应用程序中,宣传其运行的节点提供特定功能。

宣传掌上电脑应用的功能:

  1. 在项目的res / values /目录中创建XML配置文件,并将其命名为wear.xml。
  2. 将名为android_wear_capabilities的资源添加到wear.xml。
  3. 定义设备提供的功能。
  4. <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"/>