2012-05-09 22 views
10

Ostateczny cel zostanie wkrótce wyjaśniony.Android Tworzenie pliku wejściowego pamięci rezydentnej, który można dołączyć do wiadomości e-mail.

Chcę utworzyć obiekt pliku i zamiast pobierać dane z fizycznego pliku, chcę samemu dostarczyć bufor.

Następnie, chcę użyć tego pliku, który tak naprawdę nie istnieje na sdcard lub gdziekolwiek poza moją aplikacją, nadać mu nazwę i wysłać jako załącznik (za pomocą EXTRA_STREAM).

znalazłem następujący fragment kodu, przez Adriaan Koster (@adriaankoster), stanowisko Write byte[] to File in Java

// convert byte[] to File 
ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 
ObjectInputStream ois = new ObjectInputStream(bis); 
File fileFromBytes = (File) ois.readObject(); 
bis.close(); 
ois.close(); 

System.out.println(fileFromBytes); 

użyłem go do stworzenia tej funkcji

private File fileFromBytes(byte[] buf) { 
    File f = null; 
    try { 
     ByteArrayInputStream bis = new ByteArrayInputStream(buf); 
     ObjectInputStream ois = new ObjectInputStream(bis); 
     f = (File) ois.readObject(); 
     bis.close(); 
     ois.close(); 
    } 
    catch (Exception e) {} 
    return f; 
} 

a tu gdzie jestem utknąłem, ponieważ kiedy go używam:

// When sent as body the mail is sent OK 
// emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, dump()); 

// When I try to attach the mail is empty 
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, fileFromBytes(dump().getBytes())); 

Wiem z przykładów, które widziałem Argument cond powinien być identyfikatorem URI, ale: w jaki sposób utworzyć URI wirtualny, aby pasował do mojego pliku?

EDYCJA: Opcja dołączania danych bezpośrednio z aplikacji jest ważna w przypadku niektórych aplikacji. Mianowicie zabezpieczenia aplikacji bankowych, które nie chcą zbytnio przenosić poufnych danych. Z pewnością, jeśli dane nie dotrą do sdcard i trafią bezpośrednio do załącznika pocztowego, trudniej jest je wykryć niż w pamięci aplikacji.
To nie jest mój konkretny przypadek, ale chciałem podkreślić, że ta zdolność jest ważna.

+0

@adriaankoster, Jeśli tam jesteś, przeczytaj ten post. Może możesz pomóc. – ilomambo

Odpowiedz

5

Pierwszą rzeczą, którą chcesz zrobić, jak sądzę, jest stworzenie obiektu ContentProvider. Można zobaczyć przykładową realizację tutaj

https://github.com/dskinner/AndroidWeb/blob/master/src/org/tsg/web/WebContentProvider.java

gdzie w przypadku powyższego linku, w jakich można dodać do swojej AndroidManifest.xml

<provider 
    android:name="org.tsg.web.WebContentProvider" 
    android:authorities="your.package.name" /> 

Teraz będziesz mieć uri treści dostępne do użytku, content://your.package.name/.

Część powyższej ContentProvider, którą interesujecie, znowu wyobrażam sobie, to metoda openFile. Podczas udostępniania danych według intencji w aplikacjach pewne rzeczy są oczekiwane. W twoim przypadku chcesz udostępnić dane bajtowe, które mają zostać dołączone do wiadomości e-mail.

Jeśli przekażesz zawartość uri do aplikacji pocztowej, takiej jak content://your.package.name/foo z odpowiednimi flagami intencji, to zostanie wywołana openFile na Twoim dostawcy treści. W takim przypadku możesz sprawdzić koniec segmentu URI, aby uzyskać żądanie od użytkownika foo i odpowiednio go zwrócić.

Następnym problemem, który pojawił się, jest brak pliku na dysku. Chociaż nie mogę ręczyć za metodę użytą powyżej (choć wygląda ona na koszerną), to, co powinieneś zwrócić, to ParcelFileDescriptor ze swojego dostawcy treści. Jeśli spojrzysz na podany przeze mnie link, mógłbyś spróbować użyć tego jako przykładu, by uzyskać deskryptor pliku z twojego obiektu File (moje zwolnienie z wiedzy tutaj), ale wyobrażam sobie, że dane po prostu nie będą dostępne w tym momencie.

