簡體   English   中英

如何檢測安卓設備是否與安卓手表配對

[英]How to detect if android device is paired with android wear watch

我正在創建一個擴展推送通知的 android wear 應用程序。 當推送通知進來時,我的應用程序會從服務器下載大約 10 張圖像,並在手表上顯示這些額外的圖像。 這些圖像特定於 android wear 應用程序,不會顯示在手持設備上。

如何判斷手持設備是否與安卓穿戴設備配對,以便確定是否需要下載穿戴應用所需的附加圖像?

謝謝!

這里列出了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()不返回配對的藍牙設備

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"/>

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

例如(從后台線程 - 否則使用setResultCallback()而不是await() ):

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

如果返回的節點列表包含至少一個元素,則有一個連接的Android Wear設備,否則沒有。


更新:隨着Google Play Services 7.3的發布,增加了對同時連接的多個Android Wear設備的支持。 您可以使用CapabilityApi來請求具有特定功能的節點。

如果手持設備僅連接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

我正在使用一個更簡單的方法,適合我的用例,檢查是否安裝了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
    }

檢查配對設備

您可以檢查用戶是否有與其設備配對的手表,但此時無需連接。 這樣做更好,因為手表不需要在檢測時連接。

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"/>

我項目中的 Kotlin 代碼:

private val clientDataModel by lazy { ClientDataModel.getClientModelObject(this) }

private fun checkWearableStatus() {
    lifecycleScope.launch {
        try {

            val nodes: List<Node> = nodeClient.connectedNodes.await()
            if (nodes.count() <= 0) {
                // No watch is connected
                Log.d(TAG, "no wear devices was found )-: ")
            }
            else if(nodes.filter{ it.isNearby }.count() == 0)
            {
                Log.d(TAG, "there are paired devices but they are not near by or not connected...")
            }
            else {
                // Display connected devices
                for (n in nodes) {
                    Log.d(TAG, "Wear devices: " + n.displayName)
                }
            }
        } catch (ex: Exception) {
            Log.d(TAG, "Error detecting wearable devices: ${ex.message.toString()}")
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM