从 Android 中的资产共享图像时出现问题
Problems sharing an image from assets in Android
关于如何从 Android 的资产文件夹发送和共享图像(或文件)有一些文档和支持。
基本上,我得到了这些链接的支持:
- android share images from assets folder
- 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);
我可以成功看到我的选择器。
我的主要问题是
我可以在某些应用程序中共享我的照片,但不能在其他应用程序中共享。例如:
我可以分享照片的应用程序:
Google 环聊
推特
WhatsApp
Skype(卡在 "sending")
Instagram
Dropbox
无法分享图片的应用:
Gmail 收件箱
Gmail
任何图像编辑应用程序
消息
松弛
领英
列表项
Hipchat
Messenger(通过 Facebook)
脸书
我无法分享的应用程序有什么问题吗?还是我在代码上做错了什么?也许是 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
必须从 File
和 Uri.fromFile(File file)
解析出来,然后一切正常!
关于如何从 Android 的资产文件夹发送和共享图像(或文件)有一些文档和支持。
基本上,我得到了这些链接的支持:
- android share images from assets folder
- 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);
我可以成功看到我的选择器。
我的主要问题是
我可以在某些应用程序中共享我的照片,但不能在其他应用程序中共享。例如: 我可以分享照片的应用程序:
Google 环聊
推特
WhatsApp
Skype(卡在 "sending")
Instagram
Dropbox
无法分享图片的应用:
Gmail 收件箱
Gmail
任何图像编辑应用程序
消息
松弛
领英
列表项
Hipchat
Messenger(通过 Facebook)
脸书
我无法分享的应用程序有什么问题吗?还是我在代码上做错了什么?也许是 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
必须从 File
和 Uri.fromFile(File file)
解析出来,然后一切正常!