消息关闭
    暂无新消息!
在做一个手机和手表通信的小程序,按照developer.android.com这上面的说明一步步下来,可是依然不能通信。问题手机发送数据,手机自己接收了,手表接收不到。测试过程中手表只是偶尔接收到过几次~~相关关键代码如下,望大神指教

手机端主要代码:

public class MainActivity extends AppCompatActivity
        implements DataApi.DataListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener{

    private GoogleApiClient mGoogleApiClient;
    private boolean mIsConnected;
    private int count = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApiIfAvailable(Wearable.API).build();

        findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!mIsConnected) {
                    ((TextView) findViewById(R.id.textView)).append(getResources().getString(R.string.connecting) + "\n");
                    mGoogleApiClient.connect();
                }
            }
        });

        findViewById(R.id.btn_disconnect).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mIsConnected) {
                    ((TextView) findViewById(R.id.textView)).append(getResources().getString(R.string.cutting) + "\n");
                    mGoogleApiClient.disconnect();
                }
            }
        });

        findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ((TextView)findViewById(R.id.textView)).append(getResources().getString(R.string.sending) + "\n");
                // 发送数据
                PutDataMapRequest dataMapRequest = PutDataMapRequest.create("/watch_face");
                dataMapRequest.getDataMap().putString("test_data", String.format("I'm from mobile! %02d", count++));
                PendingResult<DataApi.DataItemResult> result = Wearable.DataApi.putDataItem(mGoogleApiClient, dataMapRequest.asPutDataRequest());
                result.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
                    @Override
                    public void onResult(@NonNull DataApi.DataItemResult dataItemResult) {
                        if (dataItemResult.getStatus().isSuccess()) {
                            ((TextView) findViewById(R.id.textView)).append(getResources().getString(R.string.send_success) + ": " + dataItemResult.getDataItem().getUri() + "\n");
                        } else if (dataItemResult.getStatus().isCanceled()) {
                            ((TextView) findViewById(R.id.textView)).append(getResources().getString(R.string.send_cancel) + "\n");
                        } else if (dataItemResult.getStatus().isInterrupted()) {
                            ((TextView) findViewById(R.id.textView)).append(getResources().getString(R.string.send_interrupted) + "\n");
                        }
                    }
                });
            }
        });

        findViewById(R.id.btn_clean_content).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ((TextView)findViewById(R.id.textView)).setText("");
            }
        });
    }


    // ConnectionCallbacks
    @Override
    public void onConnected(@Nullable Bundle bundle) {
        mIsConnected = true;
        ((TextView)findViewById(R.id.textView)).append(getResources().getString(R.string.connect_success) + "\n");
        Wearable.DataApi.addListener(mGoogleApiClient, this);
        new Thread(new Runnable() {
            @Override
            public void run() {
                ArrayList<Node> nodes = new ArrayList<>();
                NodeApi.GetConnectedNodesResult nodesResult = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
                String connNodes = "find Node: \n";
                for (Node node : nodesResult.getNodes()) {
                    nodes.add(node);
                    connNodes += node.getDisplayName();
                    connNodes += "\n";
                }
                ((TextView)findViewById(R.id.textView)).setText(connNodes);
            }
         // 这里是获取连接的设备名,但是一但运行就会闪退了。
        });//.start();
    }

    @Override
    public void onConnectionSuspended(int i) {
        mIsConnected = false;
        ((TextView)findViewById(R.id.textView)).append(getResources().getString(R.string.connect_suspend) + "\n");
        Wearable.DataApi.removeListener(mGoogleApiClient, this);
    };

    // OnConnectionFailedListener
    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        ((TextView)findViewById(R.id.textView)).append(getResources().getString(R.string.connect_failed) + "\n");
    };

    // DataListener
    @Override
    public void onDataChanged(DataEventBuffer var1) {
        for (DataEvent event : var1) {
            if( event.getType() == DataEvent.TYPE_CHANGED) {
                DataMap dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
                ((TextView)findViewById(R.id.textView)).append(getResources().getString(R.string.recv_data) + ": " + dataMap.getString("test_data") + "\n");
            }
        }
    }
}



