Watch开发的学习结构

Watch开发的学习结构

1. 创建Notification

2. 创建自定义的UI

3. 发送和同步数据

3.1访问可穿戴数据层

调用数据层API,需创建如下实例:

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

第二步:建议在onResume方法中调用GoogleApiClient.connect()进行连接:

protected void onResume() {
       if (!mGoogleApiClient.isConnected()) {
            mGoogleApiClient.connect();
       }
       super.onResume();
  }

第三步:当我们退出当前界面,建议断开连接:

@Override
 protected void onPause() {
     if (mGoogleApiClient.isConnected()) {
         mGoogleApiClient.disconnect();
     }
     super.onPause();
 }

完成上面三个步骤,我们就完成了数据层客户端的创建、连接和断开。
客户端连接时我们需要设置两个监听器,一个是连接成功的监听,另一个是连接失败的监听。
实现 GoogleApiClient.ConnectionCallbacks:

    #连接成功回调
    public void onConnected(@Nullable Bundle bundle) {
     }
     #连接暂停回调
     public void onConnectionSuspended(int i) {
        Log.e(TAG, "connect sucssed : "+i);
        mNode=null;
    }

实现 GoogleApiClient.OnConnectionFailedListener:

    #连接失败回调
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

当我们调用GoogleApiClient.connect()方法连接之后,会调用以上回调,反馈连接客户端的结果,连接成功之后我们可以做一些操作,比如:获取Node节点等。

3.2 同步数据单元(Data Map 支持基本类型和String类型)

问题一:可穿戴设备作为发送方时响应发送成功,但是其实未成功。
发送数据(Data Map):

PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(COUNT_PATH);
                putDataMapRequest.getDataMap().putInt(COUNT_KEY, count++);

                PutDataRequest request = putDataMapRequest.asPutDataRequest();
                request.setUrgent();

                Log.i(TAG, "Generating DataItem: " + request);
                if (!mGoogleApiClient.isConnected()) {
                    return;
                }
                Wearable.DataApi.putDataItem(mGoogleApiClient, request)
                        .setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
                            @Override
                            public void onResult(DataApi.DataItemResult dataItemResult) {
                                if (!dataItemResult.getStatus().isSuccess()) {
                                    Log.e(TAG, "ERROR: failed to putDataItem, status code: "
                                            + dataItemResult.getStatus().getStatusCode());
                                }else{
                                    Log.e(TAG, "Success: "
                                            + dataItemResult.getStatus().getStatusCode());
                                }
                            }
                        });

接受数据:
实现WearableListenerService服务的实现类

 public void onDataChanged(DataEventBuffer dataEvents) {
        Log.e(TAG, "onDataChanged: " + dataEvents);
        Log.d(TAG, "onDataChanged22: " + dataEvents+"--");
        // Loop through the events and send a message back to the node that created the data item.
        for (DataEvent event : dataEvents) {
            Uri uri = event.getDataItem().getUri();
            String path = uri.getPath();
            if (COUNT_PATH.equals(path)) {
                // Get the node id of the node that created the data item from the host portion of
                // the uri.
                String nodeId = uri.getHost();
                // Set the data of the message to be the bytes of the Uri.
                byte[] payload = uri.toString().getBytes();
                DataMap dataMap= DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
                Log.d(TAG, "updateCount: " +dataMap.getInt(COUNT_KEY));
                Log.d(TAG, "updateString: " +dataMap.getString(STRING_KEY));
            }
        }
    }

或者activity中实现DataApi.DataListener,客户端连接成功后使用Wearable.DataApi.addListener(mGoogleApiClient, this);添加监听器。

3.3传输资源

本地资源转化为Bitmap:

Bitmap bmp= BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

Bitmap转成Asset:

private static Asset toAsset(Bitmap bitmap) {
        ByteArrayOutputStream byteStream = null;
        try {
            byteStream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
            return Asset.createFromBytes(byteStream.toByteArray());
        } finally {
            if (null != byteStream) {
                try {
                    byteStream.close();
                } catch (IOException e) {
                    // ignore
                }
            }
        }
    }

