无法将数据推送到Android Wear(模拟器)

16

我一直在尝试将数据推送到安卓手表模拟器,但是一切都徒劳无功。我的模拟器监听器没有接收到任何调用。如果有其他人尝试过在手表上工作并将数据推送到手表,请帮帮我。

这是我的接收器代码:

 private GoogleApiClient mGoogleApiClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_qrcode_generation);

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Wearable.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

    final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
    stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
        @Override
        public void onLayoutInflated(WatchViewStub stub) {
            ivQrImage = (ImageView) stub.findViewById(R.id.ivQRImage);
        }
    });
}

@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    for (DataEvent event : dataEvents) {
        if (event.getType() == DataEvent.TYPE_CHANGED &&
                event.getDataItem().getUri().getPath().equals("/image")) {
            final DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
            final Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage");
            final Bitmap bitmap = loadBitmapFromAsset(profileAsset);
            Log.d(TAG, ""+bitmap);
            if (null != bitmap) {
                ivQrImage.setImageBitmap(bitmap);
                bitmap.recycle();
            }

        }
    }
}

@Override
protected void onStart() {
    super.onStart();

    mGoogleApiClient.connect();
}

@Override
protected void onStop() {
    if (null != mGoogleApiClient && mGoogleApiClient.isConnected()) {
        Wearable.DataApi.removeListener(mGoogleApiClient, this);
        mGoogleApiClient.disconnect();
    }
    super.onStop();
}

public Bitmap loadBitmapFromAsset(Asset asset) {
    if (asset == null) {
        throw new IllegalArgumentException("Asset must be non-null");
    }
    ConnectionResult result =
            mGoogleApiClient.blockingConnect(TIMEOUT_MS, 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);
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.d(TAG,"Connection Failed");
}

@Override
public void onConnected(Bundle bundle) {
    Wearable.DataApi.addListener(mGoogleApiClient, this);
    Wearable.MessageApi.addListener(mGoogleApiClient, this);
}

这就是我正在推动的方式

private void pushImageToWear() {

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.qr_code);
    Asset asset = createAssetFromBitmap(bitmap);
    PutDataMapRequest dataMap = PutDataMapRequest.create("/image");
    dataMap.getDataMap().putAsset("profileImage", asset);
    PutDataRequest request = dataMap.asPutDataRequest();
    PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi
            .putDataItem(mGoogleApiClient, request);

}

我在Android Wear活动的清单中也有以下内容:

<activity
        android:name=".QRCodeReceptionActivity"
        android:label="@string/app_name"
        android:exported="true"
        android:allowEmbedded="true"
        android:taskAffinity=""
        android:theme="@android:style/Theme.DeviceDefault.Light">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

顺便提一句,我所做的并没有什么特别的。只是按照开发者网站上提供的教程进行操作。


所以我已经使用了消息API来连接真实设备,而且它对我很有效。这可能会帮助你朝着正确的方向前进,但我怀疑它能解决你的问题。https://github.com/kentarosu/AndroidWearAndLifx - gatlingxyz
@kentarosu 是的!onConnected 会被调用。 - iZBasit
@autocrat 你尝试先使用NodeApi来查看节点是否真正连接了吗? - matiash
@matiash 不是的。我直接开始推送图片了。今晚我会尝试另外两个。 - iZBasit
3
你尝试过使用Android Wear SDK中包含的DataLayer示例吗?它展示了如何从手机发送消息到可穿戴设备的完整示例,你可以测试一下确保一切正常工作后再开始调试你自己的代码。 - Wayne Piekarski
显示剩余2条评论
4个回答

35
抱歉我使用回答,但是我需要获得50的声望才能评论 :(
我在这里https://stackoverflow.com/...遇到了同样的问题,但现在我已经解决了。
好的,我和你分享我遇到的所有问题:
首先在移动设备的AndroidManifest.xml文件中添加以下内容:
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

第二件让我有点困惑的事情是,只有当DataItem内部真正“改变”时,才会调用onDataChanged()。因此,它可能在第一次工作时有效,但以后什么也不会发生。

我在手机上更改了代码,因此每次尝试发送数据时都会有不同的时间戳:

Asset asset = createAssetFromBitmap(bitmap);
        PutDataMapRequest request = PutDataMapRequest.create("/image");
        DataMap map = request.getDataMap();
        map.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP
        map.putAsset("profileImage", asset);
        Wearable.DataApi.putDataItem(mGoogleApiClient, request.asPutDataRequest());

我在这个 IO Video 中找到了答案。

剩下的代码看起来和你的一样。 希望这有所帮助。


1
我认为你说得很对。我猜加上整数应该可以解决我的问题。但坦白地说,这本不应该是这样的。无论如何,我会尝试并让你知道结果。 - iZBasit
2
好的,我现在有充分的证据了!我遇到了一些持续的问题,所以我详细查看了DataLayer示例。Google Dev在每个数据项中插入了一行时间戳。现在一切都正常了。 - UhrArt
这里是你的评论技巧赢了;-) 谢谢 - Thibaud David
1
时间戳的查找做得很好。 - Ran
3
您可以通过调用System.currentTimeMillis()而不是创建一个新的Date()对象来稍微减少开销,因为Date()对象在内部也会调用System.currentTimeMillis(),并在调用getTime()时返回其值。 #性能至关重要 - Louis CAD
显示剩余2条评论

5
我也遇到过这个问题,花费了几个小时才解决。我的建议是?使用Android Studio创建一个新项目,并选择Android Wear和Phone + Tablet作为项目类型。这将为您提供一个工作项目的框架,然后只需要将自动生成的骨架与现有项目的差异移植过来即可。
对我而言,问题最终是以下几个因素的组合:
  • 在您的defaultConfig构建条目中,应用程序ID必须对于可穿戴设备和移动应用程序都相同,例如: defaultConfig { applicationId "com.rukkus.app" ... }
  • 移动应用程序必须将wearApp作为依赖项添加,如下所示: dependencies { ... wearApp project(':wear') }
此外(诚然,我不确定这是否必要),在示例中,Google Dev在WearableListenerService的onCreate中连接到Google API(而不是按照文档所示在onDataChanged方法中)。因此,我的WearableListenerService中的onCreate看起来像这样:
@Override
public void onCreate() {
    super.onCreate();

    // create Google Client
    GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this.ctx)
            .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult result){

                }
            })
            .addApi(Wearable.API).build();    

    //connect the client
    googleApiClient.connect();
    Log.i(TAG, "**creating google API client now**");
}

我希望你能够理解,这个问题花费了我比我想象的更长的时间来解决,因此我希望这篇文章可以帮助到未来的读者。


谢谢!这正是我的问题。 - gabi
1
你救了我的一天!我花了8个多小时才发现这实际上是问题所在... 哎呀 - Bas van Stein
我在Activity中添加了一个DataApi.DataListener,但是onDataChanged()没有被触发。如何修复它? - Madhan

3

我发现另一个需要添加到检查清单中的原因。可穿戴设备和移动应用程序必须使用相同版本的wear库构建。请检查您的gradle依赖项中的版本。

compile 'com.google.android.support:wearable:1.3.0'
compile 'com.google.android.gms:play-services-wearable:8.1.0'

(我没有足够的声望点来发表评论)


3

你的设备应用程序 ID 和可穿戴应用程序 ID 必须匹配,正如 @Bobby 在他的回答中所述。我不需要将可穿戴应用作为依赖项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接