I'm trying to write a byteArray received from a server. This is my code
private fun writePdf(content: ByteArray) {
val storageDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
val file = File("${storageDir?.path}/", "${Date().time}Download.pdf")
try {
// file.writeBytes(archivo)
val os = FileOutputStream(file, false)
os.write(content)
os.flush()
os.close()
} catch (e: IOException) {
e.printStackTrace()
}
val intent = Intent(Intent.ACTION_VIEW)
val uri = FileProvider
.getUriForFile(
this,
this.packageName + ".fileprovider",
file)
intent.setDataAndType(uri, "application/pdf")
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
try{
startActivity(intent)
}catch (e: Exception){
e.printStackTrace()
Toast.makeText(this, "Error", Toast.LENGTH_LONG)
.show()
}
}
The problem is that when the pdf opens it is blank, like nothing has been written.
I've tried writing with FileOutputStream and File.writeBytes.
I've checked the byteArray (in case is corrupted or something) and it has no problems.
I've checked the length() of the file before and after writing, and it's length increases accordingly.
Thanks, any kind of help is appreciated.
I finally found the problem, and solution. Everything with the code above was okay; the problem was that the flags for the intent to visualize the PDF were wrong. Instead of:
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
It should be:
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Related
In my app, I have several file Uri (NOT URI) store. These are of the form:
content://com.android.providers.downloads.documents/document/427
My intention is, once I click a button, open one of these Uri in a file reader (may it be MS Word, Excel, PDF Reader... depending on the extension and device).
I am currently trying this snippet:
val file = File(Uri.parse(uri).path!!)
val myMime: MimeTypeMap = MimeTypeMap.getSingleton()
val newIntent = Intent(Intent.ACTION_VIEW)
val mimeType: String = myMime.getMimeTypeFromExtension(file.extension).toString()
newIntent.setDataAndType(
FileProvider.getUriForFile(applicationContext, "${applicationContext.packageName}.provider", file), mimeType)
newIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
newIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
try {
startActivity(newIntent)
} catch (e: ActivityNotFoundException) {
}
But every time I try to open it, I get:
java.lang.IllegalArgumentException: Failed to find configured root that contains /document/427
Could you please tell me what am I missing? No answers I've found here targeted my problem. Thanks in advance!
UPDATE
Thanks to #CommonsWare help, I managed to avoid an Exception, my code now looks like this:
val newIntent = Intent(Intent.ACTION_VIEW)
newIntent.addCategory(Intent.CATEGORY_OPENABLE)
newIntent.data = Uri.parse(uri)
newIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
newIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
try {
startActivity(newIntent)
} catch (e: ActivityNotFoundException) {
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show()
}
I'm getting the Uri from here:
val fileResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
viewModel.uploadFile(result, false)
}
fileFab.setOnClickListener {
val intent = Intent()
intent.type = "application/*"
intent.action = Intent.ACTION_OPEN_DOCUMENT
fileResultLauncher.launch(intent)
}
Unfortunately, I'm getting a NoActivityFoundException
Get rid of:
val file = File(Uri.parse(uri).path!!)
...and replace your setDataAndType() call with:
newIntent.setDataAndType(Uri.parse(uri), mimeType)
Im trying load this file into my webview but its not loading
file path is something like
/data/user/0/com.xyzapp.app/cache/temp_file.docx //this is getpathhh
below is my code
first activity:-
val browseintent = Intent(this, WebviewActivityNew::class.java)
browseintent.putExtra("url", "file://"+getpathhh.toString())
startActivity(browseintent)
second Activity:-
val url = intent.extras!!.getString("url")
webview_comp.getSettings().setLoadsImagesAutomatically(true);
webview_comp.getSettings().setJavaScriptEnabled(true);
webview_comp.getSettings().setAllowContentAccess(true);
webview_comp.getSettings().setAllowFileAccess(true);
webview_comp.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webview_comp.getSettings().setAppCachePath(url);
webview_comp.getSettings().setAppCacheEnabled(true);
webview_comp.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
url?.let { webview_comp.loadUrl(it) };
if i use Action_view
val pdfOpenintent = Intent(Intent.ACTION_VIEW)
pdfOpenintent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
pdfOpenintent.setDataAndType(Uri.fromFile(getpathhh), "*/*")
try {
startActivity(pdfOpenintent)
} catch (e: ActivityNotFoundException) {
}
im getting crash as 'E/UncaughtException: android.os.FileUriExposedException: file:///data/user/0/com.xyzapp.app/cache/temp_file.docx exposed beyond app through Intent.getData()'
following what i have tried
val pdfOpenintent = Intent(Intent.ACTION_VIEW)
pdfOpenintent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
pdfOpenintent.setDataAndType(
FileProvider.getUriForFile(
applicationContext,
"com.xyzapp.app.provider",
getpathhh
), "*/*")
try {
startActivity(pdfOpenintent)
} catch (e: ActivityNotFoundException) {
}
/data/user/0/com.xyzapp.app/cache/temp_file.docx
A WebView is for .html documents.
It cannot display a .docx file.
Iam trying to open a saved pdf file from the internal cache dir.
In the "old" way my code looked liked this.
In jetpack compose i can use this part of code, the pdf is beeining created and i can see it in the device explorer. But how can i display the pdf on screen ?
fun decodeTestPdfString(pdf_string:String, context:Context) {
//make FileOutPutStream
var fos: FileOutputStream? = null
try {
if (pdf_string != null) {
f = File(context?.cacheDir, "testFile" + ".pdf")
f!!.createNewFile()
fos = FileOutputStream(f)
val decodedString: ByteArray = Base64.decode(pdf_string, Base64.DEFAULT)
fos.write(decodedString)
fos.flush()
fos.close()
}
} catch (e: Exception) {
} finally {
if (fos != null) {
fos = null
}
}
val path: Uri = FileProvider.getUriForFile(context!!, context!!.getApplicationContext().getPackageName() + ".provider", f!!)
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(path, "application/pdf")
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
try {
startActivity(intent)
} catch (e: ActivityNotFoundException) {
}
}
}
But the last step (try intent) is giving an issue.
The file is created in the cache dir, i can see it.
To open the pdf reader:
startActivity(context, intent, options:null)
I'm trying to display in the pdf intent of android an file using his Uri, but it seems that I always get an blank pdf and don't know why, can someone give me some advice why.
Code:
private fun pdfConverter(pdfFile: DtoSymptomCheckerPdf?) {
val documentsPath = File(context?.filesDir, "documents")
if(!documentsPath.exists()){
documentsPath.mkdir()
}
val file = File(documentsPath, pdfFile?.filename)
val pdfAsBytes: ByteArray = android.util.Base64.decode(pdfFile?.file, 0)
val os = FileOutputStream(file,false)
os.write(pdfAsBytes)
os.flush()
os.close()
println("EL CONTENT: " + file.length())
val uri = FileProvider.getUriForFile(App.applicationContext,
BuildConfig.APPLICATION_ID + ".provider", file)
val pdfIntent = Intent(Intent.ACTION_VIEW)
pdfIntent.setDataAndType(uri, "application/pdf")
pdfIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
try {
startActivity(pdfIntent)
} catch (e: ActivityNotFoundException) {
Toast.makeText(requireContext(), "Can't read pdf file",
Toast.LENGTH_SHORT).show()
}
}
Through base64 string iam creating a pdf file.
This pdf file is succesfully created and stored in data/users/0/cache
On a button click i want to show this pdf file.
Function in kotlin:
fun decodeArbeidscontractString() {
var fos: FileOutputStream? = null
try {
f = File(context?.cacheDir, "newPdf_f.pdf")
f!!.createNewFile()
fos = FileOutputStream(f)
val decodedString: ByteArray = Base64.decode(pdf_string_arbeidscontract,
Base64.DEFAULT)
fos.write(decodedString) //write the base64 to the pdf
fos.flush()
fos.close()
val path: Uri = Uri.fromFile(f)
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(path, "application/pdf")
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
try {
startActivity(intent)
} catch (e: ActivityNotFoundException) {
}
}
I can see the file in the emulator but cannot open it. How can i do that