修改文件:

packages/apps/Bluetooth/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java

相关代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
public static BluetoothOppReceiveFileInfo generateFileInfo(Context context, int id) {
 
    ContentResolver contentResolver = context.getContentResolver();
    Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + id);
    String filename = null, hint = null, mimeType = null;
    long length = 0;
    Cursor metadataCursor = null;
    try {
        metadataCursor = contentResolver.query(contentUri, new String[] {
            BluetoothShare.FILENAME_HINT, BluetoothShare.TOTAL_BYTES, BluetoothShare.MIMETYPE
            }, null, null, null);
    } catch (SQLiteException e) {
        if (metadataCursor != null) {
            metadataCursor.close();
        }
        metadataCursor = null;
        Log.e(Constants.TAG, "generateFileInfo: " + e);
    } catch (CursorWindowAllocationException e) {
        metadataCursor = null;
        Log.e(Constants.TAG, "generateFileInfo: " + e);
    }
 
    if (metadataCursor != null) {
        try {
            if (metadataCursor.moveToFirst()) {
                hint = metadataCursor.getString(0);
                length = metadataCursor.getLong(1);
                mimeType = metadataCursor.getString(2);
            }
        } finally {
            metadataCursor.close();
            if (V) Log.v(Constants.TAG, "Freeing cursor: " + metadataCursor);
            metadataCursor = null;
        }
    }
 
    File base = null;
    StatFs stat = null;
 
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        String root = Environment.getExternalStorageDirectory().getPath();
        base = new File(root + Constants.DEFAULT_STORE_SUBDIR);
        if (!base.isDirectory() && !base.mkdir()) {
            if (D) Log.d(Constants.TAG, "Receive File aborted - can't create base directory "
                        + base.getPath());
            return new BluetoothOppReceiveFileInfo(BluetoothShare.STATUS_FILE_ERROR);
        }
        stat = new StatFs(base.getPath());
    } else {
        if (D) Log.d(Constants.TAG, "Receive File aborted - no external storage");
        return new BluetoothOppReceiveFileInfo(BluetoothShare.STATUS_ERROR_NO_SDCARD);
    }
 
    /*
     * Check whether there's enough space on the target filesystem to save
     * the file. Put a bit of margin (in case creating the file grows the
     * system by a few blocks).
     */
    if (stat.getBlockSize() * ((long)stat.getAvailableBlocks() - 4) < length) {
        if (D) Log.d(Constants.TAG, "Receive File aborted - not enough free space");
        return new BluetoothOppReceiveFileInfo(BluetoothShare.STATUS_ERROR_SDCARD_FULL);
    }
 
    filename = choosefilename(hint);
    if (filename == null) {
        // should not happen. It must be pre-rejected
        return new BluetoothOppReceiveFileInfo(BluetoothShare.STATUS_FILE_ERROR);
    }
    String extension = null;
    int dotIndex = filename.lastIndexOf(".");
    if (dotIndex < 0) {
        if (mimeType == null) {
            // should not happen. It must be pre-rejected
            return new BluetoothOppReceiveFileInfo(BluetoothShare.STATUS_FILE_ERROR);
        } else {
            extension = "";
        }
    } else {
        extension = filename.substring(dotIndex);
        filename = filename.substring(0, dotIndex);
    }
 
    if ((filename != null) && (filename.getBytes().length > OPP_LENGTH_OF_FILE_NAME)) {
      /* Including extn of the file, Linux supports 255 character as a maximum length of the
       * file name to be created. Hence, Instead of sending OBEX_HTTP_INTERNAL_ERROR,
       * as a response, truncate the length of the file name and save it. This check majorly
       * helps in the case of vcard, where Phone book app supports contact name to be saved
       * more than 255 characters, But the server rejects the card just because the length of
       * vcf file name received exceeds 255 Characters.
       */
      try {
          byte[] oldfilename = filename.getBytes("UTF-8");
          byte[] newfilename = new byte[OPP_LENGTH_OF_FILE_NAME];
          System.arraycopy(oldfilename, 0, newfilename, 0, OPP_LENGTH_OF_FILE_NAME);
          filename = new String(newfilename, "UTF-8");
      } catch (UnsupportedEncodingException e) {
          Log.e(Constants.TAG, "Exception: " + e);
      }
      if (D) Log.d(Constants.TAG, "File name is too long. Name is truncated as: " + filename);
    }
 
    filename = base.getPath() + File.separator + filename;
    // Generate a unique filename, create the file, return it.
    String fullfilename = chooseUniquefilename(filename, extension);
 
    if (!safeCanonicalPath(fullfilename)) {
        // If this second check fails, then we better reject the transfer
        return new BluetoothOppReceiveFileInfo(BluetoothShare.STATUS_FILE_ERROR);
    }
    if (V) Log.v(Constants.TAG, "Generated received filename " + fullfilename);
 
    if (fullfilename != null) {
        try {
            new FileOutputStream(fullfilename).close();
            int index = fullfilename.lastIndexOf('/') + 1;
            // update display name
            if (index > 0) {
                String displayName = fullfilename.substring(index);
                if (V) Log.v(Constants.TAG, "New display name " + displayName);
                ContentValues updateValues = new ContentValues();
                updateValues.put(BluetoothShare.FILENAME_HINT, displayName);
                context.getContentResolver().update(contentUri, updateValues, null, null);
 
            }
            return new BluetoothOppReceiveFileInfo(fullfilename, length, new FileOutputStream(
                    fullfilename), 0);
        } catch (IOException e) {
            if (D) Log.e(Constants.TAG, "Error when creating file " + fullfilename);
            return new BluetoothOppReceiveFileInfo(BluetoothShare.STATUS_FILE_ERROR);
        }
    } else {
        return new BluetoothOppReceiveFileInfo(BluetoothShare.STATUS_FILE_ERROR);
    }
 
}
 
