无法从磨损数据层获取数据
Not able to fetch data from Wear Data layer
我正在尝试将列表从手持设备同步到可穿戴设备。在 phone 端,我有一个列表视图,您可以向其中添加项目,而在磨损端,我只显示相同的列表。我将项目添加到 /card/id
路径并在 /counter
上添加数组大小。当我将项目添加到 phone 端的列表时,OnDataChanged 方法确实被调用,但是当我尝试读取 wearside 上的项目时,它不起作用。当我试图获取连接的节点时,它会给出空指针异常,因此我无法读取数据。这是代码和日志快照:
错误
04-15 12:41:38.075: E/AndroidRuntime(13791): Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.os.Looper com.google.android.gms.common.api.GoogleApiClient.getLooper()' on a null object reference
磨损面:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDefaultCircleRadius = getResources().getDimension(R.dimen.default_settings_circle_radius);
mSelectedCircleRadius = getResources().getDimension(R.dimen.selected_settings_circle_radius);
cards = new ArrayList<GiftCard>();
new LoadCards().execute();
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.count_text);
mListView = (WearableListView) stub.findViewById(R.id.card_list_view);
}
});
mHandler = new Handler();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
// DataItem changed
DataItem item = event.getDataItem();
if (item.getUri().getPath().compareTo(COUNT_PATH) == 0) {
DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
final String counter = dataMap.getString(CardUtil.CARD_COUNT);
new LoadCards().execute();
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(c,"Card count: "+ counter,Toast.LENGTH_LONG).show();
//mTextView.setText("COUNTER FROM DATACHANGE METHOD: " + counter);
}
});
}
else if(item.getUri().getPath().compareTo(CARD_PATH) == 0){
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
// DataItem deleted
}
}
}
public GiftCard loadCardData(int id){
//Uri uri = getIntent().getData().buildUpon().encodedPath("/card").appendPath(String.valueOf(id)).build();
Uri uri = getUriForDataItem("/counter");
Log.d("URI", uri.getPath());
DataApi.DataItemResult result = Wearable.DataApi.getDataItem(mGoogleApiClient,uri).await();
DataMapItem item = DataMapItem.fromDataItem(result.getDataItem());
Asset cardImageAsset = item.getDataMap().getAsset(CardUtil.CARD_IMAGE);
//Asset barcodeImageAsset = item.getDataMap().getAsset(CardUtil.BARCODE_IMAGE);
String card_type = item.getDataMap().getString(CardUtil.CARD_TYPE);
Bitmap cardImage = BitmapFactory.decodeStream(Wearable.DataApi.getFdForAsset(mGoogleApiClient, cardImageAsset).await().getInputStream());
// Bitmap barcodeImage = BitmapFactory.decodeStream(Wearable.DataApi.getFdForAsset(mGoogleApiClient,barcodeImageAsset).await().getInputStream());
GiftCard card = new GiftCard();
card.setCardImage(cardImage);
card.setCardName(card_type);
card.setCardID(id);
return card;
}
public class LoadCards extends AsyncTask<Void, Void, Boolean> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(Void... arg0) {
// Uri uri = getIntent().getData().buildUpon().encodedPath("/counter").build();
Uri uri = getUriForDataItem("/counter");
Toast.makeText(c,uri.toString(),Toast.LENGTH_LONG).show();
DataApi.DataItemResult result = Wearable.DataApi.getDataItem(mGoogleApiClient,uri).await();
DataMapItem item = DataMapItem.fromDataItem(result.getDataItem());
int card_count = Integer.parseInt(item.getDataMap().getString(CardUtil.CARD_COUNT));
// int card_count = Integer.parseInt(loadCardCounter());
if(card_count <= 0){
Toast.makeText(c,"No cards available to show!",Toast.LENGTH_LONG).show();
} else {
for (int i = 1; i <= card_count; i++) {
GiftCard c = loadCardData(i);
cards.add(c);
}
}
return null;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
//update the card list
mAdapter = new CardListAdapter(c,cards);
mListView.setAdapter(mAdapter);
// mListView.setClickListener();
}
}
private Uri getUriForDataItem(String path) {
String nodeId = getNodeId();
return new Uri.Builder().scheme(PutDataRequest.WEAR_URI_SCHEME).authority(nodeId).path(path).build();
}
private String getNodeId() {
NodeApi.GetConnectedNodesResult nodesResult = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
List<Node> nodes = nodesResult.getNodes();
if (nodes.size() > 0) {
return nodes.get(0).getId();
} else {
Toast.makeText(c,"NO NODES AVAILABLE",Toast.LENGTH_LONG).show();
}
return null;
}}
从堆栈跟踪中可以明显看出,您正在尝试从没有 Looper 的线程中使用 Wearable DataAPI - 我相信采用 doInBackground()
方法。这就是它崩溃的原因。
将此代码直接移动到 onDataChanged()
方法中,应该可以解决问题。
我正在尝试将列表从手持设备同步到可穿戴设备。在 phone 端,我有一个列表视图,您可以向其中添加项目,而在磨损端,我只显示相同的列表。我将项目添加到 /card/id
路径并在 /counter
上添加数组大小。当我将项目添加到 phone 端的列表时,OnDataChanged 方法确实被调用,但是当我尝试读取 wearside 上的项目时,它不起作用。当我试图获取连接的节点时,它会给出空指针异常,因此我无法读取数据。这是代码和日志快照:
错误
04-15 12:41:38.075: E/AndroidRuntime(13791): Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.os.Looper com.google.android.gms.common.api.GoogleApiClient.getLooper()' on a null object reference
磨损面:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDefaultCircleRadius = getResources().getDimension(R.dimen.default_settings_circle_radius);
mSelectedCircleRadius = getResources().getDimension(R.dimen.selected_settings_circle_radius);
cards = new ArrayList<GiftCard>();
new LoadCards().execute();
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.count_text);
mListView = (WearableListView) stub.findViewById(R.id.card_list_view);
}
});
mHandler = new Handler();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
// DataItem changed
DataItem item = event.getDataItem();
if (item.getUri().getPath().compareTo(COUNT_PATH) == 0) {
DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
final String counter = dataMap.getString(CardUtil.CARD_COUNT);
new LoadCards().execute();
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(c,"Card count: "+ counter,Toast.LENGTH_LONG).show();
//mTextView.setText("COUNTER FROM DATACHANGE METHOD: " + counter);
}
});
}
else if(item.getUri().getPath().compareTo(CARD_PATH) == 0){
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
// DataItem deleted
}
}
}
public GiftCard loadCardData(int id){
//Uri uri = getIntent().getData().buildUpon().encodedPath("/card").appendPath(String.valueOf(id)).build();
Uri uri = getUriForDataItem("/counter");
Log.d("URI", uri.getPath());
DataApi.DataItemResult result = Wearable.DataApi.getDataItem(mGoogleApiClient,uri).await();
DataMapItem item = DataMapItem.fromDataItem(result.getDataItem());
Asset cardImageAsset = item.getDataMap().getAsset(CardUtil.CARD_IMAGE);
//Asset barcodeImageAsset = item.getDataMap().getAsset(CardUtil.BARCODE_IMAGE);
String card_type = item.getDataMap().getString(CardUtil.CARD_TYPE);
Bitmap cardImage = BitmapFactory.decodeStream(Wearable.DataApi.getFdForAsset(mGoogleApiClient, cardImageAsset).await().getInputStream());
// Bitmap barcodeImage = BitmapFactory.decodeStream(Wearable.DataApi.getFdForAsset(mGoogleApiClient,barcodeImageAsset).await().getInputStream());
GiftCard card = new GiftCard();
card.setCardImage(cardImage);
card.setCardName(card_type);
card.setCardID(id);
return card;
}
public class LoadCards extends AsyncTask<Void, Void, Boolean> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(Void... arg0) {
// Uri uri = getIntent().getData().buildUpon().encodedPath("/counter").build();
Uri uri = getUriForDataItem("/counter");
Toast.makeText(c,uri.toString(),Toast.LENGTH_LONG).show();
DataApi.DataItemResult result = Wearable.DataApi.getDataItem(mGoogleApiClient,uri).await();
DataMapItem item = DataMapItem.fromDataItem(result.getDataItem());
int card_count = Integer.parseInt(item.getDataMap().getString(CardUtil.CARD_COUNT));
// int card_count = Integer.parseInt(loadCardCounter());
if(card_count <= 0){
Toast.makeText(c,"No cards available to show!",Toast.LENGTH_LONG).show();
} else {
for (int i = 1; i <= card_count; i++) {
GiftCard c = loadCardData(i);
cards.add(c);
}
}
return null;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
//update the card list
mAdapter = new CardListAdapter(c,cards);
mListView.setAdapter(mAdapter);
// mListView.setClickListener();
}
}
private Uri getUriForDataItem(String path) {
String nodeId = getNodeId();
return new Uri.Builder().scheme(PutDataRequest.WEAR_URI_SCHEME).authority(nodeId).path(path).build();
}
private String getNodeId() {
NodeApi.GetConnectedNodesResult nodesResult = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
List<Node> nodes = nodesResult.getNodes();
if (nodes.size() > 0) {
return nodes.get(0).getId();
} else {
Toast.makeText(c,"NO NODES AVAILABLE",Toast.LENGTH_LONG).show();
}
return null;
}}
从堆栈跟踪中可以明显看出,您正在尝试从没有 Looper 的线程中使用 Wearable DataAPI - 我相信采用 doInBackground()
方法。这就是它崩溃的原因。
将此代码直接移动到 onDataChanged()
方法中,应该可以解决问题。