我正在尝试将资产发送到我的Sony SmartWatch3。我按照Google的文档(https://developer.android.com/training/wearables/data-layer/assets.html)进行了操作,但它不起作用。
我的掌上电脑活动代码:
public class MainActivityHandheld extends ActionBarActivity
{
private GoogleApiClient mGoogleApiClient;
private static final String MY_KEY = "com.example.andy.key.mykey";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity_handheld);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendDataToWearable();
}
});
Log.i("ANDY", "mGoogleApiClient before creation -- Handheld");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle connectionHint) {
Log.d("tag", "onConnected: " + connectionHint);
// Now you can use the Data Layer API
}
@Override
public void onConnectionSuspended(int cause) {
Log.d("tag", "onConnectionSuspended: " + cause);
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.d("tag", "onConnectionFailed: " + result);
}
})
// Request access only to the Wearable API
.addApi(Wearable.API)
.build();
Log.i("ANDY", "mGoogleApiClient after creation -- Handheld");
}
@Override
protected void onStart() {
super.onStart();
Log.i("ANDY", "mGoogleApiClient before connect -- Handheld");
mGoogleApiClient.connect();
Log.i("ANDY", "mGoogleApiClient after connect -- Handheld");
}
@Override
protected void onStop() {
Log.i("ANDY", "mGoogleApiClient before disconnect -- Handheld");
mGoogleApiClient.disconnect();
Log.i("ANDY", "mGoogleApiClient after disconnect -- Handheld");
super.onStop();
}
private void sendDataToWearable()
{
try
{
Log.i("ANDY", "Before send -- Handheld");
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
Asset asset = createAssetFromBitmap(bitmap);
PutDataRequest request = PutDataRequest.create("/image");
request.putAsset("profileImage", asset);
Wearable.DataApi.putDataItem(mGoogleApiClient, request);
Log.i("ANDY", "After send -- Handheld");
}
catch (Exception ex)
{
ex.printStackTrace();
Log.i("ANDY", "Exception -- Handheld : " + ex.getStackTrace().toString());
}
}
private static Asset createAssetFromBitmap(Bitmap bitmap) {
final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
return Asset.createFromBytes(byteStream.toByteArray());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main_activity_handheld, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
我的可穿戴活动的代码:
public class MainActivityWear extends Activity implements
DataApi.DataListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private TextView mTextView;
private GoogleApiClient mGoogleApiClient;
private static final String MY_KEY = "com.example.andy.key.mykey";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity_wear);
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);
}
});
Log.i("ANDY", "mGoogleApiClient before creation -- Wearable");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
// Request access only to the Wearable API
.addApi(Wearable.API)
.build();
Log.i("ANDY", "mGoogleApiClient after creation -- Wearable");
}
@Override
protected void onResume() {
super.onResume();
Log.i("ANDY", "mGoogleApiClient after connect (OnResume) -- Wearable");
mGoogleApiClient.connect();
Log.i("ANDY", "mGoogleApiClient after connect (OnResume) -- Wearable");
}
@Override
protected void onPause() {
super.onPause();
Log.i("ANDY", "mGoogleApiClient before removeListener & disconnect -- Wearable");
Wearable.DataApi.removeListener(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
Log.i("ANDY", "mGoogleApiClient after removeListener & disconnect -- Wearable");
}
@Override
public void onConnected(Bundle connectionHint) {
Log.i("ANDY", "mGoogleApiClient before addListener -- Wearable");
Wearable.DataApi.addListener(mGoogleApiClient, this);
Log.i("ANDY", "mGoogleApiClient after addListener -- Wearable");
// Now you can use the Data Layer API
}
@Override
public void onConnectionSuspended(int cause) {
Log.d("tag", "onConnectionSuspended: " + cause);
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.d("tag", "onConnectionFailed: " + result);
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
Log.i("ANDY", "onDataChanged before boucle event -- Wearable");
for (DataEvent event : dataEvents)
{
if (event.getType() == DataEvent.TYPE_CHANGED) {
// DataItem changed
DataItem item = event.getDataItem();
if (item.getUri().getPath().compareTo("/image") == 0)
{
Log.i("ANDY", "onDataChanged before get Asset -- Wearable");
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage");
Bitmap bitmap = loadBitmapFromAsset(profileAsset);
// Do something with the bitmap
Log.i("ANDY", "onDataChanged after get Asset -- Wearable");
try
{
Log.i("ANDY", "onDataChanged before deserialize -- Wearable");
ArrayList<MyObject> myObjectArrayList = (ArrayList<MyObject>) Serializer.deserialize(array);
Log.i("ANDY", "onDataChanged after deserialize -- Wearable");
}
catch (Exception e) {
e.printStackTrace();
Log.i("ANDY", "onDataChanged exception -- Wearable :" + e.getStackTrace().toString());
}
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
// DataItem deleted
}
}
}
public Bitmap loadBitmapFromAsset(Asset asset) {
if (asset == null) {
throw new IllegalArgumentException("Asset must be non-null");
}
ConnectionResult result =
mGoogleApiClient.blockingConnect(100, TimeUnit.MILLISECONDS);
if (!result.isSuccess()) {
return null;
}
// convert asset into a file descriptor and block until it's ready
InputStream assetInputStream = Wearable.DataApi.getFdForAsset(
mGoogleApiClient, asset).await().getInputStream();
mGoogleApiClient.disconnect();
if (assetInputStream == null) {
Log.w(TAG, "Requested an unknown Asset.");
return null;
}
// decode the stream into a bitmap
return BitmapFactory.decodeStream(assetInputStream);
}
}
手持设备代码的执行正常(日志正确显示),但程序没有进入 onDataChanged 的可穿戴方法。但是,当我尝试发送Integer而不是Asset时,它可以正常工作:
PutDataRequest request = PutDataRequest.create("/array");
request.putInt("array", 90);
Wearable.DataApi.putDataItem(mGoogleApiClient, request);
有什么想法吗?我不明白发生了什么。
答案 0 :(得分:2)
这很棘手,但为了调用,数据的内容必须改变。尝试将时间戳添加到DataMap。 E.g。
PutDataMapRequest request = PutDataMapRequest.create("/image");
Asset asset = createAssetFromBitmap(bitmap);
request.putAsset("profileImage", asset);
DataMap dataMap = request.getDataMap();
dataMap.putLong("timestamp", System.currentTimeMillis());
PutDataRequest dataRequest = request.asPutDataRequest();
Wearable.DataApi.putDataItem(mGoogleApiClient, dataRequest);