2011-01-20 16 views
11

Moja aplikacja umożliwia zapisanie obrazu na karcie SD. Ale nie wiem, jak sprawić, by pojawiała się w galerii, dopóki nie odłączysz i nie włożysz ponownie karty SD. Mam google przez kilka dni z tym problemem, ale nie jestem pewien, jak sprawić, aby pojawił się automatycznie. Znalazłem link this, ale nie jestem pewien, jak korzystać z klasy. Właśnie tego używam do zapisania pliku. Na dole bloku catch catch, gdzie chcę skanować kartę SD dla nowych mediów.Skanowanie karty SD Android w poszukiwaniu nowych plików

FileOutputStream outStream = null; 
    File file = new File(dirPath, fileName); 
    try { 
     outStream = new FileOutputStream(file); 
     bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream); 
     outStream.flush(); 
     outStream.close(); 
    } catch { 
     ... 
    } 

Jeśli ktoś mógłby wskazać mi właściwy kierunek, byłbym wdzięczny.

+0

Aplikacja "sdrescan" robi to, co chcesz. Jest wolne; może mógłbyś poprosić autora o fragment kodu? Lub po prostu uruchom go ze swojej aplikacji. –

+0

Czy istnieje sposób na ponowne skanowanie bez zatrzymywania odtwarzacza muzycznego? Mówi "Przepraszam", odtwarzacz multimedialny nie obsługuje tego pliku, dopóki nie przywrócę utworu, nie przeskoczę utworu, a następnie zostanie odtworzony ponownie. – NoBugs

Odpowiedz

5

Ponieważ ostatnia odpowiedź Zamieściłem najwyraźniej nie była odpowiednia metoda, Znalazłem inną metodę here. Zasadniczo tworzysz klasę opakowania, inicjalizujesz ją, a następnie wywołujesz metodę scan(). Bardzo pomocny post. Daj mi znać, jeśli to nie jest odpowiednie.

+0

Uwaga: To wykorzystuje metodę scanFile(), która była dostępna od początku API Poziom 1. Nie nowsza funkcja scanFile(), która została udostępniona po 8. Poziomie API – Brian

0

Możesz użyć MediaStore.Images.Media.insertImage, aby wstawić element do galerii.

+0

Dzięki za pomoc. Ale nie mogłem uzyskać "insertImage" do pracy. Znalazłem odpowiedź na innym forum. – Brian

4

Zastosowanie MediaScannerConnection:

http://developer.android.com/reference/android/media/MediaScannerConnection.html

To może być trochę uciążliwe ze względu na wielu poziomach połączeń asynchronicznych, tak API 8 (Froyo) istnieje funkcja pomocnika:

http://developer.android.com/reference/android/media/MediaScannerConnection.html#scanFile(android.content.Context, java.lang.String [], java.lang.String [], android.media.MediaScannerConnection.OnScanCompletedListener)

+0

Przeczytałem odnośnik kilka razy i nie mogę dowiedzieć się, jak uzyskać dostęp do MediaScannerConnection. Jeśli chodzi o funkcję pomocnika, nie sądzę, że byłoby to najlepsze podejście. API 8 nie jest bardzo stary i nie byłby obsługiwany na wielu urządzeniach (w tym na moim telefonie testowym). Przez kilka dni grałem z linkiem w moim pierwszym wpisie i nie mogłem zrobić tego przykładu. Jeśli mógłbyś opublikować kilka fragmentów lub wskazać mi inny przykład, byłbym wdzięczny. Do tego czasu będę musiał opuścić metodę "sendBroadcast", ponieważ jest to jedyny sposób, który działa teraz. – Brian

+0

Istnieje demo interfejsu API dla nowej funkcji: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.html Możesz znaleźć implementację kodu, która funkcja do modelowania dla własnej implementacji tutaj: http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=media/java/android/media/MediaScannerConnection.java – hackbod

+1

Aby powtórzyć: NIE WYSYŁAJ ACTION_MEDIA_MOUNTED. To zrobi WSZYSTKIE RODZAJE rzeczy, w tym pełne skanowanie karty SD. W rzeczywistości muszę się upewnić, że w przyszłych wersjach platformy aplikacje nie mogą go wysłać, ponieważ prawdopodobnie spowoduje to niewłaściwe działanie części platformy, jeśli otrzymają ją w niewłaściwym momencie. Więc spodziewamy się w przyszłości, jeśli robisz to, aby Twoja aplikacja się zepsuła. – hackbod

