私は cwac をうまく動作させることができず、デモ コードを見ても役に立ちませんでした。共有インテントを使用して pdf をエクスポートしようとしているだけです。現在、出力は「空のファイルを添付できません」というエラーです。しかし、ファイルは存在し、問題がファイル名、場所、または cwac プロバイダーの使用にあるのかどうかはわかりません。
プロバイダーの設定方法は次のとおりです。
<provider
android:name="com.commonsware.cwac.provider.StreamProvider"
android:authorities="com.anothergamedesigner.CatVimeoTest.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="com.commonsware.cwac.provider.STREAM_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
これは、プロバイダーが使用している私の xml リソースです。サブディレクトリがないため、パスを "" に設定します。それらが必要かどうかはわかりませんが、理想的には、ファイルをサブディレクトリに配置するために必要なファイルの再構築のために、コードを別の場所に切り替える必要はありません。それが問題なら、できると思いますが、ルートが機能しない理由がわかりません。
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<asset name="assets" path=""/>
</paths>
これが私のPDFActivityです(AppCompatActivityを拡張します):
変数:
private String pdfName //set in onCreate; ex. "This is my.pdf"
private static final String AUTHORITY = "com.anothergamedesigner.CatVimeoTest";
private static final Uri PROVIDER = Uri.parse("content://"+AUTHORITY);
private static final String ASSET_PATHS ="assets/";
メソッドの定義:
private Intent getOpenPDFShareIntent(String name){
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("application/pdf");
shareIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {""});
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string.default_share_subject));
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, getResources().getString(R.string.default_share_text));
shareIntent.putExtra(Intent.EXTRA_STREAM, getURI());
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setType("text/plain");
return shareIntent;
}
private Uri getURI(){
String path = ASSET_PATHS + pdfName;
return(PROVIDER
.buildUpon()
.appendPath(StreamProvider.getUriPrefix(AUTHORITY))
.appendPath(path)
.build());
}
getURI() で、System.out.println(path) の戻り値の例: "assets/my.pdf"
コードは、選択時にメニュー ボタンを介して実行されます。
Intent shareIntent = getOpenPDFShareIntent(pdfName);
StartActivity(Intent.createChooser(shareIntent, getResources().getString(R.string.contact_send_mail));
編集: null URIPrefix を削除しようとしています:
private Uri getURI(){
//String path = ASSET_PATHS + pdfName;
if(StreamProvider.getUriPrefix(AUTHORITY) != null){
return(PROVIDER
.buildUpon()
.appendPath(StreamProvider.getUriPrefix(AUTHORITY))
.appendPath(ASSET_PATHS)
.appendPath(pdfName)
.build());
} else{
return(PROVIDER
.buildUpon()
.appendPath(ASSET_PATHS)
.appendPath(pdfName)
.build());
}
}
編集 2 - DocumentFile を使用したテスト:
別の SO 回答からこれらの新しいメソッドを使用し、ファイルを返すように変更しました。
private File CopyReadAssets()
{
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getFilesDir(), "my.pdf");
try
{
in = assetManager.open("my.pdf");
out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
return file;
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
次に、次を使用してテストしました:
DocumentFile aFile = DocumentFile.fromFile(CopyReadAssets());
DocumentFile file = DocumentFile.fromSingleUri(this, getURI());
System.out.println(aFile.getName());
System.out.println(aFile.length());
System.out.println(file.getName());
System.out.println(file.length());
aFile の場合は "my.pdf" と "33528"、ファイルの場合は "my.pdf" と "FileNotFoundException" を返します。