android wearable-Transferring Assets,Sending and Receiving Messages,Handling Data Layer Events

本文介绍如何通过蓝牙传输大数据,如图片等二进制文件,并探讨了使用Assets进行缓存以节省带宽的方法。此外,还讲解了消息传递机制,包括如何发送和接收消息,以及如何检测设备连接状态。

 To send large blobs of binary data over the Bluetooth transport, such as images, attach an Asset to a data item and the put the data item into the replicated data store.

 Assets automatically handle caching of data to prevent retransmission and conserve Bluetooth bandwidth. A common pattern is for a handheld app to download an image, shrink it to an appropriate size for display on the wearable, and transmit it to the wearable app as an asset.

 Note:  Although the size of data items is limited to 100KB, assets can be as large as desired. However, transferring large assets affects the user experience in many cases, so test your apps to ensure that they perform well if you're transferring large assets.

 Create the asset using one of the create...() methods in the Asset class. Here, we convert a bitmap to a byte stream and then call createFromBytes() to create the asset.

private static Asset createAssetFromBitmap(Bitmap bitmap) {
    final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
    return Asset.createFromBytes(byteStream.toByteArray());
}

When you have an asset, attach it to a data item with the putAsset() method in DataMap or PutDataRequestand then put the data item into the data store with putDataItem():

Using PutDataRequest

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
Asset asset = createAssetFromBitmap(bitmap);
PutDataRequest request = PutDataRequest.create("/image");
request.putAsset("profileImage", asset);
Wearable.DataApi.putDataItem(mGoogleApiClient, request);

Using PutDataMapRequest

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
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);

Here's an example of how to implement the callback to detect an asset change and extract the asset:

@Override
public void onDataChanged(DataEventBuffer dataEvents) {
  for (DataEvent event : dataEvents) {
    if (event.getType() == DataEvent.TYPE_CHANGED &&
        event.getDataItem().getUri().getPath().equals("/image")) {
      DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
      Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage");
      Bitmap bitmap = loadBitmapFromAsset(profileAsset);
      // Do something with the bitmap
    }
  }
}

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);
}
> Sending and Receiving Messages

You send messages using the MessageApi and attach the following items to the message:

  • An arbitrary payload (optional)
  • A path that uniquely identifies the message's action
 Unlike with data items, there is no syncing between the handheld and wearable apps. Messages are a one-way communication mechanism that's good for remote procedure calls (RPC), such as sending a message to the wearable to start an activity.

 Note: With versions of Google Play services prior to 7.3.0, only one wearable device could be connected to a handheld device at a time. You may need to update your existing code to take the multiple connected nodes feature into consideration. If you don’t implement the changes, your messages may not get delivered to intended devices.

     Note: Capabilities are custom strings that you define and must be unique within your app.

  Initially, you can detect the capable nodes by calling the CapabilityApi.getCapability() method. The following example shows how to manually retrieve the results of reachable nodes with thevoice_transcription capability:

private static final String
        VOICE_TRANSCRIPTION_CAPABILITY_NAME = "voice_transcription";

private GoogleApiClient mGoogleApiClient;

...

private void setupVoiceTranscription() {
    CapabilityApi.GetCapabilityResult result =
            Wearable.CapabilityApi.getCapability(
                    mGoogleApiClient, VOICE_TRANSCRIPTION_CAPABILITY_NAME,
                    CapabilityApi.FILTER_REACHABLE).await();

    updateTranscriptionCapability(result.getCapability());
}

To detect capable nodes as they connect to the wearable device, register aCapabilityApi.CapabilityListener() instance to your GoogleApiClient. The following example shows how to register the listener and retrieve the results of reachable nodes with the voice_transcription capability:

private void setupVoiceTranscription() {
    ...

    CapabilityApi.CapabilityListener capabilityListener =
            new CapabilityApi.CapabilityListener() {
                @Override
                public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
                    updateTranscriptionCapability(capabilityInfo);
                }
            };

    Wearable.CapabilityApi.addCapabilityListener(
            mGoogleApiClient,
            capabilityListener,
            VOICE_TRANSCRIPTION_CAPABILITY_NAME);
}