然后使用Data Map 发送 Asset:

PutDataMapRequest dataMap = PutDataMapRequest.create(IMAGE_PATH);
        dataMap.getDataMap().putAsset(IMAGE_KEY, asset);
        dataMap.getDataMap().putLong("time", new Date().getTime());
        PutDataRequest request = dataMap.asPutDataRequest();
        request.setUrgent();

        Wearable.DataApi.putDataItem(mGoogleApiClient, request)
                .setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
                    @Override
                    public void onResult(DataApi.DataItemResult dataItemResult) {
                        Log.e(TAG, "Sending image was successful: " + dataItemResult.getStatus()
                                .isSuccess());
                    }
                });

发送成功后处理回调:

   public void onDataChanged(DataEventBuffer dataEventBuffer) {
        for (DataEvent event:dataEventBuffer){
            if (event.getType()==DataEvent.TYPE_CHANGED&&event.getDataItem().getUri().getPath().equals("/image")){
                DataMapItem dataMapItem=DataMapItem.fromDataItem(event.getDataItem());
                final Asset profileAsset=dataMapItem.getDataMap().getAsset("image");
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        final Bitmap bitmap=loadBitmapFromAsset(profileAsset);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (bitmap!=null&&mImageView!=null){
                                    mImageView.setImageBitmap(bitmap);
                                }
                            }
                        });
                    }
                }).start();

            }
        }
    }

loadBitmapFromAsset方法如下,并且必须在子线程中运行:

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

以上步骤就能完成一个图片的传输了。

3.4发送与接收消息

使用 MessageApi 发送消息,不像数据元的同步,Messages是单向交流机制,这有利于远程进程调用(RPC),比如:发送消息到可穿戴设备以开启activity。
发送消息之前,我们得先确定发送通知的节点,可通过两种方法获取:
方法一:

 private Collection<String> getNodes() {
        HashSet<String> results = new HashSet<>();
        NodeApi.GetConnectedNodesResult nodes =
                Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();

        for (Node node : nodes.getNodes()) {
            results.add(node.getId());
        }

        return results;
    }

通过广播获取节点:

 Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
            @Override
            public void onResult(NodeApi.GetConnectedNodesResult nodes) {
                for (Node node : nodes.getNodes()) {
                    mNode = node;
                }
            }
        });

发送消息如下:
发送消息之前先判断是否有节点,或者是否客户端连接

if(null!=mGoogleApiClient&&null!=mNode){
                    Wearable.MessageApi.sendMessage(mGoogleApiClient,mNode.getId(),START_ACTIVITY_PATH,new
                            byte[0]).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {


                        @Override
                        public void onResult(@NonNull MessageApi.SendMessageResult sendMessageResult) {
                            if (!sendMessageResult.getStatus().isSuccess()) {
                                Log.e("TAG", "Failed to send message with status code: "
                                        + sendMessageResult.getStatus().getStatusCode());

                            }else{
                                Log.i("TAG", " send message  成功");

                            }
                        }
                    });
                }

下面我们来说一下接收消息的两种方法:
方法一:通过Activity实现MessageListener ,通过 MessageApi.addListener()添加和MessageApi.removeListener()删除监听器。
方法二:通过继承WearableListenerService的服务。
回调都是如下方法:

public void onMessageReceived(MessageEvent messageEvent) {
        LOGD(TAG, "onMessageReceived: " + messageEvent);
        Log.d(TAG, "onDataChanged22: " + messageEvent.getData());
        // Check to see if the message is to start an activity
        if (messageEvent.getPath().equals(START_ACTIVITY_PATH)) {
            Intent startIntent = new Intent(this, MainTestActivity.class);
            startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(startIntent);
        }
    }

由此可知,我们可以通过path来判断我们的行为,通过可穿戴设备启动手执设备的界面。
messageEvent.getData()可以获取我们传输的数据,记得byte[]数组转化。

4. 创建表盘

5. 检测位置

6. 请求权限

7. 使用语音

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容