从 Android 中的资产共享图像时出现问题

Problems sharing an image from assets in Android

关于如何从 Android 的资产文件夹发送和共享图像(或文件)有一些文档和支持。

基本上,我得到了这些链接的支持:

  1. android share images from assets folder
  2. http://www.nowherenearithaca.com/2012/03/too-easy-using-contentprovider-to-send.html

和许多类似的。

但无论如何,我使用的代码是:

内容提供商

public class AssetsProvider extends ContentProvider {
private static final String LOGTAG = "MD/AssetsProvider";

@Override
public AssetFileDescriptor openAssetFile( Uri uri, String mode ) throws FileNotFoundException
{
    Log.v(LOGTAG, "AssetsGetter: Open asset file");

    AssetManager am = getContext( ).getAssets( );

    String file_name = uri.getPath().substring(1, uri.getPath().length());
    //String file_name = uri.getLastPathSegment();
    // Neither of the two lines above work for me

    if( file_name == null )
        throw new FileNotFoundException( );

    AssetFileDescriptor afd = null;

    try
    {
        afd = am.openFd( file_name );
    }
    catch(IOException e)
    {
        e.printStackTrace( );
    }

    return afd;//super.openAssetFile(uri, mode);
}

@Override
public String getType( Uri p1 )
{
    // TODO: Implement this method
    return null;
}

@Override
public int delete( Uri p1, String p2, String[] p3 )
{
    // TODO: Implement this method
    return 0;
}

@Override
public Cursor query( Uri p1, String[] p2, String p3, String[] p4, String p5 )
{
    // TODO: Implement this method
    return null;
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal )
{
    // TODO: Implement this method
    return super.query( uri, projection, selection, selectionArgs, sortOrder, cancellationSignal );
}

@Override
public Uri insert( Uri p1, ContentValues p2 )
{
    // TODO: Implement this method
    return null;
}

@Override
public boolean onCreate( )
{
    // TODO: Implement this method
    return false;
}

@Override
public int update( Uri p1, ContentValues p2, String p3, String[] p4 )
{
    // TODO: Implement this method
    return 0;
}
}

我不太喜欢,因为它需要 API 16.

ANDROID 清单(在 <application> 标签内)

<provider
    android:name="package.name.utils.AssetsProvider"
    android:authorities="package.name"
    android:grantUriPermissions="true"
    android:exported="true" />

共享图像的代码

Uri theUri = Uri.parse("content://package.name/share_picture.png");
Intent theIntent = new Intent(Intent.ACTION_SEND);
theIntent.setType("image/*");
theIntent.putExtra(Intent.EXTRA_STREAM,theUri);
theIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"");
theIntent.putExtra(android.content.Intent.EXTRA_TEXT, "");
startActivity(theIntent);

我可以成功看到我的选择器。

我的主要问题是

我可以在某些应用程序中共享我的照片,但不能在其他应用程序中共享。例如: 我可以分享照片的应用程序:

无法分享图片的应用:

我无法分享的应用程序有什么问题吗?还是我在代码上做错了什么?也许是 setType 函数?

提前致谢。

此致。

拉斐尔.


从文件共享图像时也会出现此问题,因此问题与资产无关:

今天早上我做了这个测试:

    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    Uri phototUri = Uri.parse(folderToSaveFiles+relativeNameSharePicture);

    shareIntent.setData(phototUri);
    shareIntent.setType("image/png");
    shareIntent.putExtra(Intent.EXTRA_STREAM, phototUri);
    startActivity(Intent.createChooser(shareIntent, "Share Via"));

同样的事情发生了!!

您是否尝试过在 getType() 方法中返回不同于 null 的内容? 某些应用程序可能会检查它,如果无法识别,它们将不会接受您发送的内容。 (你可以很容易地在那里记录一些东西,至少看看其他应用程序是否正在调用它)

最简单的答案是使用 my StreamProvider,它会为您处理所有这些。如果这不适用于您引用的某些应用程序,请提交带有症状的问题(例如,来自这些应用程序的堆栈跟踪)。但是,我没有将 AssetFileDescriptor 用于资产(对于兼容设备),这是我要更改的待办事项列表。

下一个最简单的答案是将资产复制到内部存储,然后 use FileProvider, along with my LegacyCompatCursorWrapper, as seen in this sample app

如果您想坚持使用您的代码:

第 1 步:实现一个真正的 getType() 方法,return MIME 类型。

步骤 #2:实现一个真正的 query() 方法,一个处理 OpenableColumns 的方法,最好使用我的 LegacyCompatCursorWrapper 或其他 deals with poorly-written clients.

第 3 步:Add FLAG_GRANT_READ_URI_PERMISSION 到您的 Intent 并将 android:exported 更改为 false

第 4 步:摆脱 EXTRA_TEXT,因为 ACTION_SEND 协议支持 EXTRA_TEXT EXTRA_STREAM,不是两者。

主要问题是 Uri 必须从 FileUri.fromFile(File file) 解析出来,然后一切正常!