2

Można również bezpośrednio wywołać skaner multimedialny, wysyłając audycję.

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri 
        .parse("file://" 
          + Environment.getExternalStorageDirectory()))); 
0

Here jest inny sposób zmusić skanowania:

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,"uri to file")); 

I wtedy system będzie ogień ACTION_MEDIA_SCANNER_FINISHED transmisję więc można reagować na nią z BroadcastReceiver

Aby móc odbierać ACTION_MEDIA_SCANNER_FINISHED transmisję Intent Filter powinien zawierać schemat danych:

IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_FINISHED); 
intentFilter.addDataScheme("file"); 
context.registerReceiver(mMediaScannerFinishReceiver, intentFilter); 

z doc:

public static final String ACTION_MEDIA_SCANNER_SCAN_FILE

Dodane w poziomie API 1 Broadcast działaniu: Prośba skaner media zeskanować plik i dodać go do bazy danych mediów. Ścieżka do pliku to zawarta w polu Intent.mData.

i

public static final String ACTION_MEDIA_SCANNER_FINISHED

Dodane w poziomie API 1 Broadcast działaniu: Skaner mediów zakończył skanowanie katalogu. Ścieżka do zeskanowanego katalogu zawiera w polu Intent.mData.

9

Próbowałem wiele różnych metod, aby uruchomić MediaScanner, i to są moje wyniki.

SendBroadcast

Najprostszym i naiwne rozwiązania. Polega ona na wykonaniu następującą instrukcję z kodu:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, 
       Uri.parse("file://"+ Environment.getExternalStorageDirectory()))); 

Jednak ta nie działa w urządzeniach KitKat, ze względu na brak wymaganych uprawnień.


MediaScannerWrapper

Jak pisał here (za @ Briana odpowiedź), polega ona na owijanie instancji MediaScannerConnection w celu wywołania metody scan() w określonym katalogu. Ta metoda okazała się działać dobrze dla wersji 4.3 i poniżej, ale wciąż nie ma szczęścia w KitKat (4,4+).


FileWalker

Jedną z wielu aplikacji w Sklepie Play, która stara się przezwyciężyć brak w Mediastore za zobowiązania zaktualizować jego bazy danych jest ReScan SD. Wysyła wiele różnych programów:

sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable/SD"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable/MicroSD"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///mnt/Removable/MicroSD"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///mnt"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///storage"))); 
    sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable"))); 

i stara się wspierać KitKat ręcznie wywołując metodę scan() nad każdego pliku w katalogu głównym. Niestety, jest to bardzo obciążające procesor i czasochłonne, więc nie jest zalecane.


„Droga shell”

Jedyną rzeczą, która wydaje się działać z KitKat w niektórych przypadkach jest wysyłanie transmisji poprzez adb shell. Tak, ten fragment pozwala nie tylko, że programowo:

Runtime.getRuntime().exec("am broadcast -a android.intent.action.MEDIA_MOUNTED -d file://" + Environment.getExternalStorageDirectory()); 

To jest bardziej hack-owski sposób prowadzenia, ale w tej chwili jest najlepsze co mogłem wymyślić.


Konkluzja

Każde z powyższych rozwiązań faktycznie działa na wszystko, co nie jest KitKat. Dzieje się tak, ponieważ dzięki Justin znaleziono błąd i został on wydany official Tracker. Oznacza to, że dopóki błąd nie zostanie usunięty, pozostaniemy bez prawdziwej obsługi KitKat.

Który użyć? Spośród nich korzystałbym z rozwiązania MediaScannerWrapper wraz z podejściem shell-ish (ostatnim).

+0

Powłoka na KITKAT Wspomniałeś, że działa w niektórych przypadkach. Chciałbym wiedzieć, jaki jest przypadek użycia tej metody? lub w którym przypadku przypadki to działa? – Ahmed

+0

Nie mogłem znaleźć żadnego przypadku użycia. Wydaje się, że działa tylko odświeżanie MediaScanner po dodaniu pliku. Z drugiej strony nie działa, gdy plik jest usuwany. – Sebastiano

+2

Zadziałało, gdy wysłałem transmisję z wiersza poleceń za pomocą powłoki adb działa zarówno dla nowych plików, jak i usuniętych. Ale program KitKat nie działa programowo w przypadku nowych plików ani usuniętych. Testowałem z plikami muzycznymi audio i korzystałem z interfejsu API emulatora 19. – Ahmed

Powiązane problemy