手表端接收相关代码:

public class DataListenerService extends WearableListenerService implements DataApi.DataListener {

    public static String intentAction = "mobile_wear_data";

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        super.onDataChanged(dataEvents);
        final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
        Intent intent = new Intent();
        intent.setAction(intentAction);
        intent.putExtra("data", "received data");
        sendBroadcast(intent);

        for (DataEvent event : events) {
            if( event.getType() == DataEvent.TYPE_CHANGED) {
                intent = new Intent();
                intent.setAction(intentAction);
                DataMap dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();

                intent.putExtra("data", dataMap.getString("test_data"));
                sendBroadcast(intent);
            }
        }

        GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
                .addApiIfAvailable(Wearable.API)
                .build();

        ConnectionResult connectionResult =
                googleApiClient.blockingConnect(30, TimeUnit.SECONDS);
        if (connectionResult.isSuccess()) {
            PutDataMapRequest dataMapRequest = PutDataMapRequest.create("/watch_face");
            dataMapRequest.getDataMap().putString("test_data", "I'm from wear!");
            Wearable.DataApi.putDataItem(googleApiClient, dataMapRequest.asPutDataRequest());
        }
    }

    @Override
    public void onPeerConnected(Node peer) {
        super.onPeerConnected(peer);
        Intent intent = new Intent();
        intent.setAction(intentAction);
        intent.putExtra("data", peer.getDisplayName());
        sendBroadcast(intent);
    }



    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        super.onMessageReceived(messageEvent);
        Intent intent = new Intent();
        intent.setAction(intentAction);
        intent.putExtra("data", messageEvent.getData().toString());
        sendBroadcast(intent);
    }


}




手表manifest代码:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="top.qhelper.watchface">

    <uses-feature android:name="android.hardware.type.watch" />

    <!-- Required to act as a custom watch face. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@android:style/Theme.DeviceDefault">
        <service
            android:name=".WatchFace"
            android:label="@string/my_digital_name"
            android:permission="android.permission.BIND_WALLPAPER">
            <meta-data
                android:name="android.service.wallpaper"
                android:resource="@xml/watch_face" />
            <meta-data
                android:name="com.google.android.wearable.watchface.preview"
                android:resource="@drawable/preview_digital" />
            <meta-data
                android:name="com.google.android.wearable.watchface.preview_circular"
                android:resource="@drawable/preview_digital_circular" />

            <intent-filter>
                <action android:name="android.service.wallpaper.WallpaperService" />
                <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
            </intent-filter>
        </service>

        <!-- 添加用来接收数据通知的服务 -->
        <service android:name=".DataListenerService">
            <intent-filter>
                <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
                <data android:scheme="wear" android:host="*" android:path="/watch_face" />
            </intent-filter>
        </service>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    </application>

</manifest>



请大神们帮忙看看,问题出在哪里呀

3个回答

︿ 1
解决了,在https://developer.android.com/training/wearables/data-layer/data-items.html 有这样一段话:In Google Play services 8.3 and later, the DataApi interface allows urgent requests for syncing of DataItems. Normally, the system may delay delivery of DataItems to the Wear network in order to improve battery life for user devices, but if a delay in syncing DataItems would negatively impact user experience, you can mark them as urgent. For example, in a remote control app where the user expects their actions to be reflected immediately, you can have the system sync your DataItems immediately by calling setUrgent().
8.3之后默认会为省电延时发送,如果要立即发送的话就要设置setUrgent()。因为是表盘,所以总是会延时发送。加上之后正常了!
︿ 0
解决了,在https://developer.android.com/training/wearables/data-layer/data-items.htmlIn Google Play services 8.3 and later, the DataApi interface allows urgent requests for syncing of DataItems. Normally, the system may delay delivery of DataItems to the Wear network in order to improve battery life for user devices, but if a delay in syncing DataItems would negatively impact user experience, you can mark them as urgent. For example, in a remote control app where the user expects their actions to be reflected immediately, you can have the system sync your DataItems immediately by calling setUrgent().