Android обмениваться изображениями из папки активов - PullRequest
19 голосов
/ 04 мая 2011

Я пытаюсь поделиться изображением из папки с активами. Мой код:

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"));

но это не работает. У вас есть идеи?

Ответы [ 6 ]

15 голосов
/ 24 августа 2011

Можно обмениваться файлами (включая изображения) из папки ресурсов через пользовательский ContentProvider

Вам необходимо расширить ContentProvider, зарегистрировать его в манифесте и реализовать метод openAssetFile. Затем вы можете оценить активы через Uri s

    @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;
    }
11 голосов
/ 05 марта 2014

В дополнение к тому, что ответил @ intrepidis :

Вам понадобятся методы переопределения, например, приведенный выше пример класса:

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

10 голосов
/ 29 сентября 2012

Этот блог объясняет все это: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);
3 голосов
/ 13 июля 2015

Многие приложения требуют, чтобы вы указали имя и размер изображения.Итак, вот улучшенный код (на примере кода 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;
    }
}
2 голосов
/ 04 февраля 2016

Для совместного использования из папки активов я могу порекомендовать только библиотеку cwac-provider (StreamProvider).

Среди усилий, направленных на то, чтобы избежать разработки собственного провайдера контента, добавлена ​​поддержка нестандартных приложений (отметьте USE_LEGACY_CURSOR_WRAPPER).

2 голосов
/ 04 мая 2011

AFAIK, нет возможности поделиться изображением из папки assets.Но можно делиться ресурсами из папки res.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...