Str*_*alo 3 android json nfc android-beam android-json
我有一个简单的活动,启动文件选择器,然后通过Android梁发送文件,如下所示:
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode==0 && resultCode==RESULT_OK) {
adapter.setBeamPushUris(new Uri[] {data.getData()}, this);
Button btn=new Button(this);
btn.setText("Done");
btn.setOnClickListener(this);
setContentView(btn);
}
}
Run Code Online (Sandbox Code Playgroud)
该活动能够正确地发送图像和.txt文件.但是,当我发送.json文件时,我得到"梁没有完成".
我认为这是因为,接收器上没有应用程序查看json文件,所以我创建了另一个版本来查看收到的txt文件.清单有
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
</intent-filter>
Run Code Online (Sandbox Code Playgroud)
当我将json文件的扩展名更改为.txt时,文件正确发送,接收应用程序启动.但是当我将扩展名更改回.json并将接收器的mimetype更改为"application/json"时,我仍然得到"Beam not not complete"消息.
有什么想法吗?
谢谢!
有什么想法吗?
Android Beam使用Beam Uris数组中第一个文件的文件扩展名在内部映射中查找相应的MIME类型,然后Intent通过蓝牙对象推送配置文件(OPP)启动文件传输.
如果找不到文件扩展名或匹配的MIME类型,则将IntentMIME类型设置为null,并且根本不启动蓝牙OPP文件传输.
替代方法
发送具有未列出的扩展名的文件时MimeUtils,请使用双元素Beam Uris数组:
uris[0]:带有.txt扩展名的虚拟文本文件(稍后要删除)
uris[1]:要传输的文件(具有无法识别的扩展名)
在您的具体情况:
adapter.setBeamPushUris(
new Uri[] { dummyTxtFileUri, data.getData() },
this);
Run Code Online (Sandbox Code Playgroud)
Android Beam会向MIME类型的蓝牙发送意图text/plain,以及Uri两个文件的s,并且蓝牙OPP文件传输将正常进行.请注意,当一次发送多个文件时,接收设备会将文件存储在子目录中beam/,通常命名为beam-YYYY-MM-DD/.
背景
我在发送具有.json扩展名的文件和具有扩展名的该文件的副本之间比较了发送设备上的日志.txt.第一个显着的区别在于:
日志:喜气洋洋 test.json
03-02 13:19:34.665: D/BluetoothOppHandover(32332): Handing off outging transfer to BT
Run Code Online (Sandbox Code Playgroud)
日志:喜气洋洋 test.txt
03-02 15:32:19.437: D/BluetoothOppHandover(3268): Handing off outging transfer to BT
03-02 15:32:19.445: D/BluetoothOppUtility(3309): putSendFileInfo: uri=file:///storage/emulated/0/Download/test.txt@2cb672fa sendFileInfo=com.android.bluetooth.opp.BluetoothOppSendFileInfo@2cb672fa
Run Code Online (Sandbox Code Playgroud)
搜索AOSP"将外包转移到BT":
平台/产品/应用/ NFC/src目录/ COM /安卓/ NFC /切换/ BluetoothOppHandover.java
void sendIntent() {
Intent intent = new Intent();
intent.setPackage("com.android.bluetooth");
String mimeType = MimeTypeUtil.getMimeTypeForUri(mContext, mUris[0]);
intent.setType(mimeType);
// ...
if (DBG) Log.d(TAG, "Handing off outging transfer to BT");
mContext.sendBroadcast(intent);
complete();
}
Run Code Online (Sandbox Code Playgroud)
在继续之前,请注意,只有Uri数组中第一个的 MIME类型才会发送Intent.以下MimeTypeUtil.getMimeTypeForUri():
平台/产品/应用/ NFC/src目录/ COM /安卓/ NFC /切换/ MimeTypeUtil.java
public static String getMimeTypeForUri(Context context, Uri uri) {
// ...
String extension = MimeTypeMap.getFileExtensionFromUrl(uri.getPath()).toLowerCase();
if (extension != null) {
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
} else {
return null;
}
// ...
Run Code Online (Sandbox Code Playgroud)
因此,如果它不识别扩展名,则返回nullMIME类型.以下MimeTypeMap.getSingleton().getMimeTypeFromExtension()......
框架/碱/核心/ JAVA /机器人/ webkit的/ MimeTypeMap.java
public String getMimeTypeFromExtension(String extension) {
return MimeUtils.guessMimeTypeFromExtension(extension);
}
Run Code Online (Sandbox Code Playgroud)
平台/ libcore /卢尼/ src目录/主/ JAVA/libcore /网/ MimeUtils.java
public final class MimeUtils {
private static final Map<String, String> mimeTypeToExtensionMap = new HashMap<String, String>();
private static final Map<String, String> extensionToMimeTypeMap = new HashMap<String, String>();
// ...
public static String guessMimeTypeFromExtension(String extension) {
if (extension == null || extension.isEmpty()) {
return null;
}
return extensionToMimeTypeMap.get(extension);
}
Run Code Online (Sandbox Code Playgroud)
在继续之前,请注意这个MimeUtils类包含了由Android认可的MIME类型列表.这是一个很好的参考.
我们到达了堆栈的末尾extensionToMimeTypeMap.get():
平台/ libcore /卢尼/ src目录/主/ JAVA/JAVA/UTIL/HashMap.java
/**
* Returns the value of the mapping with the specified key.
*
* @param key
* the key.
* @return the value of the mapping with the specified key, or {@code null}
* if no mapping for the specified key is found.
*/
public V get(Object key) {
Run Code Online (Sandbox Code Playgroud)
因此,如果未找到匹配项,则MIME类型最终将返回为null.更多的挖掘显示了这一点至关重要:
平台/产品/应用/蓝牙/ src目录/ COM /安卓/蓝牙/ OPP/BluetoothOppHandoverReceiver.java
@Override
public void onReceive(Context context, Intent intent) {
// ...
if (action.equals(Constants.ACTION_HANDOVER_SEND)) {
String type = intent.getType();
Uri stream = (Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (stream != null && type != null) {
// Save type/stream, will be used when adding transfer
// session to DB.
BluetoothOppManager.getInstance(context).saveSendingFileInfo(type,
stream.toString(), true);
} else {
if (D) Log.d(TAG, "No mimeType or stream attached to handover request");
}
// ...
// we already know where to send to
BluetoothOppManager.getInstance(context).startTransfer(device);
Run Code Online (Sandbox Code Playgroud)
由于在保存文件信息和开始传输之前对MIME类型进行了空检查,因此蓝牙OPP文件传输永远不会启动.注意,return当有一个时null,其他两个条件块,所以看来这个return在Log.d()调用之后缺少一个可能是一个bug.