Note: If you create a service that extends WearableListenerService to detect capability changes, you may want to override the onConnectedNodes() method to listen to finer-grained connectivity details, such as when a wearable device switches from Wi-Fi to a Bluetooth connection to the handset. For an example implementation, see the DisconnectListenerService class in the FindMyPhone sample. For more information on how to listen for important events, see Listen for Data Layer Events.

To determine if a node is nearby, call the Node.isNearby()method.

The following example shows how you might determine the best node to use:

private String transcriptionNodeId = null;

private void updateTranscriptionCapability(CapabilityInfo capabilityInfo) {
    Set<Node> connectedNodes = capabilityInfo.getNodes();

    transcriptionNodeId = pickBestNodeId(connectedNodes);
}

private String pickBestNodeId(Set<Node> nodes) {
    String bestNodeId = null;
    // Find a nearby node or pick one arbitrarily
    for (Node node : nodes) {
        if (node.isNearby()) {
            return node.getId();
         }
         bestNodeId = node.getId();
    }
    return bestNodeId;
}

Note: A successful result code does not guarantee delivery of the message. If your app requires data reliability, use DataItem objects or the ChannelApi class to send data between devices.


public static final String VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription";

private void requestTranscription(byte[] voiceData) {
    if (transcriptionNodeId != null) {
        Wearable.MessageApi.sendMessage(googleApiClient, transcriptionNodeId,
            VOICE_TRANSCRIPTION_MESSAGE_PATH, voiceData).setResultCallback(
                  new ResultCallback() {
                      @Override
                      public void onResult(SendMessageResult sendMessageResult) {
                          if (!sendMessageResult.getStatus().isSuccess()) {
                              // Failed to send message
                          }
                      }
                  }
            );
    } else {
        // Unable to retrieve node with transcription capability
    }
}

Note: To learn more about asynchronous and synchronous calls to Google Play services and when to use each, see Communicate with Google Play Services.

You can also broadcast messages to all connected nodes. To retrieve all of the connected nodes that you can send messages to, implement the following code:

private Collection<String> getNodes() {
    HashSet <String>results = new HashSet<String>();
    NodeApi.GetConnectedNodesResult nodes =
            Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
    for (Node node : nodes.getNodes()) {
        results.add(node.getId());
    }
    return results;
}
> Handling Data Layer Events

 When you make calls to the Data Layer API, you can receive the status of the call when it completes as well as listen for any changes that the call ends up making with listeners.

 You'll notice that calls to the Data Layer API sometimes return aPendingResult, such as putDataItem(). As soon as the PendingResult is created, the operation is queued in the background. If you do nothing else after this, the operation eventually completes silently. However, you'll usually want to do something with the result after the operation completes, so the PendingResult lets you wait for the result status, either synchronously or asynchronously.

Asynchronous calls

If your code is running on the main UI thread, do not make blocking calls to the Data Layer API. You can run the calls asynchronously by adding a callback method to the PendingResult object, which fires when the operation is completed:

pendingResult.setResultCallback(new ResultCallback<DataItemResult>() {
    @Override
    public void onResult(final DataItemResult result) {
        if(result.getStatus().isSuccess()) {
            Log.d(TAG, "Data item set: " + result.getDataItem().getUri());
        }
    }
});

Synchronous calls

If your code is running on a separate handler thread in a background service (which is the case in aWearableListenerService), it's fine for the calls to block. In this case, you can call await() on thePendingResult object, which blocks until the request completes and returns a Result object:

DataItemResult result = pendingResult.await();
if(result.getStatus().isSuccess()) {
    Log.d(TAG, "Data item set: " + result.getDataItem().getUri());
}

To listen for data layer events, you have two options:

With both these options, you override the data event callback methods for the events you are interested in handling.

