How to download PDF from byte array or byte stream - Android

How to download PDF from byte array or byte stream - Android

We can download easily pdf from byte stream, for that one have to follow some necessary steps.
Step 1 :
Have to give read and write external storage permission in AndroidMenifest.xml file :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Step 2 :
The main problem is though we gave permission but in higher android version need to give permission manually form Application settings. This is to much annoyed for any non-technical users because they want their PDF but they will not take this hassles. So we have to do this from program where user will notify he/she wants to give permission or not. This way -

public static boolean isStoragePermissionGranted(Activity activity) {
    if (Build.VERSION.SDK_INT >= 23) {
        if (ContextCompat.checkSelfPermission(activity ,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.
            //Log.v(TAG, "Permission is granted");
            return true;
        } else {
            //Toast.makeText(getApplicationContext(), "Permission is revoked",Toast.LENGTH_SHORT).show();
            //Log.v(TAG, "Permission is revoked");
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return false;
        }
    } else { //permission is automatically granted on sdk<23 upon installation
        //Toast.makeText(getApplicationContext(), "Permission is revoked",Toast.LENGTH_SHORT).show();
        //Log.v(TAG, "Permission is granted");
        return true;
    }
}

Description of this function :
If SDK version greater than 23 then App will self check and give a pop up dialogue whether user wants to give permission or not IF YES -> function will return true
And if SDK version less then 23 then function will give always true.
Step 3 :
Now the main task to write/download the bytestream as a PDF in external storage: 

private boolean writeResponseBodyToDisk(ResponseBody body) {
    try {
        // todo change the file location/name according to your needs
        time.setToNow();
        fileName = "File name" + request.getAccountNumber() + "_from" + time.format("%k : %M : %S") + ".pdf";
        //File futureStudioIconFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
        java.io.File futureStudioIconFile = new java.io.File(Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                + "/" + fileName);
        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            byte[] fileReader = new byte[4096];

            long fileSize = body.contentLength();
            long fileSizeDownloaded = 0;

            inputStream = body.byteStream();
            outputStream = new FileOutputStream(futureStudioIconFile);

            while (true) {
                int read = inputStream.read(fileReader);

                if (read == -1) {
                    break;
                }

                outputStream.write(fileReader, 0, read);

                fileSizeDownloaded += read;

                Log.d(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
            }

            outputStream.flush();

            return true;
        } catch (IOException e) {
            return false;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }

            if (outputStream != null) {
                outputStream.close();
            }
        }
    } catch (IOException e) {
        return false;
    }
}
 
Description of this function :
  • First of all I give a name of a file
  • then define the file size
  • File reader will read the whole bytestream and OutputStream will write these on Storage.
  • After whole file will read and write successfully then function will return true which mean file is downloaded successfully.
Step 4:
When download done have to show this file using intent like this way :

boolean writtenToDisk = writeResponseBodyToDisk(response.body());

if (writtenToDisk) {
    time.setToNow();
    fileName = "Statement_" + request.getAccountNumber() + "_from" + time.format("%k : %M : %S") + ".pdf";
    //File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
    java.io.File file = new java.io.File(Environment
            .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
            + "/" + fileName);
    try {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(file), "application/pdf");
        intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        startActivity(intent);
    } catch (ActivityNotFoundException e) {
        Snackbar.make(rootCoordinatorLayout, "No PDF reader found to open this file.", Snackbar.LENGTH_LONG).show();
    }

Description :
Call previous function with byte array and if return true then get the file location. After file location found then an intent will pass this file to OS and OS will show this file to regarding an application.

Conclusion:
This is the easiest way we can download PDF file from a byte array. Usage :
  • many application we download statement regarding pdf from webservice
  • webservice will send bytearray and Mobile platform duty is to show this as PDF.


Comments

Popular posts from this blog

Marquee Text Android: Using RecyclerView like Ticker

Android Spinner with Dialog Box

Comparison Between SOAP and REST