0

我正在尝试将文件从通用托管文件服务作为 Dropbox/Drive/Onedrive 复制到我设备中的特定路径。

我创建了一个工作示例来复制 jpg 文件,但我想要创建的是用于复制以下类型的版本:.docx、.pdf、.pptx、.jpg、.jpeg、.png、.gif、.mp3、 .mp4、.xlsx。

我需要做什么?如何修改我的代码?

谢谢

// the flow start from here
public void newFile() {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select file"), NEW_FILE_PRIVATE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == NEW_FILE_PRIVATE && resultCode == Activity.RESULT_OK) {
        if (data != null) {
            Uri currentUri = null;
            currentUri = data.getData();

            String contentString = currentUri.toString();

            if (contentString.contains("com.dropbox.android") ||
                contentString.contains("com.microsoft.skydrive") ||
                contentString.contains("com.google.android.apps.docs.storage")) {
                try {
                    copyFileContent(currentUri);
                } catch (IOException e) {
                    Log.e("cloud error", "error");
                }
            }
        }
    }
}

private String copyFileContent(Uri uri) throws IOException {

    ParcelFileDescriptor pFileDescriptor = getContentResolver().openFileDescriptor(uri, "r");

    FileDescriptor fileDescriptor = pFileDescriptor.getFileDescriptor();

    Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);

    pFileDescriptor.close();

    /* temporary path */
    String extension = getMimeType(getApplicationContext(), uri);

    String temporaryFilePath = Environment.getExternalStorageDirectory().toString()
            .concat("/").concat("temporaryfile")
            .concat(".").concat(extension);

    File file = new File(temporaryFilePath);

    OutputStream outStream = null;

    try {
        /* make a new bitmap from your file */

        outStream = new FileOutputStream(file);
        image.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.flush();
        outStream.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

    return temporaryFilePath;
}

编辑感谢@CommonsWare,我编写了一个使用此代码获取文件扩展名的解决方案:

public String getExtension(Context context, Uri uri) {
    String extension;

    if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
        final MimeTypeMap mime = MimeTypeMap.getSingleton();
        extension = mime.getExtensionFromMimeType(context.getContentResolver().getType(uri));
    } else {
        extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(uri.getPath())).toString());
    }

    return extension;
}

编辑 2 在@Greenapps 的帮助下,我实现了这个解决方案:

private String copyFileContent(Uri uri) throws IOException {

    InputStream inputStream = getContentResolver().openInputStream(uri);

    /* temporary path */
    String extension = getMimeType(getApplicationContext(), uri);
    String temporaryFilePath = Environment.getExternalStorageDirectory().toString()
        .concat("/").concat("temporaryfile")
        .concat(".").concat(extension);

    OutputStream outStream = new FileOutputStream(temporaryFilePath);

    final byte[] b = new byte[8192];
    for (int r;(r = inputStream.read(b)) != -1;) outStream.write(b, 0, r);

    return temporaryFilePath;
}

是否存在获取文件名而不是将其命名为“临时文件”的方法?

编辑 3

private String copyFileContent(Uri uri) throws IOException {
    InputStream inputStream = getContentResolver().openInputStream(uri);

    String uriString = uri.toString();
    String fileName = "";
    if (!uriString.contains("com.dropbox.android")) {
        Cursor returnCursor = getContentResolver().query(uri, null, null, null, null);
        int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
        returnCursor.moveToFirst();
        fileName = returnCursor.getString(nameIndex);
    } else {
        fileName = uriString.substring(uriString.lastIndexOf("/") + 1, uriString.lastIndexOf("."));
    }

    /* temporary path */
    String extension = getMimeType(getApplicationContext(), uri);
    String temporaryFilePath = Environment.getExternalStorageDirectory().toString()
        .concat("/").concat(egoName)
        .concat("/").concat("PRIVATE")
        .concat("/").concat(fileName)
        .concat(".").concat(extension);

    OutputStream outStream = new FileOutputStream(temporaryFilePath);

    final byte[] b = new byte[8192];
    for (int r;
        (r = inputStream.read(b)) != -1;) outStream.write(b, 0, r);

    return temporaryFilePath;
}
4

2 回答 2

1

大约一天后,很明显您只想复制文件。

通过打开InputStream.

 InputStream is = getContentResolver().openInputStream(uri);

然后从流中读取块并将它们写入FileOutputStream.

由于 DropBox 充满了文件,因此可以在data.getData().getPath(). 但是使用显示名称列是一个更好的主意。

于 2016-12-13T11:12:32.997 回答
0

如何使用 getContentResolver().openFileDescriptor() 从 Storage Access Framework 获取文件名和扩展名?

没有文件名或扩展名。您正在处理内容,而不是文件。您可以获得“显示名称”(例如,DocumentFilegetName()),但这不必是文件名或包含任何类型的文件扩展名。

如果我的文件是 jpg,则此代码有效,但我要做的是为每种类型的文件找到解决方案,而不使用 intent.setType("image/*") 或对其进行概括

DocumentFile通过和获取内容的 MIME 类型getType()。用于MimeTypeMap帮助您将其转换为候选文件扩展名。

于 2016-12-12T15:23:09.980 回答