Android Bluetooth 文件接收路径修改方法

修改文件:

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

posted @ 2014-12-31 09:32  回忆安在  阅读(603)  评论(0编辑  收藏  举报