private static boolean safeCanonicalPath(String uniqueFileName) {
    try {
        File receiveFile = new File(uniqueFileName);
        if (sDesiredStoragePath == null) {
            sDesiredStoragePath = Environment.getExternalStorageDirectory().getPath() +
                Constants.DEFAULT_STORE_SUBDIR;
        }
        String canonicalPath = receiveFile.getCanonicalPath();
 
        // Check if canonical path is complete - case sensitive-wise
        if (!canonicalPath.startsWith(sDesiredStoragePath)) {
            return false;
        }
 
        return true;
    } catch (IOException ioe) {
        // If an exception is thrown, there might be something wrong with the file.
        return false;
    }
}

修改方法:

root 就是存储的根目录。

如果需要将其修改之外部存储,修改此处的赋值即可。

如果需要修改子目录,修改base的拼接赋值即可。

此处修改需要注意,如果修改root或者base,则需要给sDesiredStoragePath重新赋值,使其一致,否则会导致safeCanonicalPath()判断会失败。
需要使完整的路径合法,否则无法接收文件。

结伴旅游,一个免费的交友网站:www.jieberu.com

推推族,免费得门票,游景区:www.tuituizu.com

Android Bluetooth 文件接收路径修改方法的更多相关文章

  1. Delphi获取文件名、不带扩展名文件名、文件所在路径、上级文件夹路径的方法

    1.获取不带扩展名的文件名方法,利用ChangeFileExt函数修改传入参数的扩展为空,并不会对文件本身产生变更. ChangeFileExt(ExtractFileName('D:\KK\Test ...

  2. asp.net 客户端上传文件全路径获取方法

    asp.net  获取客户端上传文件全路径方法: eg:F:\test\1.doc 基于浏览器安全问题,浏览器将屏蔽获取客户端文件全路径的方法,只能获取到文件的文件名,如果需要获取全路径则需要另想其他 ...

  3. Delphi XE的firemonkey获取当前文件所在路径的方法

    Delphi XE的firemonkey获取当前文件所在路径的方法 在之前,我们知道有三种方法: ExtractFilePath(ParamStr(0)) ExtractFilePath(Applic ...

  4. IOS获得各种文档文件夹路径的方法

    iphone沙箱模型的有四个目录,各自是什么,永久数据存储一般放在什么位置.得到模拟器的路径的简单方式是什么. documents,tmp.app,Library. (NSHomeDirectory( ...

  5. Xcode增加头文件搜索路径的方法

    Xcode增加头文件搜索路径的方法 以C++工程为例: 在Build Settings 页面中的Search Paths一节就是用来设置头文件路径. 相关的配置项用红框框起来了,共有三个配置项: He ...

  6. android获取各种系统路径的方法

    链接https://blog.csdn.net/qq_26296197/article/details/51909423 通过Environment获取的 Environment.getDataDir ...

  7. Oculus Store游戏下载默认路径修改方法

    最近在测试一款VR游戏,所以在硬件设备上选择了HTC Vive和Oculus两款眼镜.相对而言,HTC安装比较人性化:支持自定义安装路径,而且可在界面更改应用程序下载位置,如图所示: 这下替我节省了不 ...

  8. MAC在Finder栏显示所浏览文件夹路径的方法

    我们在使用MAC时,Finder栏默认只显示当前浏览的文件夹名称,而没有显示访问路径,这个问题该怎么解决呢? 操作步骤: 打开“终端”(应用程序->实用工具),输入以下两条命令: default ...

  9. MySQL参数文件及参数修改方法

    MySQL参数文件: MySQL数据库初始化参数由参数文件来设置,如果没有设置参数文件,mysql就按照系统中参数的默认值来启动. 在windows和linux上,参数文件可以被放在多个位置,数据库启 ...

随机推荐

  1. 12.持久性后门----Ettercap之ARP中毒----RAR/ZIP & linux密码破解----kali上检测rootkits

    持久性后门 生成PHP shell weevely generate 密码 /root/Desktop/404.php 靶机IP/404.php weevely http://192.168.1.10 ...

  2. License开源许可证

  3. window 下python2.7与python3.5两版本共存设置

    分别下载两个版本的Python,安装. (1)在Path环境变量中检查以下4个变量(Path中的环境变量是以分号隔开的): 1.c:\Python27 2.c:\Python27\Scripts 3. ...

  4. [Web 前端] 033 Vue 的简单使用

    目录 0. 方便起见,定个轮廓 1. v-model 举例 2. v-for 举例 3. v-if 举例 4. 事件绑定 举例 5. v-show 举例 0. 方便起见,定个轮廓 不妨记下方的程序为 ...

  5. Spark启动流程(Standalone)- master源码

    Master源码 package org.apache.spark.deploy.master //伴生类 private[deploy] class Master( override val rpc ...

  6. 一分钟搭建 Web 版的 PHP 代码调试利器

    一.背景   俗话说:"工欲善其事,必先利其器".作为一门程序员,我们在工作中,经常需要调试某一片段的代码,但是又不想打开繁重的 IDE (代码编辑器).使用在线工具调试代码有时有 ...

  7. 解决intellij idea控制台中文乱码

    乱码原因: 1.系统语言:英文 英文系统下遇到乱码问题,分析了程序执行参数如下: ps -ef | grep java 执行后得到如下的结果,省略了classpath: /System/Library ...

  8. angularJS(二):作用域$scope、控制器、过滤器

    app.controller创建控制器 一.作用域 Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带. Scope 是一个对象,有可用的方法和属性. ...

  9. Linux基础命令四

    iptables iptables -F:关闭防火墙 crontab -l查看定时任务 crontab -e :编辑定时任务 log日志相关: ls  /var/log:查看日志 du -sh  /v ...

  10. 2014-04-27 南江滨大道 6KM 晴

    33分41秒,6.03公里,慢速跑,中间有停了几次拍照 天气不错,多云 人,不多 不知道这货叫啥 2个大人3个小孩,跳绳,小时候的回忆,啊哈 老中少三代,捡风筝也是一种幸福 一家三口,江滨散步,惬意至 ...