连接显示为空,磨损未从 DataLayer 接收
Connection showing null, wear not receiving from DataLayer
对于我使用 Wear 的第一个项目,我从简单开始 - 使用 DataLayer 将一个字符串从 Android 发送到 Wear。这实际上是一个更大项目的测试,我需要做的就是有一个同步的字符串。
在运行项目上,Log一直显示字符串发送成功,"onConnected"一直显示null。不用说,手表已连接。我认为连接是问题所在,因为它可以解释为什么没有 happens/runs 磨损。调试:我正在使用通过 USB 连接的 Moto Z Play,以及通过蓝牙调试连接的 Lg G Watch。安装佩戴没有问题。然而,连接始终显示为空。
我有一个 onDataChanged 服务,它在检测到更改时通过 Toast 显示字符串 ("Testing")。这永远不会发生。如上所述,我认为这是一个连接问题,但也可能是使用不当造成的。抱歉,我是一名自学成才的高中生。感谢任何帮助或澄清。
Phone Activity:
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
//Global variables.
private static final int importFileCode = 1;
//Used for Wear DataLayer
private static final String TAG = "MainActivity";
private GoogleApiClient mGoogleApiClient;
private boolean mResolvingError = false;
//Method001: Creates the interfaces, calls necessary methods.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//Used to initiate GoogleAPiClient
initiateAPI();
//Used to test the data layer
sendAccsRequest("Testing");
}
@Override
public void onConnected(Bundle connectionHint) {
Log.d(TAG, "onConnected: " + connectionHint);
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "onConnectionSuspended: " + i);
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed: " + connectionResult);
}
//Initiates the google api client.
public void initiateAPI () {
//GoogleApiClient used for connection w/the phone
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
//Used to send the string with info to wear, hopefully.
public void sendAccsRequest(String allInfo) {
//Creates a request with a unique key
PutDataMapRequest putDataMapRequest = PutDataMapRequest.create("/allInfo");
//Inserts the variables using the keys
putDataMapRequest.getDataMap().putString("strAllInfo", allInfo);
PutDataRequest request = putDataMapRequest.asPutDataRequest();
Wearable.DataApi.putDataItem(mGoogleApiClient, request)
.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
if (!dataItemResult.getStatus().isSuccess()) {
Log.e("sendAccs", "Failed to send accs");
} else {
Log.d("sendAccs", "Successfully sent accs");
}
}
});
}
}
穿Activity:
public class Main extends WearableActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
DataApi.DataListener, MessageApi.MessageListener, CapabilityApi.CapabilityListener {
private GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
//Initiates the google api client
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
// Enables Always-on
setAmbientEnabled();
}
@Override
public void onConnected(Bundle connectionHint) {
Log.d("onConnected(): ","Successfully connected to Google API client");
Wearable.DataApi.addListener(mGoogleApiClient, this);
Wearable.MessageApi.addListener(mGoogleApiClient, this);
Wearable.CapabilityApi.addListener(
mGoogleApiClient, this, Uri.parse("wear://"), CapabilityApi.FILTER_REACHABLE);
}
@Override
public void onConnectionSuspended(int i) {
Log.e("onConnectionSuspended()",": Connection to Google API client was suspended");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e("onConnectionFailed(): ","Failed to connect, with result: " + connectionResult);
}
@Override
public void onDataChanged(DataEventBuffer dataEventBuffer) {
for (DataEvent event : dataEventBuffer) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
String path = event.getDataItem().getUri().getPath();
if (dataChangeService.accPath.equals(path)) {
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
String allInfo = dataMapItem.getDataMap()
.getString("strAllInfo");
//Prints out received string
Log.e("strAllInfo: ", allInfo);
}
} else {
Log.e("Unknown data event type", "Type = " + event.getType());
}
}
}
@Override
public void onMessageReceived(MessageEvent messageEvent) {
}
@Override
public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
}
}
dataChangeService(磨损):
public class dataChangeService extends WearableListenerService {
GoogleApiClient mGoogleApiClient;
public static final String accPath = "/allInfo";
@Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
Log.d("dataChangeService", "Successfully running");
for (DataEvent dataEvent : dataEvents) {
if (dataEvent.getType() == DataEvent.TYPE_CHANGED) {
DataMap dataMap = DataMapItem.fromDataItem(dataEvent.getDataItem()).getDataMap();
String path = dataEvent.getDataItem().getUri().getPath();
if (path.equals("/allInfo")) {
String allInfo = dataMap.getString("strAllInfo");
Toast.makeText(dataChangeService.this, "AllInfo: " + allInfo, Toast.LENGTH_SHORT).show();
}
}
}
}
}
Android 磨损清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="noobyguy.testapp">
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@android:style/Theme.DeviceDefault">
<uses-library
android:name="com.google.android.wearable"
android:required="true" />
<!--
Set to true if your app is Standalone, that is, it does not require the handheld
app to run.
-->
<meta-data
android:name="com.google.android.wearable.standalone"
android:value="true" />
<activity
android:name=".Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<service
android:name=".dataChangeService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name = "come.google.android.gms.wearable.BIND_LISTENER"/>
</intent-filter>
</service>
</application>
</manifest>
感谢您的帮助!不过说真的,我确实最终弄清楚了这个问题。
- 穿其实没用
mGoogleApiClient.connect();
但主要是清单问题,因为 BIND_LISTENER(由 Udacity 建议)需要替换为以下内容;
<service
android:name=".dataChangeService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<data android:scheme="wear" android:host="*" android:pathPrefix="/allInfo"/>
</intent-filter>
对于我使用 Wear 的第一个项目,我从简单开始 - 使用 DataLayer 将一个字符串从 Android 发送到 Wear。这实际上是一个更大项目的测试,我需要做的就是有一个同步的字符串。
在运行项目上,Log一直显示字符串发送成功,"onConnected"一直显示null。不用说,手表已连接。我认为连接是问题所在,因为它可以解释为什么没有 happens/runs 磨损。调试:我正在使用通过 USB 连接的 Moto Z Play,以及通过蓝牙调试连接的 Lg G Watch。安装佩戴没有问题。然而,连接始终显示为空。
我有一个 onDataChanged 服务,它在检测到更改时通过 Toast 显示字符串 ("Testing")。这永远不会发生。如上所述,我认为这是一个连接问题,但也可能是使用不当造成的。抱歉,我是一名自学成才的高中生。感谢任何帮助或澄清。
Phone Activity:
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
//Global variables.
private static final int importFileCode = 1;
//Used for Wear DataLayer
private static final String TAG = "MainActivity";
private GoogleApiClient mGoogleApiClient;
private boolean mResolvingError = false;
//Method001: Creates the interfaces, calls necessary methods.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//Used to initiate GoogleAPiClient
initiateAPI();
//Used to test the data layer
sendAccsRequest("Testing");
}
@Override
public void onConnected(Bundle connectionHint) {
Log.d(TAG, "onConnected: " + connectionHint);
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "onConnectionSuspended: " + i);
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed: " + connectionResult);
}
//Initiates the google api client.
public void initiateAPI () {
//GoogleApiClient used for connection w/the phone
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
//Used to send the string with info to wear, hopefully.
public void sendAccsRequest(String allInfo) {
//Creates a request with a unique key
PutDataMapRequest putDataMapRequest = PutDataMapRequest.create("/allInfo");
//Inserts the variables using the keys
putDataMapRequest.getDataMap().putString("strAllInfo", allInfo);
PutDataRequest request = putDataMapRequest.asPutDataRequest();
Wearable.DataApi.putDataItem(mGoogleApiClient, request)
.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
if (!dataItemResult.getStatus().isSuccess()) {
Log.e("sendAccs", "Failed to send accs");
} else {
Log.d("sendAccs", "Successfully sent accs");
}
}
});
}
}
穿Activity:
public class Main extends WearableActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
DataApi.DataListener, MessageApi.MessageListener, CapabilityApi.CapabilityListener {
private GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
//Initiates the google api client
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
// Enables Always-on
setAmbientEnabled();
}
@Override
public void onConnected(Bundle connectionHint) {
Log.d("onConnected(): ","Successfully connected to Google API client");
Wearable.DataApi.addListener(mGoogleApiClient, this);
Wearable.MessageApi.addListener(mGoogleApiClient, this);
Wearable.CapabilityApi.addListener(
mGoogleApiClient, this, Uri.parse("wear://"), CapabilityApi.FILTER_REACHABLE);
}
@Override
public void onConnectionSuspended(int i) {
Log.e("onConnectionSuspended()",": Connection to Google API client was suspended");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e("onConnectionFailed(): ","Failed to connect, with result: " + connectionResult);
}
@Override
public void onDataChanged(DataEventBuffer dataEventBuffer) {
for (DataEvent event : dataEventBuffer) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
String path = event.getDataItem().getUri().getPath();
if (dataChangeService.accPath.equals(path)) {
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
String allInfo = dataMapItem.getDataMap()
.getString("strAllInfo");
//Prints out received string
Log.e("strAllInfo: ", allInfo);
}
} else {
Log.e("Unknown data event type", "Type = " + event.getType());
}
}
}
@Override
public void onMessageReceived(MessageEvent messageEvent) {
}
@Override
public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
}
}
dataChangeService(磨损):
public class dataChangeService extends WearableListenerService {
GoogleApiClient mGoogleApiClient;
public static final String accPath = "/allInfo";
@Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
Log.d("dataChangeService", "Successfully running");
for (DataEvent dataEvent : dataEvents) {
if (dataEvent.getType() == DataEvent.TYPE_CHANGED) {
DataMap dataMap = DataMapItem.fromDataItem(dataEvent.getDataItem()).getDataMap();
String path = dataEvent.getDataItem().getUri().getPath();
if (path.equals("/allInfo")) {
String allInfo = dataMap.getString("strAllInfo");
Toast.makeText(dataChangeService.this, "AllInfo: " + allInfo, Toast.LENGTH_SHORT).show();
}
}
}
}
}
Android 磨损清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="noobyguy.testapp">
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@android:style/Theme.DeviceDefault">
<uses-library
android:name="com.google.android.wearable"
android:required="true" />
<!--
Set to true if your app is Standalone, that is, it does not require the handheld
app to run.
-->
<meta-data
android:name="com.google.android.wearable.standalone"
android:value="true" />
<activity
android:name=".Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<service
android:name=".dataChangeService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name = "come.google.android.gms.wearable.BIND_LISTENER"/>
</intent-filter>
</service>
</application>
</manifest>
感谢您的帮助!不过说真的,我确实最终弄清楚了这个问题。
- 穿其实没用
mGoogleApiClient.connect();
但主要是清单问题,因为 BIND_LISTENER(由 Udacity 建议)需要替换为以下内容;
<service
android:name=".dataChangeService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<data android:scheme="wear" android:host="*" android:pathPrefix="/allInfo"/>
</intent-filter>