修改文件:
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