Android 9 (API level 28) introduces great new features and capabilities for users and developers. Some of the changes impacts File Write and Read. The following is a solution to the File Write / Read problem for pdf files
Code Structure
Code Structure
GenericFileProvider.java
package com.zackdawood; import android.support.v4.content.FileProvider; public class GenericFileProvider extends FileProvider { }
FileDownloader.javapackage com.zackdawood; import android.util.Log; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class FileDownloader { private static final String TAG = "FileDownloader"; private static final int MEGABYTE = 1024 * 1024; public static void downloadFile(String fileUrl, File directory) { try { Log.v(TAG, "downloadFile() invoked "); Log.v(TAG, "downloadFile() fileUrl " + fileUrl); Log.v(TAG, "downloadFile() directory " + directory); URL url = new URL(fileUrl); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.connect(); InputStream inputStream = urlConnection.getInputStream(); FileOutputStream fileOutputStream = new FileOutputStream(directory); int totalSize = urlConnection.getContentLength(); byte[] buffer = new byte[MEGABYTE]; int bufferLength = 0; while ((bufferLength = inputStream.read(buffer)) > 0) { fileOutputStream.write(buffer, 0, bufferLength); } fileOutputStream.close(); Log.v(TAG, "downloadFile() completed "); } catch (FileNotFoundException e) { e.printStackTrace(); Log.e(TAG, "downloadFile() error" + e.getMessage()); Log.e(TAG, "downloadFile() error" + e.getStackTrace()); } catch (MalformedURLException e) { e.printStackTrace(); Log.e(TAG, "downloadFile() error" + e.getMessage()); Log.e(TAG, "downloadFile() error" + e.getStackTrace()); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "downloadFile() error" + e.getMessage()); Log.e(TAG, "downloadFile() error" + e.getStackTrace()); } } }
MainActivity.javaAndroidManifest.xmlpackage com.zackdawood; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.support.v4.app.ActivityCompat; import android.support.v4.content.FileProvider; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Toast; import java.io.File; import java.io.IOException; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private static final String[] PERMISSIONS = {android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE}; private static boolean hasPermissions(Context context, String... permissions) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) { for (String permission : permissions) { if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } } return true; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.v(TAG, "onCreate() Method invoked "); ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS, 112); } public void request(View view) { ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS, 112); } public void view(View view) { Log.v(TAG, "view() Method invoked "); if (!hasPermissions(MainActivity.this, PERMISSIONS)) { Log.v(TAG, "download() Method DON'T HAVE PERMISSIONS "); Toast t = Toast.makeText(getApplicationContext(), "You don't have read access !", Toast.LENGTH_LONG); t.show(); } else { File d = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); // -> filename = maven.pdf File pdfFile = new File(d, "maven.pdf"); Log.v(TAG, "view() Method pdfFile " + pdfFile.getAbsolutePath()); Uri path = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", pdfFile); Log.v(TAG, "view() Method path " + path); Intent pdfIntent = new Intent(Intent.ACTION_VIEW); pdfIntent.setDataAndType(path, "application/pdf"); pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); try { startActivity(pdfIntent); } catch (ActivityNotFoundException e) { Toast.makeText(MainActivity.this, "No Application available to view PDF", Toast.LENGTH_SHORT).show(); } } Log.v(TAG, "view() Method completed "); } public void download(View view) { Log.v(TAG, "download() Method invoked "); if (!hasPermissions(MainActivity.this, PERMISSIONS)) { Log.v(TAG, "download() Method DON'T HAVE PERMISSIONS "); Toast t = Toast.makeText(getApplicationContext(), "You don't have write access !", Toast.LENGTH_LONG); t.show(); } else { Log.v(TAG, "download() Method HAVE PERMISSIONS "); //new DownloadFile().execute("http://maven.apache.org/maven-1.x/maven.pdf", "maven.pdf"); new DownloadFile().execute("http://www.axmag.com/download/pdfurl-guide.pdf", "maven.pdf"); } Log.v(TAG, "download() Method completed "); } private class DownloadFile extends AsyncTask<String, Void, Void> { @Override protected Void doInBackground(String... strings) { Log.v(TAG, "doInBackground() Method invoked "); String fileUrl = strings[0]; // -> http://maven.apache.org/maven-1.x/maven.pdf String fileName = strings[1]; // -> maven.pdf String extStorageDirectory = Environment.getExternalStorageDirectory().toString(); File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); File pdfFile = new File(folder, fileName); Log.v(TAG, "doInBackground() pdfFile invoked " + pdfFile.getAbsolutePath()); Log.v(TAG, "doInBackground() pdfFile invoked " + pdfFile.getAbsoluteFile()); try { pdfFile.createNewFile(); Log.v(TAG, "doInBackground() file created" + pdfFile); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "doInBackground() error" + e.getMessage()); Log.e(TAG, "doInBackground() error" + e.getStackTrace()); } FileDownloader.downloadFile(fileUrl, pdfFile); Log.v(TAG, "doInBackground() file download completed"); return null; } } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.zackdawood"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:networkSecurityConfig="@xml/network_security_config"> <provider android:name=".GenericFileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/external_files"/> </provider> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/button3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="200px" android:onClick="download" android:text="@string/file_download" /> <Button android:id="@+id/button4" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="200px" android:onClick="view" android:text="@string/file_view" /> <Button android:id="@+id/button5" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="200px" android:onClick="request" android:text="@string/file_request" /> </LinearLayout> </android.support.design.widget.CoordinatorLayout>
strings.xml<resources> <string name="app_name">DemoInternalDownload</string> <string name="action_settings">Settings</string> <string name="file_view">File View</string> <string name="file_download">File Download</string> <string name="file_request">Request Access Again</string> </resources>
external_files.xml<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="external_files" path="."/> </paths>
network_security_config.xml<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">maven.apache.org</domain> <domain includeSubdomains="true">www.axmag.com</domain> </domain-config> </network-security-config>
build.gradleapply plugin: 'com.android.application' android { compileSdkVersion 28 defaultConfig { applicationId "com.zackdawood" minSdkVersion 15 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' }
Prompt ScreenOutput Screen
Very Helpful Post...!!! Keep it up.....
ReplyDeleteIf you want to make custom website & application you can contact us on our Web App Development Company and Android App Development Company anytime.
i need to implement progress bar when file is downloading i tried
ReplyDeletemany times but i failed .. can u help me .
Really great info you provided here.
ReplyDeleteThank You
Operations Management Assignment Writing Services
Information Technology Assignments Help
Strategic Marketing Management Assignments
Human Resource Management Assignment Help
MANAGEMENT ASSIGNMENT WRITING SERVICES
Marketing Assignment Writing Help
Really great info you provide here
ReplyDeletethank you
best orthopedic hospital in jaipur
best orthopedic doctor in jaipur
Sports injury treatment in jaipur
joint replacement hospital in jaipur
knee replacement doctor in jaipur
This blog is really fantastic
ReplyDeleteBest SSC Coaching in Jaipur
Best Bank PO Coaching In Jaipur
Best SSC CGL Coaching in jaipur
Best Coaching For SSC in Jaipur
Best Coaching For Bank In Jaipur
ReplyDeleteReally great info you provided here.
Proofreading and Editing Services
Finance Assignment Writing Services
Accounting Assignment Writing Services
Law Assignment Writing Help
Nursing Assignment Writing Help
Thanks For Sharing this Amazing Article
ReplyDeleteonline assignment help services
Assignment Writing Help
Essay Writing Help
Dissertation Writing Help Services
Case Study Writing Help
This comment has been removed by the author.
ReplyDeleteReally great info you provided here.
ReplyDeleteThank You
Machine Learning Training in jaipur
Artificial Intelligence Training in Jaipur
Sales force Training in Jaipur
Java Training in Jaipur
Android Training in Jaipur
ReplyDeleteReally great info you provided here.
online assignment help services
Assignment Writing Help
Essay Writing Help
Dissertation Writing Help Services
Case Study Writing Help
Sofa dry cleaners in Jaipur
ReplyDeleteBest sofa dry cleaners in Jaipur
Best dry cleaners in Jaipur
Sofa dry cleaners in Jaipur
Best sofa dry cleaners in Jaipur
Best dry cleaners in Jaipur
Dr Shri Niwash JAngir can help you to overcome anxiety attacks with his methodologies . Visit him to get best anxiety treatment
ReplyDeleteSandeep Nunia is the best urology doctor in Jaipur. To get the best treatment for kidney stone visit Dr Sandeep Nunia
ReplyDeleteGet the best treatment for weight loss surgery or bariatric surgery at Nav Imperial Hopsital
ReplyDeleteHear again is the best speech therapy clinic of Jaipur
ReplyDeleteThank You
ReplyDeleteonline assignment help services
Assignment Writing Help
Essay Writing Help
Dissertation Writing Help Services
Case Study Writing Help
As we all know that mobile apps are the biggest requirement of firms. Protocloud Academy is a leading Android Mobile app development institute in Jaipur. Our mentors will guide you to translate software requirements into workable programming code and maintain and develop programs with the help of live project training. They will also give you in-depth concepts knowledge in Android Application Development, JAVA language, and fine use of the Latest Android Studio and deployment on Android Devices like Smart Phone or Android Tablets. After completion of the training program, our experts will give advanced training to guide students with the latest technologies. We will provide the training certificates by approved technology partners to help students crack the interview and get their dream job.
ReplyDeletehttps://www.protocloudtechnologies.com/android-app-development-course-in-jaipur/
Your work is very good and I appreciate you and hopping for some more informative posts omnichannel contact center solution
ReplyDeleteAqurius and Gemini are considered most intelligent zodiac signs. It is said that Gemini brings intelligence to the Zodiac and have best mind of all the Zodiac.
ReplyDeleteWorking as a freelancer exposes you to various work cultures and communication approaches when you deal with customers from various countries. A 9-to-5 remote java developer is cautious about taking on freelancing work because most companies do not allow their employees to do so. Eiliana is a renowned platform where you can find freelance remote java developer jobs, and this platform also assists you in maintaining secrecy.
ReplyDeleteलक्ष्मी कुबेर मंत्र कुबेर और मां लक्ष्मी का यह मंत्र जीवन की सभी प्रकार से धन को देने वाला है, कुबेर धन के अधिपति यानि धन के राजा हैं।
ReplyDeletehttps://zacktutorials.blogspot.com/2019/05/android-pdf-write-read-using-android-9.html?showComment=1618972036343#c4163542603636294636
ReplyDeleteการใช้งาน singha66 สำหรับธุรกิจของคุณที่ต้องการเข้าสู่การขายสินค้าออนไลน์ การใช้งาน singha66 PG SLOT จะเป็นตัวเลือกที่ดีอย่างแน่นอนครับ ด้วยความสะดวกและคล่องตัวในการใช้งาน
ReplyDelete