To, co robisz, to bezpieczeństwo. Należy pamiętać, że dane można zapisywać na dysk prywatnie, więc tylko aplikacja ma dostęp do danych. Wydaje mi się, że warto to sprawdzić, jeśli dane są prywatne dla aplikacji, można je ujawnić za pośrednictwem dostawcy treści i ewentualnie zablokować, kto i jak dostawca zostanie wykorzystany, kto może go nazwać itp. chcesz zagłębić się w dokumenty Android dla tej części lub spojrzeć na kilka innych pytań SO.

W każdym razie powodzenia.

+0

Dziękuję, popatrzę na dostawców treści. Teraz wstrzymałem to, ponieważ rozwiązanie wydaje się bardziej skomplikowane, niż się spodziewałem. Dam ci nagrodę za skok wiary. – ilomambo

0

Byłem zajęty dodawaniem załącznika do poczty i mogę wysyłać wiadomości z załącznikami. , jeśli chcesz rzucić okiem: can not send mail with attachment in Android

+0

Dzięki @yiddow, przyjrzałem się twojemu wpisowi, ale nie chcę tworzyć własnego interfejsu do załączania. Chcę użyć Intent.EXTRA_STREAM i dołączyć bufor w bajtach, które mam w pamięci, bez wcześniejszego tworzenia prawdziwego pliku. – ilomambo

1

Utwórz plik w katalogu pamięci podręcznej aplikacji. Zostanie utworzony w wewnętrznym systemie plików. Użyj "getCacheDir()" API, aby uzyskać ścieżkę do katalogu pamięci podręcznej. Zapisz dane w tym katalogu, a następnie pobierz URI z obiektu File za pomocą pliku "Uri.fromFile (File file)". Po zakończeniu pliku usuń go.

Pamięć podręczna aplikacji jest dostępna tylko dla aplikacji, dlatego jest bezpieczna w użyciu.

Możesz wykonać szyfrowanie, jeśli dane są zbyt krytyczne.

+0

To jest właśnie ten punkt. Nie wiem, jak dobrze znasz świat inżynierii wstecznej. Ale zasadniczo wszystko, co jest wysyłane przez magistrale systemowe, może być monitorowane za pomocą sprzętu i dekodowane z powrotem do danych. Jest autobus do wewnętrznej pamięci RAM i autobus, który jedzie do SDcard (może są takie same, w tym przypadku Twoja sugestia jest w porządku) :::: Wolę raczej znaleźć sposób na stworzenie wirtualnego pliku bez pisania do dowolnego katalogu. – ilomambo

+0

Uwaga: czasami układem procesora jest SOC (system on chip), a wewnętrzna pamięć RAM jest jego częścią, co sprawia, że ​​monitorowanie pamięci RAM czyta/zapisuje znacznie trudniej, ponieważ nie ma zewnętrznej magistrali. Z drugiej strony sdcard jest zawsze zewnętrzny. – ilomambo

+1

AFAIK nie możemy uzyskać identyfikatora URI obiektu w pamięci RAM. – Ronnie

1

Myślę, że aby to zrobić, musisz ujawnić ContentProvider, który pozwoli ci obsługiwać URI. Aplikacja poczty e-mail powinna następnie otworzyć InputInputStream na URI, w którym momencie zwracasz InputStream na swoich danych w pamięci.

Nie próbowałem tego, ale teoretycznie powinno to zadziałać.

+0

Nie mam tak dużego doświadczenia z Androidem, czy możesz zamieścić konkretny kod? :::: BTW, tworzenie strumienia wejściowego nie stanowi problemu, ByteArrayInputStream jest klasą wbudowaną. Problem polega na tym, jak uzyskać identyfikator URI, aby wskazywał na to. – ilomambo

Powiązane problemy