ilechooser选择从GMail下载的Word文件时崩溃的应

ilechooser选择从GMail下载的Word文件时崩溃的应

本文介绍了Filechooser选择从GMail下载的Word文件时崩溃的应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用文件选择器来选择从GMail下载的WORD文件,这会导致应用程序崩溃.这是我的代码段:

I am using a file chooser to pick a WORD file downloaded from GMail, it causes the app crashed.Here's my code segment:

==文件选择器代码==

== file chooser code ==

Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
intent.addCategory(Intent.CATEGORY_OPENABLE);
//sets the select file to all types of files
String [] mimeTypes = {"application/pdf", "application/msword",
"application/vnd.openxmlformats
officedocument.wordprocessingml.document"};
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
activity.startActivityForResult(Intent.createChooser(intent, "Select
File"), PICK_FILE_REQUEST);

== onActivityResult ==

== onActivityResult ==

Uri selectedFileUri = data.getData();
String selectedFilePath = FilePath.getPath(getActivity(),
selectedFileUri);

== FilePath.getPath()==

== FilePath.getPath() ==

...
// DownloadsProvider

final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri =
ContentUris.withAppendedId(Uri.parse("content://downloads
/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);

== getDataColumn()==

== getDataColumn() ==

public static String getDataColumn(Context context, Uri uri,
     String selection, String[]    selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = { column };

    try {
        cursor = context.getContentResolver().query(uri, projection,
                selection, selectionArgs, null);
        if (cursor != null && cursor.moveToFirst()) {
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

selectedFilePath 具有以下值:content://com.android.providers.downloads.documents/document/164,FilePath.getPath()中的 contentUri 有这个价值.当它进入getDataColumn()方法时,执行"query()"后光标为空.

The selectedFilePath has this value: content://com.android.providers.downloads.documents/document/164, the contentUri in FilePath.getPath() also has this value. When it goes in getDataColumn() method, the cursor is null after executing "query()".

尝试了以下方法:1)如果我将相同的WORD文件直接放入下载"文件夹,然后从文件选择器的下载"链接中选择它,则没有问题.似乎以某种方式通过GMail并从GMail下载会导致问题. 2)仍从GMail和下载"文件夹中下载的文件,如果我通过内部存储"->下载"(即绝对路径)进行选择,则该代码可以正常工作,因为代码经过了不同的流程(上面未显示).

Tried those: 1) If I put the same WORD file direct to the "Download" folder and pick it from "Downloads" link from the file chooser, I have no issue. It seems that somehow going through GMail and downloading from GMail causes problem. 2) File still downloaded from GMail and in Download folder, if I pick it through Internal storage->Download (i.e, absolute path), it works since the code goes through different flow (which is not shown above).

我想知道我在代码中错过了处理从GMail下载的文件的地方吗?

I am wondering where I missed in the code to handle the file downloaded from GMail?

提前谢谢!

电话是Galaxy S9,Android 9.

The Phone is Galaxy S9, android 9.

推荐答案

经过一些搜索和实验后,最终从InputStream检索文件名和内容,而不是尝试获取文件的路径.这是代码段:

After some search and experiment, it ends up retrieving file name and content from InputStream instead of trying to get the path of the file. Here's the code segment:

1)获取文件详细信息:

1) get file details:

Uri selectedFileUri = data.getData();
FileDetail fileDetail = FilePath.getFileDetailFromUri(getActivity(), selectedFileUri);
String fileName = fileDetail.getFileName();
int fileSize = (int)fileDetail.getFileSize();

这是FileDetail.java:

Here's the FileDetail.java:

public class FileDetail {
    // fileSize.
    public String fileName;
    // fileSize in bytes.
    public long fileSize;

    public FileDetail() {

    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public long getFileSize() {
        return fileSize;
    }

    public void setFileSize(long fileSize) {
        this.fileSize = fileSize;
    }
}

在FilePath.java中:

In FilePath.java:

public static FileDetail getFileDetailFromUri(Context context, Uri uri) {
        FileDetail fileDetail = null;
        if (uri != null) {
            fileDetail = new FileDetail();
            // File Scheme.
            if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
                File file = new File(uri.getPath());
                fileDetail.setFileName(file.getName());
                fileDetail.setFileSize(file.length());
            }
            // Content Scheme.
            else if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
                Cursor returnCursor =
                        context.getContentResolver().query(uri, null, null, null, null);
                if (returnCursor != null && returnCursor.moveToFirst()) {
                    int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                    int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
                    fileDetail.setFileName(returnCursor.getString(nameIndex));
                    fileDetail.setFileSize(returnCursor.getLong(sizeIndex));
                    returnCursor.close();
                }
            }
        }
        return fileDetail;
    }

2)获取文件内容:

InputStream is = cr.openInputStream(selectedFileUri);
 byte[] fileContent = new byte[fileSize];
 is.read(fileContent);

我从互联网上找到了这些代码,但没有跟踪它们的位置.使用文件名& FileDetail.java中的filesize和"filecontent"字节数组中的文件内容,我现在拥有所有需要的信息.

I found those codes from internet and didn't keep track of where they are. With Filename & filesize in FileDetail.java and the file content in "filecontent" byte arrays, I have all information I need now.

这篇关于Filechooser选择从GMail下载的Word文件时崩溃的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-26 16:32