简短摘要:我正在尝试使用PutDataRequest和GoogleApiClient将Android Wear手表中的数据发送到Android手机。日志似乎表明数据已成功发送,但onDataChanged永远不会触发。我使用的是Android Studio 1.0.2。我没有使用任何模拟器,而是使用我自己的Android Wear手表 - 我已配对并通过手机上的Android Wear设备和Android Wear应用程序启用调试。在手机和Wear的AndroidManifest.xml上,我都包含了com.google.android.gms.version。
在Android手机(Android 4.4.4版本)上,我使用了一个侦听器服务,该服务通过AndroidManifest.xml绑定,并通过手机上的主要活动启动。从日志中,我可以确认在手机上成功创建了服务,但是没有收到任何数据(onDataChanged永远不会触发 - 准确地说)。
<!-- Phone manifest, registers the listener -->
<service android:name=".DataLayerListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
以下是在手机上运行的监听服务:
public class DataLayerListenerService extends WearableListenerService {
private static final String TAG = DataLayerListenerService.class.getName();
private GoogleApiClient mGoogleApiClient;
private static final String WEARABLE_DATA_PATH = "/audio";
@Override
public void onCreate() {
// I can see this fires properly on the Android mobile phone
Logger.d(TAG, "onCreate");
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
// This never fires on the Android mobile phone, even though Wear says data was sent successfully
Logger.d(TAG, "on change");
}
}
在Wear设备上,我有一个主要活动,可以创建一个Google API客户端。我使用UI按钮从音频生成输入(代码未显示),我知道这是因为日志记录正常工作。然后我尝试将这些数据从磨损设备发送到手机。在日志中,我看到&#34;结果可用。状态:状态{statusCode = SUCCESS,resolution = null}&#34; (我使用结果回调来跟踪)。
public class MainActivity extends Activity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = MainActivity.class.getName();
private static final int SPEECH_REQUEST_CODE = 1;
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private TextView mTextView;
private AudioRecord recorder;
private int bufferSize = 0;
private Thread recordingThread = null;
private GoogleApiClient mGoogleApiClient;
private volatile boolean isRecording;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "Creating MainActivity");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
// Connect to the data layer when the Activity starts
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onResume() {
if (null != mGoogleApiClient && !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
super.onResume();
}
@Override
protected void onStop() {
if (null != mGoogleApiClient && mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
super.onStop();
}
// Placeholders for required connection callbacks
@Override
public void onConnectionSuspended(int cause) {
Log.d(TAG, "Connection suspended");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Connection failed");
}
@Override
public void onConnected(Bundle connectionHint) {
Log.d(TAG, "Connected successfully");
}
// This is invoked from the UI, via a helper method not shown. Logs show the method is invoked fine.
private void processRawAudioData() {
byte data[] = new byte[bufferSize];
int read = 0;
while(isRecording) {
read = recorder.read(data, 0, bufferSize);
if(AudioRecord.ERROR_INVALID_OPERATION != read) {
Log.d(TAG, "Successfully read " + data.length + " bytes of audio");
Log.d(TAG, "Initial ten bytes: " + data[0] + data[1] + data[2] + data[3]
+ data[4] + data[5] + data[6] + data[7] + data[8] + data[9] + data[10]);
Asset myAsset = Asset.createFromBytes(data);
PutDataRequest request = PutDataRequest.create("/audio");
// might need to change time each time for other end to see change.
request.putAsset("profileImage", myAsset);
PendingResult<DataApi.DataItemResult> result =
Wearable.DataApi.putDataItem(mGoogleApiClient, request);
result.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
// LOGS SHOW STATUS "MainActivity﹕ result available. Status: Status{statusCode=SUCCESS, resolution=null}"
Log.d(TAG, "result available. Status: " + dataItemResult.getStatus());
}
});
}
}
}
}
答案 0 :(得分:9)
为了WearableListenerService
触发'onDataChanged'
事件,applicationId's
和可穿戴应用中的main app
必须匹配(build.gradle files
)。
另外,您无法发送静态数据,数据必须更改。这意味着PutDataMapRequest对象中的数据必须正在改变。
答案 1 :(得分:0)
在send dataapimap中添加一个键值 map.put(“timestamp”,System.currentmillions())
答案 2 :(得分:0)
您的onReceive是否被调用?
我遇到了类似的问题,其中手持设备发送数据但是监听器服务没有被调用。这是因为app和磨损gradle文件之间的不一致。
我的应用程序有多种口味,我必须将其删除并使其成绩与磨损相同,并且在那之后一切顺利进行
答案 3 :(得分:0)
您是否在侦听器端应用中添加了 Wearable.DataApi.addListener()?
答案 4 :(得分:0)
好的,所以我遇到了同样的问题,我发现从手机发送事件时我没有连接,所以我从未见过它。关键是: onDataChanged()不会触发,除非GoogleApiClient在发送时已连接并正在收听。一旦重新连接,它似乎不会向您发送您错过的事件;当你连接()时,你必须手动轮询错过的DataItems。
至少,这对我来说似乎是一个错误:我希望onDataChanged()可以触发客户端断开连接时发送的任何事件。假设那我错了吗?
无论如何,这是我每次连接时手动轮询我错过的事件的方式:
@Override
public void onConnected(Bundle bundle) {
Wearable.DataApi.addListener(googleApiClient, this);
syncPresets();
}
@Override
public void onConnectionSuspended(int i) {
Wearable.DataApi.removeListener(googleApiClient, this);
}
private void syncPresets() {
// Ok, so the reason is, we're calling Wearable.DataApi.addListener(googleApiClient, this);
// only when we connect.
// thus, we manually poll for the ones we missed...
Wearable.DataApi.getDataItems(googleApiClient, getDataUri(WEARABLE_DATA_PATH))
.setResultCallback(new ResultCallback<DataItemBuffer>() {
@Override
public void onResult(DataItemBuffer dataItems) {
Status status = dataItems.getStatus();
if (status.isSuccess()) {
for (DataItem dataItem : dataItems) {
Log.d(TAG, "Synced image " + dataItem);
if (dataItem != null) {
// do whatever you do with the items here...
onReceivedImage(dataItem);
}
}
} else {
Log.d(TAG, "Failed getting image: (" + status.getStatusCode() + ") " + status.getStatusMessage());
}
dataItems.release();
}
});
}