Can't Open PDF file in the storage android 10 [duplicate] - java

This question already has answers here:
Accessing external storage in Android API 29
(2 answers)
Closed 2 years ago.
I have a pdf file in the Download Storage and I try show it using intent, I already have three PDF viewer apps, but none of them sucessfully show the file, but if I open the pdf directly via file explorer its show just fine.
here is my code :
File kuda = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file1 = new File(kuda,"KK.pdf");
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri= FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID+".provider",file1);
intent.setDataAndType(uri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
my manifest :
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
provider paths :
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="Download/"/>
<files-path name="files" path="files/" />
</paths>
I'm using android 10
please help. thanks

Yea, things changed after OS 10, you have to write logic in new way. Sample where we get some response using retrofit and using those byte[], working in my apps. Put this code in your android component(activity for example). Invoking viewModel.getPdfBytes() is response from backend!
private static final int CREATE_FILE = 23;
private void saveFileToStorageIntent() {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf"));
intent.putExtra(Intent.EXTRA_TITLE, getString(R.string.text_export_pdf_file_first) + getDateString() + getString(R.string.text_export_pdf_file));
startActivityForResult(intent, CREATE_FILE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CREATE_FILE) {
if (resultCode == Activity.RESULT_OK && data != null) {
writePDFToFile(data.getData(), viewModel.getPdfBytes());
}
}
}
private void writePDFToFile(Uri uri, ResponseBody body){
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = getContentResolver().openOutputStream(uri);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
Logger.print(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
openFileWithIntent(uri,"pdf", getString(R.string.open_file));
} catch (Exception e) {
Logger.print(TAG, e.getMessage());
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void openFileWithIntent(Uri fileUri, String typeString, String openTitle) {
Intent target = new Intent(Intent.ACTION_VIEW);
target.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
target.setDataAndType(
fileUri,
MimeTypeMap.getSingleton().getMimeTypeFromExtension(typeString)
); // For now there is only type 1 (PDF).
Intent intent = Intent.createChooser(target, openTitle);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
if (BuildConfig.DEBUG) e.printStackTrace();
Toast.makeText(context, getString(R.string.error_no_pdf_app), Toast.LENGTH_SHORT).show();
FirebaseCrashlytics.getInstance().log(getString(R.string.error_no_pdf_app));
FirebaseCrashlytics.getInstance().recordException(e);
}
}

Related

How to render PDF file from Internal storage inside Android App using PdfRenderer

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();
}
}

java.io.FileNotFoundException: open failed: ENOENT error in android

