I can't quite get cwac to work, and looking at the demo code hasn't helped. I'm simply trying to export a pdf through a share intent. Currently the output is a "Can't attach empty file" error. But the file does exist, and I can't tell if the problem is with the file name, location, or cwac provider usage.
Here is how I've set up the provider.
<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>
This is my xml resource the provider is using. I set path to "" because I don't have any subdirectories. I don't know if those are required, but ideally I don't want to have to switch up my code elsewhere for the file restructure necessary to put the files in subdirectories. Although, if that's the problem, I suppose I could, but I don't see why the root shouldn't work.
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<asset name="assets" path=""/>
</paths>
Here is my PDFActivity (extends AppCompatActivity):
Variables:
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/";
Methods definitions:
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());
}
In getURI(), an example return for System.out.println(path) is: "assets/my.pdf"
The code runs via a menu button that on selection:
Intent shareIntent = getOpenPDFShareIntent(pdfName);
StartActivity(Intent.createChooser(shareIntent, getResources().getString(R.string.contact_send_mail));
EDIT: Attempting to remove 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());
}
}
EDIT 2 - Testing with DocumentFile:
I used these new methods from another SO answer and altered it to return the file.
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);
}
}
Then I tested using:
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());
It returns "my.pdf" and "33528" for aFile and "my.pdf" and "FileNotFoundException" for file.