Android无法打开Gmail附件

时间:2014-09-25 10:36:20

标签: android gmail attachment

我想用我的应用程序打开pdfs附件。

我已经设置了intent-filter

<intent-filter android:label="@string/label" >
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:mimeType="application/pdf" />
            <data android:mimeType="image/*" />
        </intent-filter>
        <intent-filter android:label="@string/label" >
            <action android:name="android.intent.action.SHARE" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:mimeType="application/pdf" />
            <data android:mimeType="image/*" />
        </intent-filter>

它在Android 4.4设备上运行良好但在4.2.2上我得到以下异常:

java.lang.SecurityException: Permission Denial: opening provider com.google.android.gm.provider.MailProvider from ProcessRecord{2120ac60 21661:com.some.app.package/u0a10113} (pid=21661, uid=10113) requires com.google.android.gm.permission.READ_GMAIL or com.google.android.gm.permission.WRITE_GMAIL

我尝试添加所有这些权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.android.email.permission.READ_ATTACHMENT"/>
<uses-permission android:name="com.google.android.gm.permission.READ_GMAIL"/>
<uses-permission android:name="com.google.android.gm.permission.READ_CONTENT_PROVIDER"/>

奇怪的是,如果我尝试加载相同的附件而不是使用gmail我使用默认的邮件应用程序,使用相同的帐户,我没有错误。

但仍然得到相同的异常我该怎么办?感谢

编辑:

我还添加了这两个:

 <uses-permission android:name="com.google.android.providers.gmail.permission.READ_GMAIL"/> 
 <uses-permission android:name="com.google.android.providers.gmail.permission.WRITE_GMAIL"/>

仍然没有运气

EDIT2:

这就是我触发异常的方式:

public static byte[] getBytesFromUri(Uri uri, Context appCtx) {

    ByteArrayOutputStream byteBuffer = null;
    InputStream inputStream = null;

    try {
        inputStream = appCtx.getContentResolver().openInputStream(uri); //crash here
        byteBuffer = new ByteArrayOutputStream();
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        int len = 0;
        while ((len = inputStream.read(buffer)) != -1) {
            byteBuffer.write(buffer, 0, len);
        }
        inputStream.close();
        inputStream=null;
        return byteBuffer.toByteArray();
    } catch (IOException e) {
        log.e(TAG, "error retrieving bytearray from uri "+uri);
        e.printStackTrace();
    }

    return null;
}

EDIT3:

以下是我如何获取文件uri:

Uri fileUri = null;
    if (Intent.ACTION_VIEW.equals(intent.getAction())) {
        fileUri = intent.getData();
        intent.setData(null);
    } else if (Intent.ACTION_SEND.equals(intent.getAction())) {
        fileUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
        intent.removeExtra(Intent.EXTRA_STREAM);
    }

编辑4 对于greenapps: 这是uris:

的Gmail

content://gmail-ls/gmail.account@gmail.com/messages/76/attachments/0.1/BEST/false

电子邮件

 file:///storage/emulated/0/Android/data/com.android.email/cache/test_file.pdf

所以uris是不同的,但它们也在4.4设备上,它仍然有效

1 个答案:

答案 0 :(得分:0)

使用以下代码: 意图过滤器

  <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:mimeType="application/octet-stream" />

            <data android:host="*" />
            <data android:scheme="smb" />
            <data android:scheme="http" />
            <data android:scheme="https" />
            <data android:pathPattern=".*\\.pdf" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:mimeType="application/octet-stream" />

            <data android:host="*" />
            <data android:scheme="smb" />
            <data android:scheme="http" />
            <data android:scheme="https" />
            <data android:mimeType="application/pdf" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:mimeType="application/octet-stream" />

            <data android:host="*" />
            <data android:scheme="file" />
            <data android:scheme="content" />
            <!-- Workaround to match files in paths with dots in them, like /sdcard/my.folder/test.pdf -->
            <data android:pathPattern=".*\\.pdf" />
            <data android:pathPattern=".*\\..*\\.pdf" />
            <data android:pathPattern=".*\\..*\\..*\\.pdf" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:mimeType="application/octet-stream" />

            <data android:host="*" />
            <data android:scheme="file" />
            <data android:scheme="content" />
            <data android:mimeType="application/pdf" />
        </intent-filter>

在活动类中使用CONTENT RESOLVER

URI转换为数据
 TextView fileNameTextView;
private File file;

 Intent intent = getIntent();
    InputStream is = null;
    FileOutputStream os = null;
    String fullPath = null;

    try {
        String action = intent.getAction();
        if (!Intent.ACTION_VIEW.equals(action)) {
            return;
        }

        Uri uri = intent.getData();
        String scheme = uri.getScheme();
        String name = null;

        if (scheme.equals("file")) {
            List<String> pathSegments = uri.getPathSegments();
            if (pathSegments.size() > 0) {
                name = pathSegments.get(pathSegments.size() - 1);
            }
        } else if (scheme.equals("content")) {
            Cursor cursor = getContentResolver().query(uri, new String[] {
                    MediaStore.MediaColumns.DISPLAY_NAME
            }, null, null, null);
            cursor.moveToFirst();
            int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
            if (nameIndex >= 0) {
                name = cursor.getString(nameIndex);
            }
        } else {
            return;
        }

        if (name == null) {
            return;
        }

        int n = name.lastIndexOf(".");
        String fileName, fileExt;

        if (n == -1) {
            return;
        } else {
            fileName = name.substring(0, n);
            fileExt = name.substring(n);
          /*  if (!fileExt.equals(".gcsb")) {
                return;
            }*/
        }

        fullPath = ""/* create full path to where the file is to go, including name/ext */;

        String filenm = fileName + fileExt;
        file = new File(getCacheDir(), filenm);



        is = getContentResolver().openInputStream(uri);
        os = new FileOutputStream(file.getPath());

        byte[] buffer = new byte[4096];
        int count;
        while ((count = is.read(buffer)) > 0) {
            os.write(buffer, 0, count);
        }
        os.close();
        is.close();


        fileNameTextView.setText(fullPath);
        pdfView.fromFile(file)
        .enableSwipe(true) // allows to block changing pages using swipe
        .swipeHorizontal(false)
        .enableDoubletap(true)
        .password("123456")
        .defaultPage(0)
        .load();
        Log.e("TAG", "===onfile path: "+file.getAbsolutePath() );
        Log.e("TAG", "===onFile name: "+file.getName() );


    } catch (Exception e) {
        if (is != null) {
            try {
                is.close();
            } catch (Exception e1) {
            }
        }
        if (os != null) {
            try {
                os.close();
            } catch (Exception e1) {
            }
        }
        if (fullPath != null) {
            File f = new File(fullPath);
            f.delete();
        }
    }