You can listen for the following events with WearableListenerService:

  • onDataChanged() - Called when data item objects are created, changed, or deleted. An event on one side of a connection triggers this callback on both sides.
  • onMessageReceived() - A message sent from one side of a connection triggers this callback on the other side of the connection.
  • onPeerConnected() and onPeerDisconnected() - Called when the connection with the handheld or wearable is connected or disconnected. Changes in connection state on one side of the connection trigger these callbacks on both sides of the connection.

To create a WearableListenerService:

  1. Create a class that extends WearableListenerService.
  2. Listen for the events that you're interested in, such as onDataChanged().
  3. Declare an intent filter in your Android manifest to notify the system about your WearableListenerService. This allows the system to bind your service as needed.

The following example shows how to implement a simple WearableListenerService:

public class DataLayerListenerService extends WearableListenerService {

    private static final String TAG = "DataLayerSample";
    private static final String START_ACTIVITY_PATH = "/start-activity";
    private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDataChanged: " + dataEvents);
        }
        final List events = FreezableUtils
                .freezeIterable(dataEvents);

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

        ConnectionResult connectionResult =
                googleApiClient.blockingConnect(30, TimeUnit.SECONDS);

        if (!connectionResult.isSuccess()) {
            Log.e(TAG, "Failed to connect to GoogleApiClient.");
            return;
        }

        // Loop through the events and send a message
        // to the node that created the data item.
        for (DataEvent event : events) {
            Uri uri = event.getDataItem().getUri();

            // Get the node id from the host value 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();

            // Send the RPC
            Wearable.MessageApi.sendMessage(googleApiClient, nodeId,
                    DATA_ITEM_RECEIVED_PATH, payload);
        }
    }
}

With a Listener Activity

If your app only cares about data layer events when the user is interacting with the app and does not need a long-running service to handle every data change, you can listen for events in an activity by implementing one or more of the following interfaces:

To create an activity that listens for data events:

  1. Implement the desired interfaces.
  2. In onCreate(Bundle), create an instance of GoogleApiClient to work with the Data Layer API.
  3. In onStart(), call connect() to connect the client to Google Play services.
  4. When the connection to Google Play services is established, the system calls onConnected(). This is where you call DataApi.addListener()MessageApi.addListener(), or NodeApi.addListener() to notify Google Play services that your activity is interested in listening for data layer events.
  5. In onStop(), unregister any listeners with DataApi.removeListener()MessageApi.removeListener(), orNodeApi.removeListener().
  6. Implement onDataChanged()onMessageReceived()onPeerConnected(), and onPeerDisconnected(), depending on the interfaces that you implemented.

