【问题标题】:OnMessageReceived not called in WearableListenerService在 WearableListenerService 中未调用 OnMessageReceived
【发布时间】:2014-07-25 14:16:34
【问题描述】:

我正在使用 Eclipse IDE 开发 android wear 应用程序。我对 wear 应用程序和移动应用程序使用相同的包名称,并且我正在根据 google documentation 手动打包可穿戴应用程序。一切正常。它安装在 Android wear 上使用手机USB调试的模拟器。

我的问题是当我使用以下代码向可穿戴设备发送消息时

List<Node> nodeList=getNodes();
for(Node node : nodeList) {
    Log.v(" ", "telling " + node.getId() );

    PendingResult<MessageApi.SendMessageResult> result = Wearable.MessageApi.sendMessage(
        mGoogleApiClient,
        node.getId(),
        START_ACTIVITY_PATH,
        null
    );

    result.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
        @Override
        public void onResult(MessageApi.SendMessageResult sendMessageResult) {
            Log.v(" ", "Phone: " + sendMessageResult.getStatus().getStatusMessage());
        }
    });
}

当设备对等时 OnPeerConnected 方法正在运行,但 OnMessageReceived 从未在 WearableListenerService 中调用。这是我的 WearableListenerService 代码:

public class DataLayerListenerService extends WearableListenerService {

    private static final String TAG = "DataLayerSample";
    private static final String START_ACTIVITY_PATH = "/start/MainActivity";
    private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";
    private static final String LOG_TAG = "log";
    @Override
    public void onPeerConnected(Node peer) {
        super.onPeerConnected(peer);

        String id = peer.getId();
        String name = peer.getDisplayName();

        Log.d(LOG_TAG, "Connected peer name & ID: " + name + "|" + id);
    }
    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        System.out.println("Recevive message3");
    }

    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        System.out.println("service watch message1");
        if (messageEvent.getPath().equals(START_ACTIVITY_PATH)) {
            System.out.println("service watch message2");
            Intent startIntent = new Intent(this, MainActivity.class);
            startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(startIntent);
        }
    }
}

Logcat 中也总是出现警告信息:

应用与记录的应用密钥不匹配:AppKey[com.myapp,c3f31717fa35401056c20a2798907f1232efa75e] != AppKey[com.myapp,f36e726eefc7e528db26a1c25f6fbf2f93dacd70]

如果两个应用程序的应用程序密钥应该相同,那么我如何为两个应用程序创建相同的应用程序密钥。

非常感谢任何帮助, 谢谢。

【问题讨论】:

  • com.myphoneapp 和 com.wearableapp 是什么?
  • @Maciej。这是错误的。现在我已经更正了我的帖子。一个“com.myapp”声明是手机应用程序的包名称,第二个是磨损应用程序。无论如何感谢您的回复。
  • 没问题。请看下面我的回答:)

标签: android


【解决方案1】:

您收到的错误消息:

app 与记录的 app 键不匹配: AppKey[com.myapp,c3f31717fa35401056c20a2798907f1232efa75e] != AppKey[com.myapp,f36e726eefc7e528db26a1c25f6fbf2f93dacd70]

表明您的应用使用不同的密钥进行签名。
手机和可穿戴应用程序的包名称相同——这很好,但它们也需要共享相同的签名。这就是无法传递消息的原因 - 根据包名称和签名,可穿戴应用程序被识别为“同一应用程序的一部分”。

请确保您使用相同的密钥对两个应用进行签名。如果您正在测试自动安装功能,请确保从手表模拟器中卸载可穿戴应用的调试版本。

【讨论】:

  • 谢谢@Maciej。现在我可以看到问题了。可穿戴应用程序已签名,但 android 应用程序直接安装在手机上(通过 USB 调试)。如果我是对的,那么我应该怎么做才能让它签名?或者根据你的说法,如果卸载调试版本可以解决这个问题,那我该怎么做。请指导..
  • 您说您的可穿戴应用程序已签名-您是如何签名的?您还需要签署电话应用程序才能让他们相互交流。 “仅卸载”不会解决问题:) - 您需要将其替换为签名版本(这意味着:卸载未签名的版本 + 安装新的签名版本)。请注意,对于测试和开发,您可以使用两个未签名的应用程序。只有在进行一些最终测试时(在商店发布之前),您才能在签名的应用程序上测试最终结果。另外请告诉我有关您的安装的更多详细信息,为什么您有一个应用程序签名而另一个没有?
  • 我使用签名的密钥库证书将可穿戴应用程序打包到移动应用程序中。现在我正在使用 USB 调试在我的手机上对其进行测试。当我使用 USB 进行测试时,没有选项可以签署我的手机应用程序,即我是没有创建它的 apk 文件并将其直接安装在手机上。所以我认为我的手机应用程序是未签名的。这至少对我来说是一个令人困惑的情况。
  • 如果您想测试已签名的手机 apk,您需要打包手机 apk 并使用您的密钥库对其进行签名。完成该步骤后,您必须使用adb 命令:adb -d install path/to/your/phone_signed.apk 安装此 apk。 -d 表示此命令将被定向到任何连接 cia adb 的设备(而不是模拟器实例 - 如果您在 PC 上启动了 Android Wear 模拟器)。如果您不熟悉 adb,您可以做一个“简单的方法”,只需将签名的 apk 复制到手机的内存(从 pc),然后使用手机上的一些文件浏览器安装它。您需要先卸载未签名的版本。
  • 谢谢 Maciej。最后你的解决方案对我有用。感谢你宝贵的时间。
【解决方案2】:

我有同样的错误,我的错是“磨损”模块的包名与应用程序的不同。

BAD:
[module: app] es.voghdev.myapp
[module: wear] es.voghdev.myapp.wear

GOOD:
[module: app] es.voghdev.myapp
[module: wear] es.voghdev.myapp

让我浪费了这么多时间!! >:-(

【讨论】:

    【解决方案3】:

    使用异步任务发送消息,因为它们会阻塞 ui 线程。您还需要调用 await 方法。要让应用程序拥有相同的密钥,您需要使用带有 gradle 的构建变体。

    public class SendMessageTask extends AsyncTask<Void, Void, Void> {
    
        @Override
        protected Void doInBackground(Void... voids) {
            NodeApi.GetConnectedNodesResult nodes =
                    Wearable.NodeApi.getConnectedNodes(apiClient).await();
            for (Node node : nodes.getNodes()) {
                Wearable.MessageApi
                        .sendMessage(apiClient, node.getId(), "/start/MainActivity", null)
                        .await();
            }
    
            return null;
        }
    
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            Toast.makeText(MainActivity.this, "Message Sent", Toast.LENGTH_SHORT).show();
        }
    }
    

    【讨论】:

    • 不需要使用 AsyncTask,因为 MessageApi 已经支持异步。只需将 .await() 调用替换为 setResultCallback() 调用,并在调用完成时传递回调。使用 AsyncTask 只会创建一个额外的线程,这是不需要的。
    猜你喜欢
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多