我正在构建一个使用IOCipher和SQLCipher运行的安全Android应用程序。我的应用程序存储打算由第三方应用程序打开的PDF,DOC,DOCX,XLS,XLSX文件。目前我可以打开所有这些类型的文件,但 DOCX 。当我使用此方法打开存储在IOCipher中的docx文件时:
File file = new File(path);
Uri contentUri = Uri.parse(VFSContentProvider.FILES_URI + file.getName());
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(contentUri);
Microsoft Word提示我错误消息:
无法打开文件" myFile.docx.docx" 。
发生这种情况对于我的所有docx文件,当内容提供商返回时,它似乎在文件末尾附加了两次mime类型......
以下是我的IOCipher内容提供商:
public class VFSContentProvider extends ContentProvider {
public static final String TAG = "VFSContentProvider";
public static final Uri FILES_URI = Uri
.parse("content://com.plante.android.cobalt.VFSContentProvider/");
private MimeTypeMap mimeTypeMap;
@Override
public boolean onCreate() {
mimeTypeMap = MimeTypeMap.getSingleton();
return true;
}
@Override
public String getType(Uri uri) {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri.toString());
return mimeTypeMap.getMimeTypeFromExtension(fileExtension);
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
ParcelFileDescriptor[] pipe = null;
InputStream in = null;
try {
pipe = ParcelFileDescriptor.createPipe();
String path = uri.getPath();
Log.i(TAG, "streaming " + path);
// BufferedInputStream could help, AutoCloseOutputStream conflicts
in = new FileInputStream(new File(path));
new PipeFeederThread(in, new AutoCloseOutputStream(pipe[1])).start();
} catch (IOException e) {
Log.e(TAG, "Error opening pipe", e);
throw new FileNotFoundException("Could not open pipe for: "
+ uri.toString());
}
return (pipe[0]);
}
@Override
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
// throw new RuntimeException("Operation not supported");
return null;
}
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
throw new RuntimeException("Operation not supported");
}
@Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
static class PipeFeederThread extends Thread {
InputStream in;
OutputStream out;
PipeFeederThread(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
@Override
public void run() {
byte[] buf = new byte[8192];
int len;
try {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
Log.e(TAG, "File transfer failed:", e);
}
}
}
这是日志文件:
03-16 13:38:20.714 800-1325/? I/ActivityManager: START u0 {act=android.intent.action.VIEW dat=content://com.plante.android.cobalt.VFSContentProvider/0c8dbc0e1671e127ed9fcb2786b218d379f12888Finance_Corporate_BCP_Checklist_2014_MH20150115.docx flg=0x13000003 cmp=com.microsoft.office.word/com.microsoft.office.apphost.LaunchActivity} from uid 10182 on display 0