2010-11-15 8 views
7

Lo que trato de hacer es esto: quiero que mi aplicación descargue una imagen de Internet y la guarde en la memoria interna del teléfono en una ubicación privada para la aplicación. Si no hay ninguna imagen disponible para el elemento de la lista (es decir, no se puede encontrar en Internet), quiero que se muestre una imagen de marcador de posición predeterminada. Esta es la imagen que he definido en mi archivo list_item_row.xml como el predeterminado.Android - descarga de imagen desde la web, guardando en la memoria interna en la ubicación privada a la aplicación, mostrando el elemento de la lista

En mi archivo ListActivity, estoy llamando a una instancia de una clase CustomCursorAdapter que he escrito. Es en CustomCursorAdapter donde estoy iterando a través de todos los elementos de la lista y definiendo qué contenido debe asignarse a las vistas, incluido el archivo de imagen al tratar de leerlo desde la memoria interna.

He visto varias preguntas sobre este tema, pero los ejemplos son específicos de la memoria externa del teléfono (p. Ej. SDCard), implican guardar cadenas en lugar de imágenes o utilizar Bitmap.CompressFormat para reducir la resolución del archivo (lo cual es innecesario en mi caso, ya que estas imágenes serán pequeñas miniaturas de resolución ya pequeña). Tratar de reconstruir el código de cada ejemplo ha sido difícil, de ahí que pregunte sobre mi ejemplo específico.

Por el momento, creo que he escrito un código válido, pero no se muestra ninguna imagen para mis elementos de la lista, incluida la imagen del marcador de posición predeterminado. No sé si el problema está causado por un código de descarga/guardado no válido o un código de lectura no válido; no ayuda el hecho de que no sé cómo verificar la memoria interna para ver si existe la imagen.

De todos modos, aquí está mi código. Cualquier ayuda sería muy apreciada.

ProductUtils.java

public static String productLookup(String productID, Context c) throws IOException { 
    URL url = new URL("http://www.samplewebsite.com/" + productID + ".jpg"); 
    URLConnection connection = url.openConnection(); 
    InputStream input = connection.getInputStream(); 
    FileOutputStream output = 
     c.openFileOutput(productID + "-thumbnail.jpg", Context.MODE_PRIVATE); 
    byte[] data = new byte[1024]; 

    output.write(data); 
    output.flush(); 
    output.close(); 
    input.close(); 
} 

CustomCursorAdapter.java

public class CustomCursorAdapter extends CursorAdapter { 
    public CustomCursorAdapter(Context context, Cursor c) { 
     super(context, c); 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
     ImageView thumbnail = (ImageView) view.findViewById(R.id.thumbnail); 

     String fileName = 
       cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_IMAGE_FILE_PATH)); 

     Bitmap bMap = BitmapFactory.decodeFile(fileName); 
     thumbnail.setImageBitmap(bMap); 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
     LayoutInflater inflater = LayoutInflater.from(context); 
     View v = inflater.inflate(R.layout.list_item_row, parent, false); 
     bindView(v, context, cursor); 
     return v; 
    } 
} 

Respuesta

2

Parece que simplemente refiriéndose al nombre del archivo de imagen cuando intentaba leerlo no fue suficiente, y tuve que llamar a getFilesDir() para obtener la ruta del almacenamiento del archivo. A continuación se muestra el código utilicé:

String path = context.getFilesDir().toString(); 
String fileName = cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_PRODUCT_ID)); 

if (fileName != null && !fileName.equals("")) { 
    Bitmap bMap = BitmapFactory.decodeFile(path + "/" + fileName); 
    if (bMap != null) { 
     thumbnail.setImageBitmap(bMap); 
    } 
} 
+0

Entonces mi pregunta era válida: "¿Escribir en el registro para que esté seguro de haber escrito y leído el mismo archivo?". – dacwe

+0

Originalmente, no sabía que se necesitaba nada más que el nombre de archivo y pensé que la aplicación sabía por sí misma de la ruta específica donde estaría el archivo. – Keeb13r

7

parece que algo de código se deja fuera, me re-escrito así:

ProductUtils.java

public static String productLookup(String productID, Context c) throws IOException { 

    URL url = new URL("http://www.samplewebsite.com/" + productID + ".jpg"); 

    InputStream input = null; 
    FileOutputStream output = null; 

    try { 
     String outputName = productID + "-thumbnail.jpg"; 

     input = url.openConnection().getInputStream(); 
     output = c.openFileOutput(outputName, Context.MODE_PRIVATE); 

     int read; 
     byte[] data = new byte[1024]; 
     while ((read = input.read(data)) != -1) 
      output.write(data, 0, read); 

     return outputName; 

    } finally { 
     if (output != null) 
      output.close(); 
     if (input != null) 
      input.close(); 
    } 
} 
+0

La aplicación no se compilará con ese código. Dice que las variables de entrada y salida deben inicializarse. Corregí las líneas problemáticas para decir "InputStream input = null" y "FileOutputStream output = null", pero sigo teniendo el mismo problema sin visualización de imágenes. – Keeb13r

+0

Parece que el error que recibo es este: "java.io.IOException: es un directorio". No estoy seguro de qué pensar, ya que pensé que simplemente especificando el nombre del archivo sin introducir ninguna carpeta intermedia, la ruta de escritura y lectura sería exactamente la misma. – Keeb13r

+0

Hum, does productID contiene barras inclinadas ('/')? – dacwe

-1
void writeToFile(Bitmap _bitmapScaled) 
    { 
     ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
     _bitmapScaled.compress(Bitmap.CompressFormat.PNG, 40, bytes); 
     try{ 
     File f; 
     //you can create a new file name "test.jpg" in sdcard folder. 
     if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) 
      f =new File(android.os.Environment.getExternalStorageDirectory(),"FamilyLocator/userimages/"+imageName); 
     else 
     f = new File(Environment.getDataDirectory(),"FamilyLocator/userimages/"+imageName); 

     f.createNewFile(); 
     //write the bytes in file 
     FileOutputStream fo = new FileOutputStream(f); 
     fo.write(bytes.toByteArray()); 
     // remember close de FileOutput 
     fo.close(); 
     }catch(Exception e){e.printStackTrace();} 
    } 
+0

Este código no es realmente relevante para la pregunta y ni siquiera se compila. Sin embargo, creo que hay valor en elinear el algoritmo para persistir en el mapa de bits para uso futuro. – IcedDante

Cuestiones relacionadas