Android梁文件传输失败分析与解决方法

  

最近在修改Android7.0原生平台的一些错误,其中有关Android梁传输文件的一些问题还是蛮多的,所以特地找时间总结下曾经踏过的坑。

  

<强> 1。传输的文件名包含中文时,导致传输失败

  

可能是由于谷歌未考虑到本地化差异,导致在传输中文文件名的文件时直接提示传输失败。

        包\程序\ Nfc \ src \ com \ android \ Nfc \梁\ MimeTypeUtil.java   之前      

 Android梁文件传输失败分析与解决方法

  

其实,上面忘了说了,只是从文件管理器中进入Android梁分享才会出现上面的问题。因为当从其他途径,比如说从图库中去分享图片,由于是通过内容的uri(内容://com.xx.xxx/xxx)形式分享的,所以并不会直接包含文件真实路径,也就不存在中文问题了。

  

当从文件管理器中进入Android梁分享时,是通过文件的uri(文件://存储/xxx/aa.jpg)形式分享的,在获取文件的mimeType的时候会走其他如果里面的流程。

        框架核心android webkit \ \ java \ \基础\ \ MimeTypeMap.java   之前      

 Android梁文件传输失败分析与解决方法

  

从上面代码可以看的到,在获取文件后缀名的时候,在最后对文件名做了正则匹配,包含中文的文件名肯定匹配失败,导致最后返回空的后缀,所以也就返回零的mimeType。最终导致了文件传输失败。

  

既然问题找出来了,修改方法也就比较简单了,将上面那一层正则判断去掉即可,由于这个是在fwk中的方法,为了不影响其他模块的调用。你也可以将整个方法复制到nfc模块中,然后将正则判断去掉。

  

<强> 2。传输的文件名包含特殊字符时,导致传输失败

  

比如文件名包含“#”时,会导致传输失败。其实这个问题里面包含两个问题:
  (1)。从文件管理器中通过Android梁分享时,直接传输失败。
  其实,这个问题跟上面1中的问题也是类似的:

        框架核心android webkit \ \ java \ \基础\ \ MimeTypeMap.java   之前      

 Android梁文件传输失败分析与解决方法

  

假如将1中的问题修复了,即下面的正则判断去除了,最后还是返回零的mimeType,导致传输失败。修复方法也比较简单,将上面的“#”处理代码去除,同时也需要将下面的正则判断去除。

  

(2)。修复了(1)中的问题后,测试了几下发现不管是通过文件管理器还是图库都提示传输失败,不过跟上面不一样的是:
  通知栏进度显示是传输完毕了的,已经100%了,但是过了一会儿接收端就提示传输失败了,发送端显示传输成功。

  

通过查看,文件也确实是传到了接收端,不过不是在梁目录下,而是在蓝牙目录下。我们都知道,Android梁传输文件其实底层是通过蓝牙来实现传输的。只不过接收端和发送端并不需要蓝牙的配对,而是通过nfc来建立双方的连接。

  

分析代码流程发现,文件首先传输到了蓝牙文件夹下,然后通过renameTo将传输到蓝牙目录中的文件移动到梁目录下。

        包\程序\ Nfc \ src \ com \ android \ Nfc \梁\ BeamTransferManager.java   之前      

 Android梁文件传输失败分析与解决方法

  

所以怀疑在renameTo的时候出现了异常,日志中也印证了这一点。而且srcFile打印的文件路径中将文件名中的“#”去除了,所以在蓝牙目录下就找不到这个文件了,renameTo当然会失败。

  

通过一步步跟踪传递uri参数的地方,发现蓝牙模块通过广播发送过来的uri是纯粹的文件路径,/存储/模拟/0/蓝牙/weeww # jpg。所以getScheme返回的是null,调用uri.getPath的时候,自动将文件路径中的“#”去除了。

        包\程序\ Nfc \ src \ com \ android \ Nfc \梁\ BeamStatusReceiver.java   之前      

 Android梁文件传输失败分析与解决方法

  

解决方法也比较简单,我们不调用uri.getPath就行了,直接将uriString传进构造文件的参数中。

Android梁文件传输失败分析与解决方法