将字符串从手表发送到 phone
Sending String from watch to phone
我正在尝试使用以下代码将字符串从可穿戴设备发送到移动设备。
此实现基于 https://github.com/twotoasters/Wear-MessageApiDemo/
如果连接到我增加的设备的时间延迟有问题
CONNECTION_TIME_OUT_MS
从 100 到 2000(毫秒)。
我在移动清单中添加:
<service
android:name=".ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
</intent-filter>
</service>
而不是
<service
android:name=".ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
因为 com.google.android.gms.wearable.BIND_LISTENER
已弃用
代码可以编译,但 phone 没有收到消息。
方法
private void showToast(String message) {
Log.d(TAG, "received message : " + message);
}
收到消息时应在 listenerService
内触发。
问题是从未收到消息。我是否正确执行了消息 api?
API 版本:23
来源:
Mobile component
开始监听服务:
------------------------------------ MainActivity.onCreate ----- ----------
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ListenerService();
}
定义侦听器服务以侦听消息
-------------------------------- ListenerService -------- --------
import android.util.Log;
import android.widget.TextView;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.WearableListenerService;
public class ListenerService extends WearableListenerService {
private static final String TAG = "ListenerService";
TextView mTextView;
@Override
public void onMessageReceived(MessageEvent messageEvent) {
MainActivity.mTextView.setText("got message");
showToast(messageEvent.getPath());
}
private void showToast(String message) {
Log.d(TAG, "received message : " + message);
}
}
在清单中定义服务
------------------------------------ AndroidManifest.xml ----- ----------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.runner">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.BODY_SENSORS"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.GPS_PROVIDER" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
</intent-filter>
</service>
</application>
</manifest>
Wear component
主要活动:
package common;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.wearable.activity.WearableActivity;
import android.support.wearable.view.BoxInsetLayout;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
public class MainActivity extends WearableActivity {
private static final long CONNECTION_TIME_OUT_MS = 2000;
private static final String MESSAGE = "Hello Wear!";
private GoogleApiClient client;
private String nodeId;
private static final String TAG = "MainActivity";
private BoxInsetLayout mContainerView;
/**
* Initializes the GoogleApiClient and gets the Node ID of the connected device.
*/
private void initApi() {
client = getGoogleApiClient(this);
retrieveDeviceNode();
}
/**
* Returns a GoogleApiClient that can access the Wear API.
* @param context
* @return A GoogleApiClient that can make calls to the Wear API
*/
private GoogleApiClient getGoogleApiClient(Context context) {
return new GoogleApiClient.Builder(context)
.addApi(Wearable.API)
.build();
}
/**
* Connects to the GoogleApiClient and retrieves the connected device's Node ID. If there are
* multiple connected devices, the first Node ID is returned.
*/
private void retrieveDeviceNode() {
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) {
Log.d(TAG, "nodeId "+nodeId);
nodeId = nodes.get(0).getId();
}
client.disconnect();
}
}).start();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initApi();
sendToast();
}
/**
* Sends a message to the connected mobile device, telling it to show a Toast.
*/
private void sendToast() {
if (nodeId != null) {
new Thread(new Runnable() {
@Override
public void run() {
client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
Wearable.MessageApi.sendMessage(client, nodeId, MESSAGE, null);
client.disconnect();
}
}).start();
}
}
}
更新:
这里是 class 添加到移动模块以侦听收到的消息:
package com.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MessageListener extends BroadcastReceiver {
private static final String TAG = "MessageListener";
@Override
public void onReceive(Context context, Intent intent) {
String str = intent.getAction();
Log.i(TAG, "onReceive triggered : "+str);
}
}
AndroidManifest.xml 中 MessageListener 的配置:
<receiver android:name="com.receivers.MessageListener">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
</intent-filter>
</receiver>
我试过在第 String str = intent.getAction();
行设置断点,但 onReceive
方法似乎没有被调用。
在 wear 模块中,方法 onNodeFound()
似乎确实在调用此行 Wearable.MessageApi.sendMessage(googleApiClient, nodeId, MESSAGE_PATH, "Hello Wear!".getBytes(Charset.forName("UTF-8")));
时正确发送消息。我是否正确设置了 MessageListener
?
更新 2:
接收者活动:
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
public class ReceiverActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-event-name"));
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("EXTRA_MESSAGE");
Log.d("receiver", "Got message: " + message);
}
};
@Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
}
在 ListenerService
中,正在触发方法 onMessageReceived
并在此处尝试广播消息:
@Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
Log.d("tester", "received a message from wear: " + new String(messageEvent.getData()));
final String message = new String(messageEvent.getData());
final Intent messageIntent = new Intent();
messageIntent.putExtra("EXTRA_MESSAGE", message); // define your extra
LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);
}
在 AndroidManifest.xml 中启动 activity :
<activity android:name=".ReceiverActivity">
</activity>
但是ReceiverActivity
似乎没有收到消息,ReceiverActivity
设置正确吗?
更新 3:
根据评论开始 activity 我添加:
Intent intent = new Intent(this, ReceiverActivity.class);
startActivity(intent);
到MainActivity.onCreate
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, ReceiverActivity.class);
startActivity(intent);
......
new ListenerService();
这不是您启动任何服务的方式。这只是创建一个 Servie 实例,它什么都不做,将在 onCreate() 退出后被收集。
当您收到消息时,系统将启动此服务。您只需要在清单中定义它。此外,您可能需要为收到的消息定义路径,例如
<service android:name=".ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:scheme="wear" android:host="*" android:pathPrefix="/message"/>
</intent-filter>
</service>
这就是设置服务所需的全部内容。此外,请记住,为了接收消息,您的 Wear 应用程序和手持应用程序应具有相同的包名称 (applicationId)。仔细检查您没有不匹配的 applicationId 口味或 buildTypes。因此,如果您在 build.gradle 中有 applicationId,请确保它们与 wear 和 handhelp 应用程序项目匹配
defaultConfig {
applicationId "com.runner"
关于更新UI:
@Override
public void onMessageReceived(MessageEvent messageEvent) {
MainActivity.mTextView.setText("got message");
}
这不是与 Activity 交互服务的方式。
当服务 运行 时,Activity 可能会或可能不会 运行ning。仅从 Activity 更新 Activtity UI。如果您需要向用户显示消息,请使用 BroadcastReceiver
或 Observer
.
请注意,onMessageReceived()
不会在 Main UI
线程上 运行,因此在显示 Toast
之前使用 Handler
。
因此,如果您想将此服务的消息传递给 Activity,其中一种方法是
@Override
public void onMessageReceived(MessageEvent messageEvent) {
final byte[] data = messsageEvent.getData();
if (data != null) {
final String message = new String(data, Charset.forName("UTF-8"));
final Intent messageIntent = new Intent("custom-event-name");
intent.putExtra(EXTRA_MESSAGE, message); // define your extra
LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);
// Register BroadcastReiver from LocalBroadcastManager in your Activity to receive this broadcast
}
}
或者如果你想开始 Activity 如果不是 运行ning,你需要一个不同的方法:
<activity
android:name=".ReceiverActivity"
android:launchMode="singleTop"/>
服务:
@Override
public void onMessageReceived(MessageEvent messageEvent) {
final byte[] data = messsageEvent.getData();
if (data != null) {
final String message = new String(data, Charset.forName("UTF-8"));
final Intent activityIntent = new Intent(this, ReceiverActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("EXTRA_MESSAGE", message);
startActivity(intent);
}
}
// In this case, in Activity, if it's explicitly started, you don't need a BroadcastReceiver
// Instead, you can get the extra from Activity Intent
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handleIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
String message = intent.getStringExtra("EXTRA_MESSAGE");
}
在 Wear 组件中
initApi();
sendToast();
您使用可能 运行 同时使用的不同线程,因此当 sendToast() 运行 时,您实际上可能还没有解析 nodeId。
我建议做的是将 onCreate()
中的 GoogleApiClient
与监听器连接起来。客户端连接后,开始获取节点。您不需要生成自己的线程,如果您使用 setResultCallback()
而不是 await()
,API 是异步的
编辑 14/02/2018:正如 Rajesh 在评论中提到的,Wearable.API 已弃用。下面的答案指的是旧 API,这在撰写本文时是新的。我将按原样保留旧答案,但我没有时间研究如何使用新的 APIs.
private static final String MESSAGE_PATH = "/message";
private GoogleApiClient googleApiClient;
@Override
protected void onCerate(Bundle state) {
super.onCreate(state);
googleApiClient = getGoogleApiClient(this);
googleApiClient.connect();
}
@Override
protected void onDestroy() {
super.onDestroy();
googleApiClient.disconnect();
}
private GoogleApiClient getGoogleApiClient(Context context) {
return new GoogleApiClient.Builder(context)
.addApi(Wearable.API)
.addConnectionCallbacks(mConnectionCallbacks)
.build();
}
private void findNodes() {
Wearable.NodeApi.getConnectedNodes(googleApiClient).setResultCallback(
new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(
@NonNull final NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
List<Node> nodes = result.getNodes();
if (nodes != null && !nodes.isEmpty()) {
nodeId = nodes.get(0).getId();
Log.d(TAG, "nodeId "+ nodeId);
onNodeFound();
}
}
});
}
private void onNodeFound() {
if (nodeId != null) {
// Now you have your node, send a message, make sure the path starts like the path in manifest
// What you thought is a message is actually a path, and the actual message is the byte array.
// You may concat your message in path though, but keep in mind you will have to parse the string then
Wearable.MessageApi.sendMessage(client, nodeId, MESSAGE_PATH, "Hello Wear!".getBytes(Charset.forName("UTF-8")));
}
}
private final GoogleApiClient.ConnectionCallbacks mConnectionCallbacks
= new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(@Nullable final Bundle bundle) {
findNodes();
}
@Override
public void onConnectionSuspended(final int i) {
}
};
我正在尝试使用以下代码将字符串从可穿戴设备发送到移动设备。 此实现基于 https://github.com/twotoasters/Wear-MessageApiDemo/
如果连接到我增加的设备的时间延迟有问题
CONNECTION_TIME_OUT_MS
从 100 到 2000(毫秒)。
我在移动清单中添加:
<service
android:name=".ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
</intent-filter>
</service>
而不是
<service
android:name=".ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
因为 com.google.android.gms.wearable.BIND_LISTENER
已弃用
代码可以编译,但 phone 没有收到消息。
方法
private void showToast(String message) {
Log.d(TAG, "received message : " + message);
}
收到消息时应在 listenerService
内触发。
问题是从未收到消息。我是否正确执行了消息 api?
API 版本:23
来源:
Mobile component
开始监听服务:
------------------------------------ MainActivity.onCreate ----- ----------
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ListenerService();
}
定义侦听器服务以侦听消息
-------------------------------- ListenerService -------- --------
import android.util.Log;
import android.widget.TextView;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.WearableListenerService;
public class ListenerService extends WearableListenerService {
private static final String TAG = "ListenerService";
TextView mTextView;
@Override
public void onMessageReceived(MessageEvent messageEvent) {
MainActivity.mTextView.setText("got message");
showToast(messageEvent.getPath());
}
private void showToast(String message) {
Log.d(TAG, "received message : " + message);
}
}
在清单中定义服务
------------------------------------ AndroidManifest.xml ----- ----------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.runner">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.BODY_SENSORS"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.GPS_PROVIDER" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
</intent-filter>
</service>
</application>
</manifest>
Wear component
主要活动:
package common;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.wearable.activity.WearableActivity;
import android.support.wearable.view.BoxInsetLayout;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
public class MainActivity extends WearableActivity {
private static final long CONNECTION_TIME_OUT_MS = 2000;
private static final String MESSAGE = "Hello Wear!";
private GoogleApiClient client;
private String nodeId;
private static final String TAG = "MainActivity";
private BoxInsetLayout mContainerView;
/**
* Initializes the GoogleApiClient and gets the Node ID of the connected device.
*/
private void initApi() {
client = getGoogleApiClient(this);
retrieveDeviceNode();
}
/**
* Returns a GoogleApiClient that can access the Wear API.
* @param context
* @return A GoogleApiClient that can make calls to the Wear API
*/
private GoogleApiClient getGoogleApiClient(Context context) {
return new GoogleApiClient.Builder(context)
.addApi(Wearable.API)
.build();
}
/**
* Connects to the GoogleApiClient and retrieves the connected device's Node ID. If there are
* multiple connected devices, the first Node ID is returned.
*/
private void retrieveDeviceNode() {
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) {
Log.d(TAG, "nodeId "+nodeId);
nodeId = nodes.get(0).getId();
}
client.disconnect();
}
}).start();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initApi();
sendToast();
}
/**
* Sends a message to the connected mobile device, telling it to show a Toast.
*/
private void sendToast() {
if (nodeId != null) {
new Thread(new Runnable() {
@Override
public void run() {
client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
Wearable.MessageApi.sendMessage(client, nodeId, MESSAGE, null);
client.disconnect();
}
}).start();
}
}
}
更新:
这里是 class 添加到移动模块以侦听收到的消息:
package com.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MessageListener extends BroadcastReceiver {
private static final String TAG = "MessageListener";
@Override
public void onReceive(Context context, Intent intent) {
String str = intent.getAction();
Log.i(TAG, "onReceive triggered : "+str);
}
}
AndroidManifest.xml 中 MessageListener 的配置:
<receiver android:name="com.receivers.MessageListener">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
</intent-filter>
</receiver>
我试过在第 String str = intent.getAction();
行设置断点,但 onReceive
方法似乎没有被调用。
在 wear 模块中,方法 onNodeFound()
似乎确实在调用此行 Wearable.MessageApi.sendMessage(googleApiClient, nodeId, MESSAGE_PATH, "Hello Wear!".getBytes(Charset.forName("UTF-8")));
时正确发送消息。我是否正确设置了 MessageListener
?
更新 2:
接收者活动:
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
public class ReceiverActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-event-name"));
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("EXTRA_MESSAGE");
Log.d("receiver", "Got message: " + message);
}
};
@Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
}
在 ListenerService
中,正在触发方法 onMessageReceived
并在此处尝试广播消息:
@Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
Log.d("tester", "received a message from wear: " + new String(messageEvent.getData()));
final String message = new String(messageEvent.getData());
final Intent messageIntent = new Intent();
messageIntent.putExtra("EXTRA_MESSAGE", message); // define your extra
LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);
}
在 AndroidManifest.xml 中启动 activity :
<activity android:name=".ReceiverActivity">
</activity>
但是ReceiverActivity
似乎没有收到消息,ReceiverActivity
设置正确吗?
更新 3:
根据评论开始 activity 我添加:
Intent intent = new Intent(this, ReceiverActivity.class);
startActivity(intent);
到MainActivity.onCreate
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, ReceiverActivity.class);
startActivity(intent);
......
new ListenerService();
这不是您启动任何服务的方式。这只是创建一个 Servie 实例,它什么都不做,将在 onCreate() 退出后被收集。
当您收到消息时,系统将启动此服务。您只需要在清单中定义它。此外,您可能需要为收到的消息定义路径,例如
<service android:name=".ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:scheme="wear" android:host="*" android:pathPrefix="/message"/>
</intent-filter>
</service>
这就是设置服务所需的全部内容。此外,请记住,为了接收消息,您的 Wear 应用程序和手持应用程序应具有相同的包名称 (applicationId)。仔细检查您没有不匹配的 applicationId 口味或 buildTypes。因此,如果您在 build.gradle 中有 applicationId,请确保它们与 wear 和 handhelp 应用程序项目匹配
defaultConfig {
applicationId "com.runner"
关于更新UI:
@Override
public void onMessageReceived(MessageEvent messageEvent) {
MainActivity.mTextView.setText("got message");
}
这不是与 Activity 交互服务的方式。
当服务 运行 时,Activity 可能会或可能不会 运行ning。仅从 Activity 更新 Activtity UI。如果您需要向用户显示消息,请使用 BroadcastReceiver
或 Observer
.
请注意,onMessageReceived()
不会在 Main UI
线程上 运行,因此在显示 Toast
之前使用 Handler
。
因此,如果您想将此服务的消息传递给 Activity,其中一种方法是
@Override
public void onMessageReceived(MessageEvent messageEvent) {
final byte[] data = messsageEvent.getData();
if (data != null) {
final String message = new String(data, Charset.forName("UTF-8"));
final Intent messageIntent = new Intent("custom-event-name");
intent.putExtra(EXTRA_MESSAGE, message); // define your extra
LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);
// Register BroadcastReiver from LocalBroadcastManager in your Activity to receive this broadcast
}
}
或者如果你想开始 Activity 如果不是 运行ning,你需要一个不同的方法:
<activity
android:name=".ReceiverActivity"
android:launchMode="singleTop"/>
服务:
@Override
public void onMessageReceived(MessageEvent messageEvent) {
final byte[] data = messsageEvent.getData();
if (data != null) {
final String message = new String(data, Charset.forName("UTF-8"));
final Intent activityIntent = new Intent(this, ReceiverActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("EXTRA_MESSAGE", message);
startActivity(intent);
}
}
// In this case, in Activity, if it's explicitly started, you don't need a BroadcastReceiver
// Instead, you can get the extra from Activity Intent
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handleIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
String message = intent.getStringExtra("EXTRA_MESSAGE");
}
在 Wear 组件中
initApi();
sendToast();
您使用可能 运行 同时使用的不同线程,因此当 sendToast() 运行 时,您实际上可能还没有解析 nodeId。
我建议做的是将 onCreate()
中的 GoogleApiClient
与监听器连接起来。客户端连接后,开始获取节点。您不需要生成自己的线程,如果您使用 setResultCallback()
而不是 await()
编辑 14/02/2018:正如 Rajesh 在评论中提到的,Wearable.API 已弃用。下面的答案指的是旧 API,这在撰写本文时是新的。我将按原样保留旧答案,但我没有时间研究如何使用新的 APIs.
private static final String MESSAGE_PATH = "/message";
private GoogleApiClient googleApiClient;
@Override
protected void onCerate(Bundle state) {
super.onCreate(state);
googleApiClient = getGoogleApiClient(this);
googleApiClient.connect();
}
@Override
protected void onDestroy() {
super.onDestroy();
googleApiClient.disconnect();
}
private GoogleApiClient getGoogleApiClient(Context context) {
return new GoogleApiClient.Builder(context)
.addApi(Wearable.API)
.addConnectionCallbacks(mConnectionCallbacks)
.build();
}
private void findNodes() {
Wearable.NodeApi.getConnectedNodes(googleApiClient).setResultCallback(
new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(
@NonNull final NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
List<Node> nodes = result.getNodes();
if (nodes != null && !nodes.isEmpty()) {
nodeId = nodes.get(0).getId();
Log.d(TAG, "nodeId "+ nodeId);
onNodeFound();
}
}
});
}
private void onNodeFound() {
if (nodeId != null) {
// Now you have your node, send a message, make sure the path starts like the path in manifest
// What you thought is a message is actually a path, and the actual message is the byte array.
// You may concat your message in path though, but keep in mind you will have to parse the string then
Wearable.MessageApi.sendMessage(client, nodeId, MESSAGE_PATH, "Hello Wear!".getBytes(Charset.forName("UTF-8")));
}
}
private final GoogleApiClient.ConnectionCallbacks mConnectionCallbacks
= new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(@Nullable final Bundle bundle) {
findNodes();
}
@Override
public void onConnectionSuspended(final int i) {
}
};