2012-04-27 15 views
20

Mam aparat DSLR i tablet Samsung Galaxy Tab z systemem Android Honeycomb. DSLR podłączony do tabletu za pomocą kabla USB (przez zestaw USB umożliwiający obsługę hosta na tablecie). Chcę otrzymywać powiadomienia, gdy użytkownik robi zdjęcie za pomocą tego zewnętrznego aparatu, aby pobrać ten obraz na tablet lub zrobić coś innego, jak pokazano to powiadomienie Toast zawierające meta-informacje pobrane z obrazu.Oglądaj zmiany w zewnętrznej pamięci USB dla Honeycomb lub nowszych wersji Androida

O ile mi się wszystkich istniejących narzędzi (jak FileObserver użyciem bazowego inotify mechanizm, MediaContentProvider etc) pozwalającą na oglądanie zmian, żądać określonego pliku lub ścieżka do oglądanych. Było to wystarczająco dobre, dopóki nie mieliśmy obsługi protokołu warstwy blokowej w wersjach 2.x i wcześniejszych wersji Androida - po podłączeniu urządzenia zostało ono zamontowane gdzieś w systemie plików urządzenia i można było użyć tego punktu montowania jako punktu oglądania dla tych narzędzi .

Od czasu pojawienia się modułu o strukturze plastra miodu firma Google zmieniła sposób dostępu do zewnętrznych urządzeń USB na Media Transfer Protocol z podziałem na PTP. Teraz, kiedy podłączę zewnętrzne urządzenie USB do urządzenia z Androidem, nie zobaczę dla niego żadnych punktów montowania (używam polecenia adb shell i następującego potem polecenia mount, aby je uzyskać). Ponadto implementacja MTP wykorzystuje identyfikatory przechowywania, które najwyraźniej działają jako wyższy poziom abstrakcji i są po prostu wartościami całkowitymi. Miałem nadzieję, że istnieje sposób, aby w jakiś sposób przetłumaczyć te id pamięci na rzeczywiste ścieżki/punkt montowania/cokolwiek, ale najwyraźniej nie wydaje się.

myślą o Androidzie MediaScanner który jest już uruchomiony na urządzeniu Domyślałem mogła poradzić sobie z tym problem, ze szczególnym Intent nadawanym kiedy są tam zmiany w mediach pliki dostępne z urządzenia, więc zacząłem szukać już istniejący i nadaje Intents za powiadomienie, ale bez powodzenia - znalazłem tylko ACTION_MEDIA_MOUNTED i ACTION_MEDIA_REMOVED, które są nadawane tylko wtedy, gdy urządzenie jest odpowiednio podłączone i odłączone. Oznacza to, że MediaScanner nie może zauważyć żadnych zmian na urządzeniu, dopóki go nie zremontujesz (dwukrotnie sprawdziłem to za pomocą aplikacji Galeria fotografii - nie widzę żadnych nowo utworzonych obrazów w kamerze, dopóki nie odłączysz go i nie włączysz go w systemie Android urządzenie ponownie).

Próbując dostać tę ścieżkę montowania dla zewnętrznego sdcard użyłem Environment.getExternalStorageDirectory() API wezwanie, ale plony emulowane ścieżkę sdcard Galaktyki który /mnt/sdcard ani jednego aparatu. To też nie działa dla mnie.

Udało mi się rozwiązać ten problem dopiero po uruchomieniu okresowego zdarzenia Timer z AsyncTask działającego jako TimerTask. Zadanie to inicjuje połączenie USB, otwiera urządzenie, skanuje pamięć całego urządzenia, pobiera tylko ostatnie wykonane zdjęcie, a następnie zamyka deskryptor urządzenia i połączenie USB.

Nie wygląda to najlepiej i efektywnie, biorąc pod uwagę, że musi wykonywać wszystkie te czynności za każdym razem, co może być dość częste, powiedzmy co 5 lub 10 sekund. To zdecydowanie szybko wyczerpuje baterię i wytwarza zbędne wejścia/wyjścia systemu do zrobienia tylko ostatniego zrobionego zdjęcia i porównania go z poprzednim zrobionym zdjęciem (w 99% to ten sam obraz), ale nie znalazłem lepszego działającego rozwiązania za to. Znacznie lepiej byłoby mieć mechanizm obserwatora z powiadomieniami opartymi na zdarzeniach.

Moje pytanie brzmi: czy istnieje skuteczniejszy sposób powiadamiania o zmianach w zewnętrznej pamięci USB dla wersji Honeycomb lub nowszych wersji Androida, a nie opisanych powyżej?

Odpowiedz

2

Jeśli potrzebujesz bardziej wydajnego sposobu, aparat musiałby przesłać sygnał usb, że zrobił zdjęcie. Chyba to nie robi.

Dlatego trzeba będzie sprawdzić ręcznie, wykonując swój sposób są discribing:

zamontować przechowywanie -> sprawdzić zmiany -> rób swoje ze swoimi wykrytych zmian.

Nie wiem co ty używany do odczytu „drogę MTP”, ale tutaj przykładową aplikację:

https://github.com/ynakanishi/Honeycomb-MTP-sample

nie do skanowania całej pamięci za każdym razem można zapisać wynik odczytać nazwy plików na przykład za każdym razem, gdy je sprawdzasz i porównujesz, aby znaleźć nowe. Zwykle nazwa pliku zaczyna się od tego samego numeru w kamerze. Więc jeśli rozpoczynasz sesję z pustą kartą SD, znasz już nazwę pliku, które będzie mieć zdjęcie. powiedzmy img0001.jpg. Musisz więc napisać funkcję, aby chwycić ten plik, dopóki się nie powiedzie. jeśli chcesz następny plik img0002.jpg, możesz napisać zadanie/usługę/funkcję, aby pobrać ten plik, aż do skutku, i tak dalej.

Jeśli chcesz zaoszczędzić na baterii, możesz zaimplementować dodatkową baterię/źródło zasilania pomiędzy nimi do zasilania portu USB.

Zamiast zadania Async lub timerTask można wypróbować usługę ScheduledExecutorService i sprawdzić, czy zużywa ona mniej energii.

Mam nadzieję, że dałem Ci nowe myśli