【问题标题】:Share image without WRITE_EXTERNAL_STORAGE?在没有 WRITE_EXTERNAL_STORAGE 的情况下共享图像?
【发布时间】:2015-03-23 23:55:45
【问题描述】:

有没有办法使用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);

当 uri 指向 getExternalFilesDir() 中的文件时,共享工作正常,但我更喜欢不需要 WRITE_EXTERNAL_STORAGE 权限的解决方案,以供关注隐私的用户使用。

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

  1. 文件提供者:

    uri = FileProvider.getUriForFile(context, authority, imageFile);
    

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

  1. 上传到网络服务器:

    uri = Uri.parse("http://my-image-host.com/screenshot.jpg");
    

这到处都失败了,导致一些(Google+)崩溃。

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

  1. 注入媒体商店:

    uri = MediaStore.Images.Media.insertImage(contentResolver, bitmap, name, description);
    

这会引发 SecurityException,说明它需要 WRITE_EXTERNAL_STORAGE。

我还缺少其他方法吗?

【问题讨论】:

  • 尝试将FileProvider 与我的LegacyCompatCursorWrapper 混在一起,看看你是否有更好的运气。该包装器是my CWAC-Provider project 的一部分,here is a sample app 显示了它与FileProvider 的一个小子类一起使用。如果它对 Google+ 没有帮助,请告诉我(例如,CWAC-Provider 跟踪器上的问题)。

标签: android android-intent


【解决方案1】:

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

要与FileProvider结合使用,添加my CWAC-Provider library作为依赖,然后创建自己的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)));
  }
}

所有这一切都是将FileProvider query() 结果包装成LegacyCompatCursorWrapper。您的应用程序配置的其余部分与直接使用 FileProvider 相同(例如,<meta-data> 元素),除了您的 <activity> 元素的 android:name 属性将指向您自己的类。您可以在 this sample app 中看到这一点。

【讨论】:

  • 当以下链接中解释的内容正常工作时,为什么我们应该使用 CWAC 库。是不是像某些设备一样无法使用? medium.com/androidsrc/…
  • @nizam.sp:这在答案和the answer that I linked to 中都有介绍。许多应用程序认为任何带有content 方案的Uri 都必须有一个_DATA 列。这是不正确的,而且从来都不是正确的,但它适用于 MediaStore,这是几年前一些开发人员关心的全部内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-04
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
  • 2012-08-22
相关资源
最近更新 更多