【发布时间】:2025-12-27 23:55:06
【问题描述】:
我无法让 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 资源。我将路径设置为“”,因为我没有任何子目录。我不知道是否需要这些,但理想情况下,我不想为了将文件放入子目录所需的文件重组而在其他地方切换我的代码。虽然,如果这是问题所在,我想我可以,但我不明白为什么 root 不应该工作。
<?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));
编辑: 正在尝试删除空 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”。
【问题讨论】:
-
我将从修复您的 MIME 类型开始。您没有共享纯文本。您正在分享
application/pdf,并且您正在呼叫setType()两次。此外,在您让事情正常运行之前,请摆脱EXTRA_TEXT。ACTION_SEND支持 eitherEXTRA_TEXTorEXTRA_STREAM,因此您可能会获得其中之一,但不能同时获得两者,具体取决于ACTION_SEND活动的实现.除此之外,你从getURI()得到的整个Uri是什么样的? -
我已经注释掉了这些行,是的,注意到 setType 的东西并删除了它。同样的问题,但可能最好按照您的建议进行。 URI 是:content://com.anothergamedesigner.CatVimeoTest/null/assets%2FCEGA%20OnBoard%20Support%201.6.compressed.pdf
-
知道 null 部分是如何产生的吗?
标签: android commonsware-cwac share-intent