Here's an example that implements DataApi.DataListener:

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

    private GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (!mResolvingError) {
            mGoogleApiClient.connect();
        }
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Connected to Google Api Service");
        }
        Wearable.DataApi.addListener(mGoogleApiClient, this);
    }

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

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_DELETED) {
                Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
            } else if (event.getType() == DataEvent.TYPE_CHANGED) {
                Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
            }
        }
    }
}
智慧政务:打造“线上”有温度、“线下”有速度的新体验 在数字化浪潮的推动下,智慧政务正成为政府服务转型的重要方向。通过数据共享与流程优化,智慧政务解决方案致力于解决企业和群众反映强烈的办事难、办事慢、办事繁等问题,实现“一网通办”,让政务服务更加便捷、高效。 一、智慧政务的发展趋势 近年来,随着数字中国战略的深入实施,政务服务正朝着“全国一体化”方向发展。从最初的“可看可查”到如今的“一网通办”,政务服务经历了从互联网+政务服务(省市县)到长三角一体化政务平台,再到区域/全国一体化在线政务服务平台的飞跃。国务院及各级政府积极推进大数据、政务服务改革,明确建设目标、内容和节奏,为智慧政务的发展提供了强有力的政策支持。 二、智慧政务的核心挑战 尽管智慧政务取得了显著进展,但仍面临诸多挑战。跨部门、多流程环节的政务服务中,数据共享时效性差、权责不清成为制约协同效率的主要因素。同时,数据安全管控不足、数据质量问题缺乏责任追溯,也影响了政务服务的可信度和质量。此外,在线办理深度不够、群众认同感不高,以及政务热线服务多样性、便捷性和智能性不足,都是当前智慧政务需要解决的问题。 三、智慧政务解决方案的创新实践 针对上述挑战,智慧政务解决方案通过一系列创新实践,推动政务服务向线上线下一体化方向发展。具体而言,该方案包括以下几个关键方面: “一码通”服务:面向民众和企业,提供行、办、用、管一体化的政务服务。通过“一码通”,群众和企业可以在政务服务大厅及试点事项中,使用电子证照调用授权,实现身份证明、社会保障信息核验、医疗健康一码通办等功能。这不仅简化了办事流程,还提升了用户体验。 “一网通”服务:提供全程网办的政务服务。通过智能预审、远程面审、一窗办理、智能引导等功能,实现政务服务的全流程网上办理。群众和企业可以足不出户,通过政务服务官网、APP、小程序等多种渠道,享受7*24小时全天候的政务服务。 “一号通”服务:作为政务服务智能总客服,通过全媒体接入方式,整合热线、微信、邮件、短信等多种服务渠道,实现一号对外、服务通达。运用人工智能技术,构建自动服务应答体系,提高服务效率和质量。同时,通过大数据分析,及时掌握舆情热点和政情民意,为服务监督和实时决策提供依据。 “协同办”与“协同管”:面向政府工作人员,提供办、查、看、管一体化的工作门户。通过集成门户、工作中心、信息中心、知识中心等功能模块,实现政务工作的统一管理和高效协同。同时,整合监管数据、打通监管业务、感知监管风险,助力监管决策,提升政府治理能力。 四、智慧政务的未来展望 随着新基建的加速推进,5G、AI、工业互联网、物联网等新型基础设施的建设将为智慧政务的发展提供更强有力的支撑。未来,智慧政务将继续深化数据共享与流程优化,推动政务服务向更加智能化、便捷化、个性化的方向发展。同时,通过加强跨部门、跨领域的监管协同,提升政府治理能力和服务水平,为构建数字政府、掌上政府奠定坚实基础。 总之,智慧政务解决方案通过创新实践,正在逐步解决政务服务中的痛点问题,让“线上”服务更有温度、“线下”服务更有速度。随着技术的不断进步和应用的深入推广,智慧政务将迎来更加广阔的发展前景。
内容概要:本文介绍了一种基于中位数的多个候选观测信号的状态估计方法,重点研究了异常值的处理机制,旨在提升状态估计的鲁棒性与准确性。该方法通过选取多个观测信号并利用中位数的抗干扰特性,有效抑制异常值对估计结果的影响,适用于存在噪声或异常测量的复杂系统。文中提供了完整的Matlab代码实现,便于读者验证和应用该算法,并通过实验分析验证了其在异常值存在情况下的优越性能。; 适合人群:具备一定信号处理、状态估计或自动化背景【状态估计】使用中位数的多个候选观测信号的状态估计方法,包括异常值研究(Matlab代码实现)的科研人员及工程技术人员,尤其适合从事控制系统、传感器融合、电力系统状态估计等相关领域的研究生和工程师。; 使用场景及目标:①应用于存在异常观测值的实际系统中,如传感器故障、通信干扰等场景下的状态估计;②用于提升传统估计算法的鲁棒性,对比中位数方法与均值、加权最小二乘等方法的抗噪能力;③作为科研参考,复现算法并进一步改进,用于论文研究或工程项目开发。; 阅读建议:建议读者结合Matlab代码逐步调试运行,理解中位数在多信号融合中的具体实现方式,重点关注异常值注入前后的估计效果对比,深入掌握算法鲁棒性设计思路,并可将其扩展至其他状态估计框架中进行优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值