I am trying to get the file from picking image from photos and get intent data, save the file in internal memory and use the file to load on Image views.
But I am getting the error as follows:
java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.dailyfaithapp.dailyfaith/Files/MI_10052020_1711.png: open failed: ENOENT (No such file or directory)
I checked on the lower version of api i.e. on 24 it worked once or twice but again it failed.
And on api 29 its not working at all. For that I followed this url :
https://medium.com/#sriramaripirala/android-10-open-failed-eacces-permission-denied-da8b630a89df
I checked the code in java and tried the same but still its giving the error.
I am also checking for runtime permissions and have specified permissions in manifest file.
Following is my code:
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name = "android.permission.WAKE_LOCK" />
<uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name = "com.google.android.apps.photos.permission.GOOGLE_PHOTOS" />
Checking runtime permissions :
private boolean checkPermission() {
return ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
;
}
private void requestPermissionAndContinue() {
if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, WRITE_EXTERNAL_STORAGE)
&& ActivityCompat.shouldShowRequestPermissionRationale(this, READ_EXTERNAL_STORAGE)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Allow Daily Faith to access photos," +
"media, and files on your device?");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(ThemesActivity.this,
new String[]{WRITE_EXTERNAL_STORAGE
, READ_EXTERNAL_STORAGE}, 200);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
Log.e("", "permission denied, show dialog");
} else {
ActivityCompat.requestPermissions(ThemesActivity.this,
new String[]{WRITE_EXTERNAL_STORAGE,
READ_EXTERNAL_STORAGE}, 200);
}
} else {
selectImageFromGallery();
}
}
Checking if permission is given:
if (!checkPermission()) {
selectImageFromGallery();
} else {
if (checkPermission()) {
requestPermissionAndContinue();
} else {
selectImageFromGallery();
}
}
Opening intent :
public void selectImageFromGallery()
{
Intent pickPhoto = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto , 2);
}
Get intent data on result :
#RequiresApi(api = Build.VERSION_CODES.KITKAT) #Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a image.
// The Intent's data Uri identifies which item was selected.
if (data != null) {
customTheme = true;
// This is the key line item, URI specifies the name of the data
mImageUri = data.getData();
// Saves image URI as string to Default Shared Preferences
SharedPreferencesData sharedPreferencesData =
new SharedPreferencesData(this);
sharedPreferencesData.setStr("customThemeSet","true");
try {
Bitmap bitmap =
MediaStore.Images.Media.getBitmap(getContentResolver(), mImageUri);
/* Utils.storeImage(bitmap,
ThemesActivity.this);
File file = Utils.getOutputMediaFile(ThemesActivity.this);
*/
try {
final ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(
mImageUri, "r");
final FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
Utils.storeImage(bitmap,
ThemesActivity.this);
File file = Utils.getOutputMediaFile(ThemesActivity.this);
int color = Utils.getDominantColor(bitmap);
Log.d("Bitmap", bitmap.toString());
Boolean isDark = Utils.isColorDark(color);
if(customTheme) {
for (Themes themes : themesArrayList) {
themes.setCustomTheme(file.getPath());
themes.setDark(isDark);
}
if(isDark)
sharedPreferencesData.setStr("ThemeColor","dark");
else
sharedPreferencesData.setStr("ThemeColor","light");
themesAdapter = new ThemesAdapter(themesArrayList, this,customTheme);
recyclerView.setAdapter(themesAdapter);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
Log.e("Failed", "Failed to Parse Image Uri", e);
try {
throw new Exception("failed to parse image uri");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}
}
Saving and getting file
public static File getOutputMediaFile(Context context){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ context.getApplicationContext().getPackageName()
+ "/Files");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
mediaStorageDir.mkdirs();
}
else {
return null;
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName="MI_"+ timeStamp +".png";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
public static void storeImage(Bitmap image,Context context) {
File pictureFile = getOutputMediaFile(context);
if (pictureFile == null) {
Log.d(TAG,
"Error creating media file, check storage permissions: ");// e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
Before I was getting EACCESS error when I only used above two funtions to save the file.
Later I tried Parcel file descriptor but not working
Why am I getting this error? Is it only on api level 29 or below too?
What can be the solution for this to run on all devices?
Here is what worked for me Using the downloads folder which all phones old and new have public access to..
try{
File csvfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/brcOrdersaved.csv");
final String filename = csvfile.toString();
if (!csvfile.exists()) {
// displayMsg(context, "No Saved Order: ");
return (false);
}
FileReader fr = new FileReader(filename);
BufferedReader reader = new BufferedReader(fr);
String csvLine = "";
final char Separator = ',';
final char Delimiter = '"';
final char LF = '\n';
final char CR = '\r';
boolean quote_open = false;
if (reader.equals(null)) {
displayMsg(context, "NULL");
return (false);//rww 11/13/2021
}
int i = 0;
while (!myendofcsvfile) {
csvLine = reader.readLine();
if (csvLine == null) {
myendofcsvfile = true;
}
// do stuff here
}
fr.close();
fileexists = true;
} catch (Exception e) {
String msg = "Can not Load Saved Order ";
fileexists = false;
return (fileexists);
}
I add this permissions, and it works.
<uses-permission
enter code hereandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />

Opening a downloaded file and copying it

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.

Downloading a PDF and displaying it (FileUriExposedException)

As a preface, I am familiar with coding (2 years in highschool) but am a complete novice when it comes to Android Studio (and Java, in general). I've been searching for solutions for my problem, but due to my inexperience I have no idea how to implement the solutions to my project.
In short, I need to download a pdf from some external URL, store it into external storage, and display it using some pdf-viewer application. I've been getting error:
...
android.os.FileUriExposedException: file:///storage/emulated/0/pdf/Read.pdf exposed beyond app through Intent.getData()
...
I've been using this source on using an intent to open a pdf-viewer and this source on "File Provider" as references.
Below is what I have so far:
Fire (with a clickable TextView that should download and display the pdf)
public class Fire extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fire);
final TextView testButton = findViewById(R.id.testPDF);
// File file = getFilesDir();
testButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Fire.this, pdfView.class);
startActivity(intent);
}
});
pdfView activity
public class pdfView extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_view);
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, "pdf");
folder.mkdir();
File file = new File(folder, "Read.pdf");
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
Downloader.DownloadFile(__PDF_URL___, file);
showPdf();
}
public void showPdf()
{
File file = new File(Environment.getExternalStorageDirectory()+"/pdf/Read.pdf");
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
}
Downloader class
public class Downloader {
public static void DownloadFile(String fileURL, File directory) {
try {
FileOutputStream f = new FileOutputStream(directory);
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
e.printStackTrace();
}
}
From my research, it seems that my problem stems from my usage of URI instead of a "File provider." Also, it seems the solution that implements a "File Provider" uses Context in some form or another, and I'm confused on what the purpose of context is and how to implement it.
If you do not have answers that is fine. Any information on how to figure this out or even understand the concept is good enough for me.
If your targetSdkVersion >= 24, then we have to use FileProvider class to give access to the particular file or folder to make them accessible for other apps.
1) First Add a FileProvider tag in AndroidManifest.xml under tag as below:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
<application
...
<provider
android:name=".GenericFileProvider"
android:authorities="${applicationId}.my.package.name.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
</application>
</manifest>
2) Then create a provider_paths.xml file in res/xml folder. Folder may be needed to created if it doesn't exist.
<paths>
<external-path name="external_files" path="."/>
</paths>
3) Now create PdfDownload.java class file and paste below code:
public class PdfDownload extends Activity {
TextView tv_loading;
Context context;
int downloadedSize = 0, totalsize;
float per = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
isStoragePermissionGranted();
super.onCreate(savedInstanceState);
tv_loading = new TextView(this);
tv_loading.setGravity(Gravity.CENTER);
tv_loading.setTypeface(null, Typeface.BOLD);
setContentView(tv_loading);
downloadAndOpenPDF();
}
public static String getLastBitFromUrl(final String url) {
return url.replaceFirst(".*/([^/?]+).*", "$1");
}
void downloadAndOpenPDF() {
final String download_file_url = getIntent().getStringExtra("url");
new Thread(new Runnable() {
public void run() {
Uri path = Uri.fromFile(downloadFile(download_file_url));
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri uri = FileProvider.getUriForFile(PdfDownload.this, BuildConfig.APPLICATION_ID, downloadFile(download_file_url));
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
finish();
} catch (ActivityNotFoundException e) {
tv_loading
.setError("PDF Reader application is not installed in your device");
}
}
}).start();
}
File downloadFile(String dwnload_file_path) {
File file = null;
try {
URL url = new URL(dwnload_file_path);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.connect();
String test = getLastBitFromUrl(dwnload_file_path);
String dest_file_path = test.replace("%20", "_");
// set the path where we want to save the file
File SDCardRoot = Environment.getExternalStorageDirectory();
// // create a new file, to save the downloaded file
file = new File(SDCardRoot, dest_file_path);
if (file.exists()) {
return file;
}
FileOutputStream fileOutput = new FileOutputStream(file);
// Stream used for reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
// this is the total size of the file which we are
// downloading
totalsize = urlConnection.getContentLength();
setText("Starting PDF download...");
// create a buffer...
byte[] buffer = new byte[1024 * 1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
per = ((float) downloadedSize / totalsize) * 100;
if ((totalsize / 1024) <= 1024) {
setText("Total PDF File size : " + (totalsize / 1024)
+ " KB\n\nDownloading PDF " + (int) per + "% complete");
} else {
setText("Total PDF File size : " + (totalsize / 1024) / 1024
+ " MB\n\nDownloading PDF " + (int) per + "% complete");
}
// setText("configuring your book pleease wait a moment");
}
// close the output stream when complete //
fileOutput.close();
// setText("Download Complete. Open PDF Application installed in the device.");
setText("configuaration is completed now your book is ready to read");
} catch (final MalformedURLException e) {
setTextError("Some error occured. Press back and try again.",
Color.RED);
} catch (final IOException e) {
setTextError("Some error occured. Press back and try again.",
Color.RED);
} catch (final Exception e) {
setTextError(
"Failed to download image. Please check your internet connection.",
Color.RED);
}
return file;
}
void setTextError(final String message, final int color) {
runOnUiThread(new Runnable() {
public void run() {
tv_loading.setTextColor(color);
tv_loading.setText(message);
}
});
}
void setText(final String txt) {
runOnUiThread(new Runnable() {
public void run() {
tv_loading.setText(txt);
}
});
}
private static final String TAG = "MyActivity";
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission is granted");
return true;
} else {
Log.v(TAG, "Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
} else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG, "Permission is granted");
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission: " + permissions[0] + "was " + grantResults[0]);
}
}
}

File not found error after selecting a file in android

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();
}
}
});

Categories