2010-11-15 4 views
7

Co próbuję zrobić, to: chcę, aby moja aplikacja pobrała obraz z Internetu i zapisała go w pamięć wewnętrzna telefonu w lokalizacji, która jest prywatna dla aplikacji. Jeśli nie ma dostępnego obrazu dla elementu listy (tzn. Nie można go znaleźć w Internecie), chcę wyświetlić domyślny obraz zastępczy. Jest to obraz, który zdefiniowałem w pliku list_item_row.xml jako domyślny.Android - pobieranie obrazu z sieci, zapisywanie w pamięci wewnętrznej w lokalizacji prywatnej do aplikacji, wyświetlanie pozycji na liście

W moim pliku ListActivity wywołuję instancję klasy CustomCursorAdapter, którą napisałem. Właśnie w CustomCursorAdapter dokonuję iteracji po wszystkich elementach listy i określam, jakie treści muszą być odwzorowane na widoki, w tym plik obrazu, próbując odczytać go z pamięci wewnętrznej.

Widziałem kilka pytań na ten temat, ale przykłady są albo specyficzne dla pamięci telefonu zewnętrznego (np. SDCard), obejmują zapisywanie ciągów zamiast obrazów albo wymagają użycia Bitmap.CompressFormat w celu zmniejszenia rozdzielczości pliku (co w moim przypadku jest niepotrzebne, ponieważ obrazy te będą małymi miniaturkami o już małej rozdzielczości). Próba złożenia kodu z każdego przykładu była trudna, stąd moje pytanie o mój konkretny przykład.

W tej chwili uważam, że napisałem prawidłowy kod, ale nie wyświetla się żaden obraz dla elementów listy, w tym domyślny obraz zastępczy. Nie wiem, czy problem jest spowodowany przez nieprawidłowy kod pobierania/zapisu lub nieprawidłowy kod odczytu - nie pomaga mi to, że nie wiem, jak sprawdzić pamięć wewnętrzną, aby sprawdzić, czy obraz istnieje.

W każdym razie, oto mój kod. Każda pomoc będzie bardzo ceniona.

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

Odpowiedz

2

Wygląda po prostu odnosi się do nazwy pliku obrazu gdy próbuje odczytać to nie wystarczyło, i musiałem zadzwonić getFilesDir(), aby uzyskać ścieżkę do przechowywania plików. Poniżej znajduje się kod użyłem:

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

Następnie moje pytanie było prawidłowe: "Zapisz w dzienniku, aby upewnić się, że masz napisać i przeczytać ten sam plik?". – dacwe

+0

Początkowo nie zdawałem sobie sprawy, że potrzebne jest coś więcej niż nazwa pliku i pomyślałem, że aplikacja była świadoma konkretnej ścieżki, w której plik byłby. – Keeb13r

7

wydaje się, że niektóre kod jest pominięty, to ponownie napisał tak:

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

Aplikacja nie zostanie skompilowany z tym kodem. Mówi, że zmienne wejściowe i wyjściowe muszą zostać zainicjowane. Poprawiłem problematyczne linie, aby powiedzieć "InputStream input = null" i "FileOutputStream output = null", ale nadal mam ten sam problem z brakiem wyświetlania obrazu. – Keeb13r

+0

Wygląda na to, że otrzymuję błąd: "java.io.IOException: Is a directory". Nie jestem pewien, co myśleć, ponieważ myślałem, że samo określenie nazwy pliku bez wprowadzania żadnych folderów pośrednich spowoduje, że ścieżka zapisu i odczytu będzie dokładnie taka sama. – Keeb13r

+0

Hum, czy identyfikator produktu zawiera ukośniki ('/')? – 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

Ten kod nie jest tak naprawdę związany z pytaniem, a nawet go nie kompiluje. Sądzę, że warto jednak nakreślić algorytm utrzymywania bitmapy do przyszłego użycia. – IcedDante

Powiązane problemy