2011-02-04 12 views
10

Tengo algunos requisitos para proteger algunos datos confidenciales. Los datos se descargan en formato PDF desde una URL y se guarda como un archivo privado de aplicaciones usando el siguiente código:¿VER INTENTO desde un URI del proveedor de contenido?

public File downloadPDF(final Context fileContext, Uri reportUri, final String fileName) 
{ 
    try 
    { 
     HttpGet get = new HttpGet(reportUri.toString()); 

     File file = httpClient.execute(get, new ResponseHandler<File>() 
     { 
      @Override 
      public File handleResponse(HttpResponse response) throws ClientProtocolException, IOException 
      { 
       if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) 
       { 
        response.getEntity().writeTo(fileContext.openFileOutput(fileName, Context.MODE_WORLD_READABLE)); 
        return fileContext.getFileStreamPath(fileName); 
       } 
       return null; 
      } 
     }); 

     return file; 
    } 
    catch (IOException e) 
    { 
     Log.e(TAG, "Unable to download report.", e); 
    } 

    return null; 
} 

Ahora, lo que me gustaría hacer es cambiar esto usando Context.MODE_PRIVATE y crear un ContentProvider para que mi aplicación tenga control total sobre el uso compartido de este archivo en un lector de PDF como Adobe Reader. es posible? Actualmente uso un código como el siguiente para pasar el URI del informe al lector de PDF configurado actualmente.

// Fire up a PDF viewer intent for the URL. 
    Intent intent = new Intent(Intent.ACTION_VIEW); 
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    intent.setDataAndType(uri, "application/pdf"); 
    startActivity(intent); 

¿Funcionaría lo mismo a través de un URI de ContentProvider? Un contenido: // paquete/tipo de archivo URI? Voy a probar un pequeño pico mañana para ver si puedo, pero si alguien sabe que solo el archivo: // URI está permitido, sería realmente útil.


ACTUALIZACIÓN

pude resolver mi problema satisfactoriamente mediante la aplicación de una subclase ContentProvider con el siguiente método anulado:

@Override 
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException 
{ 
    // The filename is the path in the URI without the initial slash. 
    String fileName = uri.getPath().substring(1); 
    File file = getContext().getFileStreamPath(fileName); 
    return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); 
} 

Entonces, cuando me llamas más allá de la intención de ver, se reescribe algo como lo siguiente:

Intent intent = new Intent(Intent.ACTION_VIEW); 
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
Uri uri = Uri.withAppendedPath(Uri.parse("content://providername/"),filePath); 
intent.setData(uri); 
startActivity(intent); 

Y en mi caso, uso Adobe Reader, que implementa correctamente la carga desde content:// URI.

Respuesta

4

¿Funcionaría lo mismo a través de un URI del tipo ContentProvider? Un contenido: // paquete/tipo de archivo URI?

Debería. Necesitará tener su ContentProvider return application/pdf para getType(). Y es posible que algunos lectores de PDF no manejen los valores content://Uri.

Lo que puede hacer es hacer la ContentProvider, a continuación, utilizar PackageManager para ver si algo va a entender su ACTION_VIEWIntent en el content://Uri. Si algo responde, estás listo. De lo contrario, puede recurrir a hacer que el archivo sea legible por todo el mundo y utilizando su implementación actual. O bien, dado que cambiar el archivo a legible por todo el mundo puede ser complicado, puede ejecutar la prueba desde el principio (por ejemplo, cuando se inicia la aplicación) con un poco de Uri que admita su ContentProvider, para que sepa qué ruta tomar cuando lo haga tus descargas

+0

Muchas gracias. Tengo la intención de pasar la mañana trabajando en una prueba de concepto para ver si los archivos PDF 'content: // 'son aceptados por los lectores de PDF que uso habitualmente. Yo tampoco sabía sobre este uso del 'PackageManager', así que tendré una lectura al respecto. – Thorinside

+1

Sí, parece que eso es lo que está sucediendo.Eché un vistazo a la 'fuente' de Adobe Reader para ver si usará un Resolver contenido en el caso de un 'VIEW content: // Intent' y parece que realmente lo hará. Estoy tratando de descubrir ahora por qué mi ContentProvider no está siendo devuelto. – Thorinside

+0

Bien, acabo de descubrir que tengo que anular el método openFile en mi instancia de ContentProvider para interceptar la solicitud de Adobe Reader para el flujo de entrada. Estoy animado – Thorinside

1

No hay proveedores de contenido no protegen archivos

De hecho, probablemente lo primero que una aplicación podría hacer con un archivo desde un proveedor de contenidos es hacer una copia temporal en su directorio caché. Creo que deberías volver a visitar esto.

Cuestiones relacionadas