最新的Android Wear更新支持ChannelApi,可用于向可穿戴设备或掌上电脑发送文件。问题是我找不到如何使用此功能的单个示例。 Android示例不包含此功能。所以如果有人知道如何使用sendFile / receiveFile并且可以在这里给出一个快速的例子,那将是值得赞赏的。
答案 0 :(得分:7)
请查看此answer,了解如何使用渠道API在设备之间创建渠道。
创建googleClient并检索要将文件发送到的设备的nodeId之后,基本上您可以在可穿戴设备上使用以下代码:
//opening channel
ChannelApi.OpenChannelResult result = Wearable.ChannelApi.openChannel(googleClient, nodeId, "/mypath").await();
channel = result.getChannel();
//sending file
channel.sendFile(googleClient, Uri.fromFile(file));
然后,在手持设备上:
//receiving the file
@Override
public void onChannelOpened(Channel channel) {
if (channel.getPath().equals("/mypath")) {
file = new File("/sdcard/file.txt");
try {
file.createNewFile();
} catch (IOException e) {
//handle error
}
channel.receiveFile(mGoogleApiClient, Uri.fromFile(file), false);
}
}
//when file is ready
@Override
public void onInputClosed(Channel channel, int i, int i1) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "File received!", Toast.LENGTH_SHORT).show();
}
});
}
如果您需要更多相关信息,请访问reference site from Google
答案 1 :(得分:2)
这只是答案的补充:还要检查androidmanifest中的WearableListenerService。它的意图过滤器应包含com.google.android.gms.wearable.CHANNEL_EVENT操作。
答案 2 :(得分:0)
我成功地使用了一些类似这样的代码。传输可能相当慢。
手持式和可穿戴式应用程序的gradle文件中都必须具有相同的applicationId。 可穿戴设备需要像这样的清单条目
<service
android:name="com.me.myWearableListenerService"
android:enabled="true"
android:exported="true">
<intent-filter>
<!-- listeners receive events that match the action and data filters -->
<action android:name="com.google.android.gms.wearable.CHANNEL_EVENT"/>
<data android:scheme="wear" android:host="*" android:pathPrefix="/MyAppPath" />
</intent-filter>
</service>
在手持设备发送文件时启动其WearableListenerService。
private static final String WEARABLE_FILE_COPY = "MyAppPath/FileCopy";
private void copyFileToWearable (final File file, final String nodeId, Context ctx) {
new Thread(new Runnable() {
@Override
public void run() {
final ChannelClient cc = Wearable.getChannelClient(ctx);
ChannelClient.ChannelCallback ccb = new ChannelClient.ChannelCallback() {
@Override
public void onChannelClosed(@NonNull ChannelClient.Channel channel, int i, int i1) {
super.onChannelClosed(channel, i, i1);
Log.d(TAG, "copyFileToWearable " + channel.getNodeId() + " onChannelClosed ");
cc.unregisterChannelCallback(this);
}
@Override
public void onOutputClosed(@NonNull ChannelClient.Channel channel, int i, int i1) {
super.onOutputClosed(channel, i, i1);
Log.d(TAG, "copyFileToWearable " + channel.getNodeId() + " onOutputClosed ");
cc.unregisterChannelCallback(this);
// this is transfer success callback ...
}
};
ChannelClient.Channel c;
Log.d(TAG, "copyFileToWearable transfer file " + file.getName() +
" size:" + file.length()/1000000 + "Mb");
try {
// send the filename to the wearable with the channel open
c = Tasks.await(cc.openChannel(nodeId, WEARABLE_FILE_COPY + "/" + file.getName()));
Log.d(TAG, "copyFileToWearable channel opened to " + nodeId);
Log.d(TAG, "copyFileToWearable register callback");
Tasks.await(cc.registerChannelCallback(c, ccb));
Log.d(TAG, "copyFileToWearable sending file " + file.getName());
Tasks.await(cc.sendFile(c, Uri.fromFile(file)));
// completion is indicated by onOutputClosed
} catch (Exception e) {
Log.w(TAG, "copyFileToWearable exception " + e.getMessage());
cc.unregisterChannelCallback(ccb);
// failure
}
}
}).start();
}
在c.getPath()以WEARABLE_FILE_COPY开头时,从WearableListenerService中的onChannelOpened调用
private void receiveFileFromHandheld(final ChannelClient.Channel c, File myStorageLocation, Context ctx) {
// filename sent by the handheld is at the end of the path
String[] bits = c.getPath().split("\\/");
// store in a suitable spot
final String receivedFileName = myStorageLocation.getAbsolutePath() + "/" + bits[bits.length-1];
new Thread(new Runnable() {
@Override
public void run() {
final ChannelClient cc = Wearable.getChannelClient(ctx);
ChannelClient.ChannelCallback ccb = new ChannelClient.ChannelCallback() {
boolean mClosed = false;
@Override
public void onChannelClosed(@NonNull ChannelClient.Channel channel, int i, int i1) {
super.onChannelClosed(channel, i, i1);
Log.d(TAG, "receiveFileFromHandheld " + channel.getNodeId() + " onChannelClosed ");
if (!mClosed){
// failure ...
}
}
@Override
public void onInputClosed(@NonNull ChannelClient.Channel channel, int i, int i1) {
super.onInputClosed(channel, i, i1);
Log.d(TAG, "receiveFileFromHandheld " + channel.getNodeId() + " onInputClosed ");
long fs = new File(receivedFileName).length();
Log.d(TAG, "receiveFileFromHandheld got " + receivedFileName +
" size:" + fs / 1000000 + "Mb");
cc.unregisterChannelCallback(this);
mClosed = true;
// success !
}
};
try {
Log.d(TAG, "receiveFileFromHandheld register callback");
Tasks.await(cc.registerChannelCallback(c, ccb));
Log.d(TAG, "receiveFileFromHandheld receiving file " + receivedFileName);
Tasks.await(cc.receiveFile(c, Uri.fromFile(new File(receivedFileName)), false));
// completion is indicated by onInputClosed
} catch (Exception e) {
Log.w(TAG, "receiveFileFromHandheld exception " + e.getMessage());
cc.unregisterChannelCallback(ccb);
// failure ...
}
}
}
).start();
}