android从资源文件夹共享图像

我正在尝试从我的资产文件夹共享图片。 我的代码是:

Intent share = new Intent(Intent.ACTION_SEND); share.setType("image/jpg"); share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///assets/myImage.jpg")); startActivity(Intent.createChooser(share, "Share This Image")); 

但它不起作用。 你有什么想法?

Solutions Collecting From Web of "android从资源文件夹共享图像"

可以通过自定义ContentProvider共享资产文件夹中的文件(包括图像)

您需要扩展ContentProvider ,将其注册到清单中并实现openAssetFile方法。 然后您可以通过Uri评估资产

  @Override public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { AssetManager am = getContext().getAssets(); String file_name = uri.getLastPathSegment(); if(file_name == null) throw new FileNotFoundException(); AssetFileDescriptor afd = null; try { afd = am.openFd(file_name); } catch (IOException e) { e.printStackTrace(); } return afd; } 

这个博客解释了一切:
http://nowherenearithaca.blogspot.co.uk/2012/03/too-easy-using-contentprovider-to-send.html

基本上,这是清单:

 <provider android:name="yourclass.that.extendsContentProvider" android:authorities="com.yourdomain.whatever"/> 

内容提供者类有这样的:

 @Override public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { AssetManager am = getContext().getAssets(); String file_name = uri.getLastPathSegment(); 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); } 

而调用代码这样做:

 Uri theUri = Uri.parse("content://com.yourdomain.whatever/someFileInAssetsFolder"); Intent theIntent = new Intent(Intent.ACTION_SEND); theIntent.setType("image/*"); theIntent.putExtra(Intent.EXTRA_STREAM,theUri); theIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Subject for message"); theIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Body for message"); startActivity(theIntent); 

补充@Cris Nash的回答:

您将需要像上面的示例类的重写方法:

 package com.android.example; import android.content.ContentProvider; import android.net.Uri; import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import java.io.FileNotFoundException; import android.content.ContentValues; import android.database.Cursor; import java.io.IOException; import android.os.CancellationSignal; public class AssetsProvider extends ContentProvider { @Override public AssetFileDescriptor openAssetFile( Uri uri, String mode ) throws FileNotFoundException { Log.v( TAG, "AssetsGetter: Open asset file" ); AssetManager am = getContext( ).getAssets( ); String file_name = uri.getLastPathSegment( ); 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; } @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; } } 

我需要重写两次查询方法。 在你的androidmanifest.xml文件中添加以下代码行:

 <provider android:name="com.android.example.AssetsProvider" android:authorities="com.android.example" android:grantUriPermissions="true" android:exported="true" /> 

这样,所有的工作就像一个魅力:D

许多应用程序要求您提供图像的名称和大小。 所以这是一个改进的代码(使用Google的FileProvider代码作为例子):

 public class AssetsProvider extends ContentProvider { private final static String LOG_TAG = AssetsProvider.class.getName(); private static final String[] COLUMNS = { OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE }; @Override public boolean onCreate() { return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { /** * Source: {@link FileProvider#query(Uri, String[], String, String[], String)} . */ if (projection == null) { projection = COLUMNS; } final AssetManager am = getContext().getAssets(); final String path = getRelativePath(uri); long fileSize = 0; try { final AssetFileDescriptor afd = am.openFd(path); fileSize = afd.getLength(); afd.close(); } catch(IOException e) { Log.e(LOG_TAG, "Can't open asset file", e); } final String[] cols = new String[projection.length]; final Object[] values = new Object[projection.length]; int i = 0; for (String col : projection) { if (OpenableColumns.DISPLAY_NAME.equals(col)) { cols[i] = OpenableColumns.DISPLAY_NAME; values[i++] = uri.getLastPathSegment(); } else if (OpenableColumns.SIZE.equals(col)) { cols[i] = OpenableColumns.SIZE; values[i++] = fileSize; } } final MatrixCursor cursor = new MatrixCursor(cols, 1); cursor.addRow(values); return cursor; } @Override public String getType(Uri uri) { /** * Source: {@link FileProvider#getType(Uri)} . */ final String file_name = uri.getLastPathSegment(); final int lastDot = file_name.lastIndexOf('.'); if (lastDot >= 0) { final String extension = file_name.substring(lastDot + 1); final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); if (mime != null) { return mime; } } return "application/octet-stream"; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } @Override public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { final AssetManager am = getContext().getAssets(); final String path = getRelativePath(uri); if(path == null) { throw new FileNotFoundException(); } AssetFileDescriptor afd = null; try { afd = am.openFd(path); } catch(IOException e) { Log.e(LOG_TAG, "Can't open asset file", e); } return afd; } private String getRelativePath(Uri uri) { String path = uri.getPath(); if (path.charAt(0) == '/') { path = path.substring(1); } return path; } } 

AFAIK,没有办法从assets文件夹共享图片。 但是可以从res文件夹共享资源。

要从资产文件夹共享,我只能推荐cwac提供程序库(StreamProvider)。

在避免开发自己的内容提供商,它增加了一些反复无常的旧应用程序的支持(检查USE_LEGACY_CURSOR_WRAPPER )。