Twórz i udostępniaj plik z pamięci wewnętrznej

Moim celem jest utworzenie pliku XMLPamięć wewnętrzna a następnie wyślij za pośrednictwem zamiaru udziału.

Jestem w stanie utworzyć plik XML przy użyciu tego kodu

FileOutputStream outputStream = context.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
PrintStream printStream = new PrintStream(outputStream);
String xml = this.writeXml(); // get XML here
printStream.println(xml);
printStream.close();

Utknąłem, próbując pobrać Uri do pliku wyjściowego, aby go udostępnić. Najpierw próbowałem uzyskać dostęp do pliku, konwertując plik na Uri

File outFile = context.getFileStreamPath(fileName);
return Uri.fromFile(outFile);

To wracaplik: ///data/data/com.my.package/files/myfile.xml ale nie mogę dołączyć tego do wiadomości e-mail, przesyłania itp.

Jeśli ręcznie sprawdzę długość pliku, jest to właściwe i pokazuje, że istnieje rozsądny rozmiar pliku.

Następnie utworzyłem dostawcę treści i próbowałem odwołać się do pliku i nie jest to prawidłowy uchwyt do pliku. TheContentProvider nigdy nie wydaje się, aby był nazywany jakimkolwiek punktem.

Uri uri = Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/" + fileName);
return uri;

To wracacontent: //com.my.package.provider/myfile.xml ale sprawdzam plik i ma zerową długość.

Jak prawidłowo uzyskać dostęp do plików? Czy muszę utworzyć plik u dostawcy treści? Jeśli tak to jak?

Aktualizacja

Oto kod, którego używam do udostępniania. Jeśli wybiorę Gmaila, pojawi się on jako załącznik, ale gdy go wyślę, pojawia się błądNie można wyświetlić załącznika a otrzymany e-mail nie ma załącznika.

public void onClick(View view) {
    Log.d(TAG, "onClick " + view.getId());

    switch (view.getId()) {
        case R.id.share_cancel:
            setResult(RESULT_CANCELED, getIntent());
            finish();
            break;

        case R.id.share_share:

            MyXml xml = new MyXml();
            Uri uri;
            try {
                uri = xml.writeXmlToFile(getApplicationContext(), "myfile.xml");
                //uri is  "file:///data/data/com.my.package/files/myfile.xml"
                Log.d(TAG, "Share URI: " + uri.toString() + " path: " + uri.getPath());

                File f = new File(uri.getPath());
                Log.d(TAG, "File length: " + f.length());
                // shows a valid file size

                Intent shareIntent = new Intent();
                shareIntent.setAction(Intent.ACTION_SEND);
                shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
                shareIntent.setType("text/plain");
                startActivity(Intent.createChooser(shareIntent, "Share"));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            break;
    }
}

Zauważyłem, że jestException rzucony tutaj od środkacreateChooser (...), ale nie mogę zrozumieć, dlaczego jest rzucony.

E / ActivityThread (572): Activity com.android.internal.app.ChooserActivity wyciekł IntentReceiver com.android.internal.app.ResolverActivity$1@4148d658 pierwotnie zarejestrowany tutaj. Czy brakuje Ci połączenia do wyrejestrowania odbiornika ()?

Zbadałem ten błąd i nie mogę znaleźć niczego oczywistego. Oba te linki sugerują, że muszę wyrejestrować odbiornik.

ChooserActivity wyciekło IntentReceiverDlaczego Intent.createChooser () potrzebuje odbiornika BroadcastReceiver i jak go wdrożyć?

Mam konfigurację odbiornika, ale jest to konfiguracjaAlarmManager to jest ustawione gdzie indziej i nie wymaga aplikacji do rejestracji / wyrejestrowania.

Kod dla openFile (...)

Jeśli jest to potrzebne, oto dostawca treści, który stworzyłem.

public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    String fileLocation = getContext().getCacheDir() + "/" + uri.getLastPathSegment();

    ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(fileLocation), ParcelFileDescriptor.MODE_READ_ONLY);
    return pfd;
}

questionAnswers(3)

yourAnswerToTheQuestion