2011-05-04 11 views
17

Estoy intentando compartir una imagen de mi carpeta de activos. Mi código es:compartir imágenes androide de activos carpeta

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

pero no funciona. ¿Tienes alguna idea?

Respuesta

2

yo sepa, no hay manera de compartir una imagen de la carpeta assets. Pero es posible compartir recursos de la carpeta res.

+0

me puede dar un ejemplo de cómo compartir imágenes de la carpeta dibujable de recursos? –

+3

El formato es: 'android.resource: // [paquete]/[tipo]/[id]'. Por lo tanto, es un ejemplo de URI: ' "android.resource: //com.your.app/drawable/" + Integer.toStrng (R.drawable.some_resource)'. – Michael

+0

He intentado usar share.putExtra (Intent.EXTRA_STREAM, Uri.parse ("android.resource: //com.packake.myapp/drawable/" + Integer.toString (R.drawable.myimage))); funciona al compartirlo con Gmail, pero cuando trato de compartirlo con el correo yahoo recibo el mensaje "Acceso denegado acceso. El recurso no se puede leer". ¿tienes alguna idea de por qué? –

14

Es posible compartir archivos (incluyendo imágenes) de la carpeta de activos a través de una costumbre ContentProvider

necesita extender ContentProvider, registrarlo en su manifiesto y poner en práctica el método openAssetFile. A continuación, puede evaluar los activos a través de 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; 
    } 
+0

¿Puedes agregar más detalles sobre cómo podemos llamar esto desde otra aplicación? –

8

Este blog explica todo:
http://nowherenearithaca.blogspot.co.uk/2012/03/too-easy-using-contentprovider-to-send.html

Básicamente, esto va en el manifiesto:

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

El contenido de clase de proveedor tiene esta :

@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); 
} 

Y el código de llamada hace esto:

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); 
+0

no puedo usar su solución; consulte esto: http://stackoverflow.com/questions/21929721/contentprovider-dont-working-for-sharing-images-from-assets-folder – NullPointerException

+0

Asegúrese de que el URI comience con "content: //" –

+0

Obtengo "java.io.FileNotFoundException: este archivo no se puede abrir como un descriptor de archivo; probablemente esté comprimido" en am.openFd (nombre_de_archivo) – GozzoMan

9

Como complemento de lo @Cris Nash respondió:

que va a necesitar métodos de anulación como ejemplo de la clase anterior:

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; 
     } 
} 

que necesitaba para anular dos veces el método de consulta . Y añadir estas líneas por encima de la etiqueta en su AndroidManifest.xml:

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

Y con esto, todo el trabajo como un encanto: D

+0

alguien puede por favor ayudarme estoy obteniendo imágenes de los activos ----> carpeta ----> imagen1.png y no he podido obtener imágenes de la subcarpeta de activos pls sugerirme editar el código de esta línea Cadena file_name = uri.getLastPathSegment(); – user3233280

+0

http://pastie.org/9265206 – user3233280

+1

Lo siento por mi retraso. ¿Cómo envías el archivo para intentarlo? Creo que el código está bien. Necesitas llamar a la imagen por direcciones como esta: file: ///android_asset/folder/image1.png Si necesitas compartir esto, necesitas usar este código: String file = "folder/image1.png"; Uri theUri = Uri.parse ("content: //com.example.yourproject/" + file); Propósito theIntent = new Intent (Intent.ACTION_SEND); theIntent.setType ("image/*"); theIntent.putExtra (Intent.EXTRA_STREAM, theUri); startActivity (Intent.createChooser (theIntent, "Send to:"); – Kikuto

3

Muchas aplicaciones requieren que se proporcione el nombre y el tamaño de la imagen. Así que aquí es un código mejorado (utilizando el código FileProvider de Google como ejemplo):

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

Para compartir la carpeta de activos sólo puedo recomendar el cwac-provider biblioteca (StreamProvider).

Entre evitar el desarrollo de su propio proveedor de contenido, agrega algo de soporte para las aplicaciones heredadas caprichosas (marque USE_LEGACY_CURSOR_WRAPPER).

Cuestiones relacionadas