当前位置: 代码迷 >> Android >> Android Bluetooth 文件接收途径修改方法
  详细解决方案

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

热度:526   发布时间:2016-04-28 03:06:42.0
Android Bluetooth 文件接收路径修改方法

修改文件:

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


相关代码片段:

    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()判断会失败。
需要使完整的路径合法,否则无法接收文件。


  相关解决方案