没有WRITE_EXTERNAL_STORAGE分享图片?

Dar*_*ell 6 android android-intent

有没有办法用来Intent.ACTION_SEND共享屏幕截图而不需要android.permission.WRITE_EXTERNAL_STORAGE

这是分享部分:

    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.setType("image/jpeg");
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
    Intent chooserIntent = Intent.createChooser(shareIntent, shareTitle);
    startActivity(chooserIntent);
Run Code Online (Sandbox Code Playgroud)

当uri指向文件时getExternalFilesDir(),共享工作正常,但我更喜欢不需要WRITE_EXTERNAL_STORAGE隐私相关用户许可的解决方案.

我尝试了3种不同的方法:

  1. 文件提供者:

    uri = FileProvider.getUriForFile(context, authority, imageFile);
    
    Run Code Online (Sandbox Code Playgroud)

这适用于某些共享样式(Gmail)但不适用于其他共享样式(Google+).

  1. 上传到Web服务器:

    uri = Uri.parse("http://my-image-host.com/screenshot.jpg");
    
    Run Code Online (Sandbox Code Playgroud)

这在所有地方都失败了,一些人(Google+)崩溃了.

(我怀疑如果我使用每个社交网络API而不是自己实现共享逻辑,这可能会有效chooserIntent)

  1. 注入Media Store:

    uri = MediaStore.Images.Media.insertImage(contentResolver, bitmap, name, description);
    
    Run Code Online (Sandbox Code Playgroud)

这会引发SecurityException,解释它需要WRITE_EXTERNAL_STORAGE.

我还缺少其他方法吗?

Com*_*are 3

基于Stefan Rusek 的工作,我创建了LegacyCompatCursorWrapper,旨在帮助提高FileProvider(和其他ContentProvider实现)与正在查找_DATA列但未找到列的客户端应用程序的兼容性。该_DATA模式最初由 所使用MediaStore,但应用程序尝试引用该列从来都不是一个好主意。

要将其与 结合使用FileProvider,请将我的 CWAC-Provider 库添加为依赖项,然后创建您自己的 的子类FileProvider,例如:

/***
 Copyright (c) 2015 CommonsWare, LLC
 Licensed under the Apache License, Version 2.0 (the "License"); you may not
 use this file except in compliance with the License. You may obtain a copy
 of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License.

 From _The Busy Coder's Guide to Android Development_
 http://commonsware.com/Android
 */

package com.commonsware.android.cp.v4file;

import android.database.Cursor;
import android.net.Uri;
import android.support.v4.content.FileProvider;
import com.commonsware.cwac.provider.LegacyCompatCursorWrapper;

public class LegacyCompatFileProvider extends FileProvider {
  @Override
  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    return(new LegacyCompatCursorWrapper(super.query(uri, projection, selection, selectionArgs, sortOrder)));
  }
}
Run Code Online (Sandbox Code Playgroud)

这一切所做的就是将FileProvider query()结果包装在LegacyCompatCursorWrapper. FileProvider应用程序配置的其余部分与直接使用(例如元素)相同<meta-data>,只是<activity>元素的android:name属性将指向您自己的类。您可以在此示例应用程序中看到它的实际效果。