I want to open a .pdf file in my android app.now i can browse the pdf file and after browsing the file I am getting File Not Found Error when i check the file exist or not. Now after selecting the file my selected file Uri data.getData() is like
content://com.android.externalstorage.documents/document/6333-6131:SHIDHIN.pdf
and the path when i parse using data.getData().getPath().toString() is like
/document/6333-6131:SHIDHIN.pdf Here is my code. Please Help me.
// To Browse the file
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf");
startActivityForResult(intent, PICK_FILE_REQUEST);
After selecting file
//onActivityResult
public void onActivityResult(final int requestCode, int resultCode, Intent data) {
try {
switch (requestCode) {
case PICK_FILE_REQUEST:
if (resultCode == RESULT_OK) {
try {
Uri fileUri = data.getData();
String path = fileUri.getPath().toString();
File f = new File(path);
if (f.exists()) {
System.out.println("\n**** Uri :> "+fileUri.toString());
System.out.println("\n**** Path :> "+path.toString());
final Intent intent = new Intent(MainActivity.this, ViewPdf.class);
intent.putExtra(PdfViewerActivity.EXTRA_PDFFILENAME, path);
startActivity(intent);
} else {
System.out.println("\n**** File Not Exist :> "+path);
}
} catch (Exception e) {
ShowDialog_Ok("Error", "Cannot Open File");
}
}
break;
}
} catch (Exception e) {
}
}
This is not the answer but a workaround.
File file = new File("some_temp_path"); # you can also use app's internal cache to store the file
FileOutputStream fos = new FileOutputStream(file);
InputStream is = context.getContentResolver().openInputStream(uri);
byte[] buffer = new byte[1024];
int len = 0;
try {
len = is.read(buffer);
while (len != -1) {
fos.write(buffer, 0, len);
len = is.read(buffer);
}
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
pass this file's absolute path to your activity.
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
File pdfFile = new File(Environment.getExternalStorageDirectory(), "Case Study.pdf");
try {
if (pdfFile.exists()) {
Uri path = Uri.fromFile(pdfFile);
Intent objIntent = new Intent(Intent.ACTION_VIEW);
objIntent.setDataAndType(path, "application/pdf");
objIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(objIntent);
} else {
Toast.makeText(MainActivity.this, "File NotFound", Toast.LENGTH_SHORT).show();
}
} catch (ActivityNotFoundException e) {
Toast.makeText(MainActivity.this, "No Viewer Application Found", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
Related
I am trying to give a preview of PDF to the user before uploading it to a server. I am using PdfRenderer. I just to give the preview of the 1st page. On Start, I am calling the file chooser function that lets you select a pdf file from Internal memory, and on ActivityResult the render function is called, however, I am facing an error
I/System.out: Cursor= android.content.ContentResolver$CursorWrapperInner#a8d29d4
Uri String= content://com.adobe.scan.android.documents/document/root%3A23
File pathcontent://com.adobe.scan.android.documents/document/root%3A23
W/System.err: java.lang.IllegalArgumentException: Invalid page index
at android.graphics.pdf.PdfRenderer.throwIfPageNotInDocument(PdfRenderer.java:282)
at android.graphics.pdf.PdfRenderer.openPage(PdfRenderer.java:229)
at com.ay404.androidfileloaderreader.CustomFunc.Main2Activity.openPdfFromStorage(Main2Activity.java:56)
Here is my code:
#RequiresApi(api=Build.VERSION_CODES.LOLLIPOP)
private void openPdfFromStorage(Uri uri,String filename) throws IOException {
File fileCopy = new File(getCacheDir(), filename);//anything as the name
copyToCache(fileCopy, uri);
ParcelFileDescriptor fileDescriptor =
ParcelFileDescriptor.open(fileCopy,
ParcelFileDescriptor.MODE_READ_ONLY);
mPdfRenderer = new PdfRenderer(fileDescriptor);
mPdfPage = mPdfRenderer.openPage(1);
Bitmap bitmap = Bitmap.createBitmap(mPdfPage.getWidth(),
mPdfPage.getHeight(),
Bitmap.Config.ARGB_8888);//Not RGB, but ARGB
mPdfPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
imageView.setImageBitmap(bitmap);
}
void copyToCache(File file,Uri uri) throws IOException {
if (!file.exists()) {
InputStream input = getContentResolver().openInputStream(uri);
FileOutputStream output = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int size;
while ((size = input.read(buffer)) != -1) {
output.write(buffer, 0, size);
}
input.close();
output.close();
}
}
RequiresApi(api=Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_PDF_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
Uri uri = data.getData();
String uriString=uri.toString();
File myFile=new File(uriString);
String displayName=null;
Cursor cursor=null;
Log.e("URI: ", uri.toString());
try {
if (uriString.startsWith("content://")) {
try {
cursor=getApplicationContext().getContentResolver().query(uri, null, null, null, null);
System.out.println("Cursor= " + cursor);
System.out.println("Uri String= " + uriString);
System.out.println("File path" + data.getData());
if (cursor != null && cursor.moveToFirst()) {
displayName=cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
openPdfFromStorage(uri,displayName);
File imgFile=new File(String.valueOf(data.getData()));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
cursor.close();
}
} else if (uriString.startsWith("file://")) {
System.out.println("Uri String= " + uriString);
System.out.println("File path" + myFile.getAbsolutePath());
displayName=myFile.getName();
try {
openPdfFromStorage(uri,displayName);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void fileChoser(){
Intent intent=new Intent();
intent.setType("application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Pdf"), PICK_PDF_REQUEST);
}
#Override
protected void onStart() {
super.onStart();
fileChoser();
}
}
Found the fix, the path needs to be static, therefore, I am copying the files to cache and then opening them from cache location
private void showPdf(String base64, String filename) {
String fileName = "test_pdf ";
try {
final File dwldsPath = new File(this.getExternalFilesDir(String.valueOf(this.getCacheDir()))+"/"+filename);
Log.d("File path", String.valueOf(dwldsPath));
byte[] pdfAsBytes = Base64.decode(base64, 0);
FileOutputStream os;
os = new FileOutputStream(dwldsPath, false);
os.write(pdfAsBytes);
os.flush();
os.close();
Uri uri = FileProvider.getUriForFile(this,
BuildConfig.APPLICATION_ID + ".provider",
dwldsPath);
fileName="";
String mime = this.getContentResolver().getType(uri);
openPDF(String.valueOf(dwldsPath),fileName);
} catch(Exception e){
e.printStackTrace();
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri selected = data.getData();
File file = new File(String.valueOf(selected));
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[(int) file.length()];
try {
for (int readnum; (readnum = fis.read(buf)) != -1; ) {
bos.write(buf, 0, readnum);
}
} catch (Exception e) {
e.printStackTrace();
}
byte[] bytes = bos.toByteArray();
ParseFile parseFile =new ParseFile("video.mp4",bytes);
ParseObject parseObject = new ParseObject("video2");
parseObject.put("video2", parseFile);
parseObject.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Toast.makeText(userlist.this, "video has been uploaded successfully :)", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(userlist.this, "sorry we could't upload the video ", Toast.LENGTH_SHORT).show();
}
}
});
}
This is my current code. I managed to access the phone gallery and then I convert the video to byte array to be able to upload it to Parse but i guess the problem is that any video i choose returns null i access the gallery using this code :
public class userlist extends AppCompatActivity {
public void getphoto() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 1);
}
here is my stack trace
java.io.FileNotFoundException: content:/media/external/video/media/14146 (No such file or directory)
2020-07-05 17:28:03.965 31930-31930/com.parse.starter W/System.err: at com.parse.starter.userlist.onActivityResult(userlist.java:85)
2020-07-05 17:28:03.967 31930-31930/com.parse.starter W/System.err: at com.parse.starter.userlist.onActivityResult(userlist.java:92)
2020-07-05 17:28:03.981 31930-32065/com.parse.starter W/System: Ignoring header Content-Type because its value was null.
I am writing an App to save files (pictures) as a certain name given by a column from csv-file. The user have to choose the csv with the filebrowser first and then the file will be copyied to my Dir-Data directory.
Everything worsk fine but it seems like the Path i get form the File src Object doesn't work with the Operation.
I expect the error obviously here(2nd Code-Box)
And sry in advance if it is obvious/easy to avoid, it is my first Android-Project ever.
I already tryed to use different Copy Functions with different parameter types and also tryed other formats such as String given by uri.toString().
//CSV Opener
public void performFileSearch() {
// ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
// browser.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
// Filter to only show results that can be "opened"
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Filter to show only .csv using the image MIME data type.
// For all it would be "*/*".
intent.setType("text/comma-separated-values");
startActivityForResult(intent, READ_REQUEST_CODE);
}
//create paths
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK)
{
if (resultData != null) {
Uri path = resultData.getData();
stringUri = path.getPath();
File src = new File(stringUri);
File destination = new File(getFilesDir().getPath());
try {
copyDirectoryOneLocationToAnotherLocation(src,destination);
}
catch(IOException e) {
e.printStackTrace();
System.out.print("error in upload");
}
Toast.makeText(MainActivity.this, "Path: "+stringUri , Toast.LENGTH_SHORT).show();
}
}
}
//copy-operation from StackOverflow
public static void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation)
throws IOException {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
String[] children = sourceLocation.list();
for (int i = 0; i < sourceLocation.listFiles().length; i++) {
copyDirectoryOneLocationToAnotherLocation(new File(sourceLocation, children[i]),
new File(targetLocation, children[i]));
}
} else {
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
I want the choosen file to be copied in my data/data/... directory to be used later in the App.
BUT: the path i get from the objets doesn`t work for me
Thx #Mike M. , the tip with using getContentResolver() brougth me the anwser after trying around.
Finally is used an other Copy funktion and reworked the onActivityResult();
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK)
{
if (resultData != null) {
try {
String destination = getFilesDir().getPath();
InputStream src = getContentResolver().openInputStream(resultData.getData()); // use the uri to create an inputStream
try {
convertInputStreamToFile(src, destination);
} catch (IOException e) {
e.printStackTrace();
System.out.print("error in upload");
}
} catch (FileNotFoundException ex) {
}
String destination = getFilesDir().getPath();
Toast.makeText(MainActivity.this, "Success!: CSV-File copyed to : " +destination , Toast.LENGTH_SHORT).show();
}
}
}
public static void convertInputStreamToFile(InputStream is, String destination) throws IOException
{
OutputStream outputStream = null;
try
{
File file = new File(destination + "/Student.csv");
outputStream = new FileOutputStream(file);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = is.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
}
finally
{
if(outputStream != null)
{
outputStream.close();
}
}
}
Hello I am tring to open a .pdf file present in a file using an intent but it is giving me 2 errors on the following line
File file = new File(getContext().getAssets().open("assets/test.pdf"));
Errors
1.Unhandled java.IO.Exception.
2.getAssets()may produce java.lang.NullPointerException
Here us the code in a fragment
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0) {
File file = new File(getContext().getAssets().open("assets/test.pdf"));
if (file .exists())
{
Uri path = Uri.fromFile(file );
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path , "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try
{
startActivity(pdfIntent ); }
catch (ActivityNotFoundException e)
{
Toast.makeText(getActivity(), "Please install a pdf file viewer",
Toast.LENGTH_LONG).show();
}
}
}
}
File fileBrochure = new File(Environment.getExternalStorageDirectory() + "/" + "abc.pdf");
if (!fileBrochure.exists())
{
CopyAssetsbrochure();
}
/** PDF reader code */
File file = new File(Environment.getExternalStorageDirectory() + "/" + "abc.pdf");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try
{
getApplicationContext().startActivity(intent);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(SecondActivity.this, "NO Pdf Viewer", Toast.LENGTH_SHORT).show();
}
}
//method to write the PDFs file to sd card
private void CopyAssetsbrochure() {
AssetManager assetManager = getAssets();
String[] files = null;
try
{
files = assetManager.list("");
}
catch (IOException e)
{
Log.e("tag", e.getMessage());
}
for(int i=0; i<files.length; i++)
{
String fStr = files[i];
if(fStr.equalsIgnoreCase("abc.pdf"))
{
InputStream in = null;
OutputStream out = null;
try
{
in = assetManager.open(files[i]);
out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/" + files[i]);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
break;
}
catch(Exception e)
{
Log.e("tag", e.getMessage());
}
}
}
}
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);
}
You cannot open the pdf file directly from the assets folder.You first have to write the file to sd card from assets folder and then read it from sd card
try with the file provider
Intent intent = new Intent(Intent.ACTION_VIEW);
// set flag to give temporary permission to external app to use your FileProvider
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// generate URI, I defined authority as the application ID in the Manifest, the last param is file I want to open
String uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, file);
// I am opening a PDF file so I give it a valid MIME type
intent.setDataAndType(uri, "application/pdf");
// validate that the device can open your File!
PackageManager pm = getActivity().getPackageManager();
if (intent.resolveActivity(pm) != null) {
startActivity(intent);
}
To serve a file from assets to another app you need to use a provider.
Google for the StreamProvider of CommonsWare.
I am trying to open a file I demand from my user to download so I can use it so I am trying to copy it to my internal storage.
I tried using this code:
Intent myIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
myIntent.setType("text/*");
myIntent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(myIntent, 100);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) {
if(resultCode == Activity.RESULT_OK){
Uri result= data.getData();
Log.e("fag", result.getPath());
copyFile(result);
}
if (resultCode == Activity.RESULT_CANCELED) {
Log.e("", "canceled");
}
}
Intent a = new Intent(getApplicationContext(), MainActivity.class);
startActivity(a);
}
private void copyFile(Uri inputFile) {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(inputFile.getPath());
out = openFileOutput(NAME , MODE_PRIVATE);
byte[] buffer = new byte[1024];
while ( in.read(buffer) != -1) {
out.write(buffer);
}
in.close();
in = null;
out.close();
out = null;
} catch (FileNotFoundException fnfe1) {
Log.e("tag", fnfe1.getMessage());
fnfe1.printStackTrace();
}
catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
But when I run this code, I got a File Not Found Exception. so I checked what URI I get from the intent and it isn't the path to the file but this path
/document/primary:Download/5643_05072018-13-48.csv
and I don't know how to use this URI.
I got a simmmilar resualt using the ACTION_GET_CONTENT intent.
So my question is can I use this code and the URI that I got to copy that file or I need to do it in an other way? and how in both cases?
in = new FileInputStream(inputFile.getPath());
Change to:
InputStream is = getContentResolver().openInputStream(inputFile);
And dont name that inputFile but uri.