私の目標は、内部ストレージにXMLファイルを作成し、それを共有インテントを介して送信することです。
このコードを使用してXMLファイルを作成できます
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();
共有するために出力ファイルにURIを取得しようとして立ち往生しています。私は最初にファイルをURIに変換してファイルにアクセスしようとしました
File outFile = context.getFileStreamPath(fileName);
return Uri.fromFile(outFile);
これはfile:///data/data/com.my.package/files/myfile.xmlを返しますが、これを電子メールに添付したり、アップロードしたりすることはできません。
ファイルの長さを手動で確認すると、それは適切であり、妥当なファイルサイズがあることを示しています。
次に、コンテンツプロバイダーを作成し、ファイルを参照しようとしましたが、ファイルへの有効なハンドルではありません。はContentProvider
、どのポイントとも呼ばれることはないようです。
Uri uri = Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/" + fileName);
return uri;
これはcontent://com.my.package.provider/myfile.xmlを返しますが、ファイルをチェックすると長さがゼロです。
ファイルに正しくアクセスするにはどうすればよいですか?コンテンツプロバイダーでファイルを作成する必要がありますか?もしそうなら、どのように?
アップデート
これが私が共有するために使用しているコードです。Gmailを選択すると、添付ファイルとして表示されますが、送信すると「添付ファイルを表示できませんでした」というエラーが表示され、届いたメールに添付ファイルがありません。
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;
}
}
createChooser(...)Exception
の内部からスローされていることに気づきましたが、なぜスローされたのかわかりません。
E / ActivityThread(572):アクティビティcom.android.internal.app.ChooserActivityが、最初にここに登録されたIntentReceiver com.android.internal.app.ResolverActivity $ 1@4148d658をリークしました。unregisterReceiver()の呼び出しがありませんか?
私はこのエラーを調査しましたが、明らかなものは何も見つかりません。これらのリンクは両方とも、受信者の登録を解除する必要があることを示唆しています。
- ChooserActivityがIntentReceiverをリークしました
- Intent.createChooser()にBroadcastReceiverが必要な理由とその実装方法を教えてください。
私はレシーバーをセットアップしていますが、それAlarmManager
は他の場所で設定されており、アプリが登録/登録解除する必要はありません。
openFile(...)のコード
必要に応じて、これが私が作成したコンテンツプロバイダーです。
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;
}