How to Read a PDF in Android

how to read pdf file file in android studio

You can view a pdf file in an android project in different ways. I will describe some of them here-

1. Using Library:
Steps are below:


Installation
Add to build.gradle:
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'


ProGuard
If you are using ProGuard, add following rule to proguard config file:

-keep class com.shockwave.**


Include PDFView in your layout

<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>


Further link is here


2. Load pdf url into webview:

webview = (WebView)findViewById(R.id.webview);
progressbar = (ProgressBar) findViewById(R.id.progressbar);
webview.getSettings().setJavaScriptEnabled(true);
String filename = file_url_with_name;
webview.loadUrl(file_url + filename);

webview.setWebViewClient(new WebViewClient() {

public void onPageFinished(WebView view, String url) {
// do your stuff here
progressbar.setVisibility(View.GONE);
}
});


3. Manually show PDF file into Imageview


// Example for creating manual PDF viewer into imageview used butterknife view binding<br/>

public class PdfRenderActivity extends AppCompatActivity {

@BindView(R.id.pdf_image) ImageView imageViewPdf;
@BindView(R.id.button_pre_doc) FloatingActionButton prePageButton;
@BindView(R.id.button_next_doc) FloatingActionButton nextPageButton;

private static final String FILENAME = "report.pdf";

private int pageIndex;
private PdfRenderer pdfRenderer;
private PdfRenderer.Page currentPage;
private ParcelFileDescriptor parcelFileDescriptor;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_render);
ButterKnife.bind(this);
pageIndex = 0;
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onStart() {
super.onStart();
try {
openRenderer(getApplicationContext());
showPage(pageIndex);
} catch (IOException e) {
e.printStackTrace();
}
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onStop() {
try {
closeRenderer();
} catch (IOException e) {
e.printStackTrace();
}
super.onStop();
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@OnClick(R.id.button_pre_doc)
public void onPreviousDocClick(){
showPage(currentPage.getIndex() - 1);
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@OnClick(R.id.button_next_doc)
public void onNextDocClick(){
showPage(currentPage.getIndex() + 1);
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void openRenderer(Context context) throws IOException {
// In this sample, we read a PDF from the assets directory.
File file = new File(context.getCacheDir(), FILENAME);
if (!file.exists()) {
// Since PdfRenderer cannot handle the compressed asset file directly, we copy it into
// the cache directory.
InputStream asset = context.getAssets().open(FILENAME);
FileOutputStream output = new FileOutputStream(file);
final byte[] buffer = new byte[1024];
int size;
while ((size = asset.read(buffer)) != -1) {
output.write(buffer, 0, size);
}
asset.close();
output.close();
}
parcelFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
// This is the PdfRenderer we use to render the PDF.
if (parcelFileDescriptor != null) {
pdfRenderer = new PdfRenderer(parcelFileDescriptor);
}
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void closeRenderer() throws IOException {
if (null != currentPage) {
currentPage.close();
}
pdfRenderer.close();
parcelFileDescriptor.close();
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void showPage(int index) {
if (pdfRenderer.getPageCount() <= index) {
return;
}
// Make sure to close the current page before opening another one.
if (null != currentPage) {
currentPage.close();
}
// Use `openPage` to open a specific page in PDF.
currentPage = pdfRenderer.openPage(index);
// Important: the destination bitmap must be ARGB (not RGB).
Bitmap bitmap = Bitmap.createBitmap(currentPage.getWidth(), currentPage.getHeight(),
Bitmap.Config.ARGB_8888);
// Here, we render the page onto the Bitmap.
// To render a portion of the page, use the second and third parameter. Pass nulls to get
// the default result.
// Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
currentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
// We are ready to show the Bitmap to user.
imageViewPdf.setImageBitmap(bitmap);
updateUi();
}

/**
* Updates the state of 2 control buttons in response to the current page index.
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void updateUi() {
int index = currentPage.getIndex();
int pageCount = pdfRenderer.getPageCount();
prePageButton.setEnabled(0 != index);
nextPageButton.setEnabled(index + 1 < pageCount);
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public int getPageCount() {
return pdfRenderer.getPageCount();
}

}

Doc is here

Android open pdf file

The problem is that there is no app installed to handle opening the PDF. You should use the Intent Chooser, like so:

File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +"/"+ filename);
Intent target = new Intent(Intent.ACTION_VIEW);
target.setDataAndType(Uri.fromFile(file),"application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Intent intent = Intent.createChooser(target, "Open File");
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
// Instruct the user to install a PDF reader here, or something
}

Reading a pdf from phone and storing it in a string in Android Studio

Add permission:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

to your AndroidManifest.xml.

Also if your target SDK is 23 or higher you must request for this permission while the app is running. More info here

Example implementation may look like this:

  1. Create helper class for requesting permissions

    public class PermissionChecker {

    private final Activity activity;
    private final View layout;
    private final int requestCode;
    private final String permission;
    private final String description;

    public PermissionChecker(@NonNull Activity activity, @NonNull View layout,
    int requestCode,
    @NonNull String permission,
    @NonNull String description) {
    this.activity = activity;
    this.layout = layout;

    this.requestCode = requestCode;
    this.permission = permission;
    this.description = description;
    }

    public void requestPermission() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
    // Provide an additional rationale to the user if the permission was not granted
    // and the user would benefit from additional context for the use of the permission.
    // Display a SnackBar with a button to request the missing permission.
    Snackbar.make(layout, description, Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {
    @Override
    public void onClick(View view) {
    requestPermission(activity, permission, requestCode);
    }
    }).show();
    } else {
    // No explanation needed, we can request the permission.
    requestPermission(activity, permission, requestCode);
    }
    }

    public boolean checkPermission() {
    return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED;
    }

    public boolean onRequestPermissionsResult(int requestCode, int[] grantResults) {
    return requestCode == this.requestCode
    && ((grantResults.length > 0)
    && (grantResults[0] == PackageManager.PERMISSION_GRANTED));
    }

    private void requestPermission(Activity activityContext, String permission, int requestCode) {
    ActivityCompat.requestPermissions(activityContext, new String[] { permission }, requestCode);
    }
    }
  2. Your Activity should implement OnRequestPermissionsResultCallback

    implements ActivityCompat.OnRequestPermissionsResultCallback
  3. Init PermissionChecker for external storage permission.

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // ...

    View rootView = getWindow().getDecorView().getRootView();

    readExternalStoragePermissionChecker = new PermissionChecker(this, rootView,
    PERMISSION_REQUEST_READ_EXTERNAL_STORAGE,
    Manifest.permission.READ_EXTERNAL_STORAGE,
    "Read external storage access is required to read pdfs from sdcard."
    );

    if (readExternalStoragePermissionChecker.checkPermission()) {
    convertPDFToText(path);
    }
    else {
    readExternalStoragePermissionChecker.requestPermission();
    }

    // ...
    }
  4. Override onRequestPermissionsResult method in your Activity.

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (readExternalStoragePermissionChecker.onRequestPermissionsResult(requestCode, grantResults)) {
    convertPDFToText(path);
    }
    }

How to open a PDF from an Android app (in a separate PDF viewer app)

Here's the solution that worked for me. It's a class called PdfHandler and here's how you use it - just put the pdf file in the assets folder. It will open it in a PDF viewer app if one is available, and if not show a warning message and direct the user to the Adobe Reader Play Store entry.

PdfHandler pdf = new PdfHandler(this);
pdf.openPdf("document.pdf");

The PdfHandler class. You should move text resources into Android string resources.

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.net.Uri;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
* Handles the opening of PDF files, using whatever app the user has installed to view PDFs
* If no PDF app installed, shows a warning and directs them to appropriate Store listing
*/
public class PdfHandler {

public PdfHandler(Context context) {
this.context = context;
}

public void openPdf(String filename) {
if (isPdfAppAvailable()) {
copyPdfAndOpenIt(filename);
} else {
showPdfWarning();
}
}

private void copyPdfAndOpenIt(String filename) {
try {
File file = copyPdfFromAssetsToStorage(filename);
startPdfIntent(file);
} catch (Exception e) {
Log.e("PdfHandler", "Error handling the PDF file", e);
}
}

private File copyPdfFromAssetsToStorage(String filename) throws Exception {
String tempFilename = "temp.pdf";
AssetManager is = context.getAssets();
InputStream inputStream = is.open(filename);
String outFilename = context.getFilesDir() + "/" + tempFilename;
FileOutputStream outputStream = context.openFileOutput(tempFilename, Context.MODE_WORLD_READABLE);
copy(inputStream, outputStream);
outputStream.flush();
outputStream.close();
inputStream.close();
return new File(outFilename);
}

private void copy(InputStream fis, FileOutputStream fos) throws IOException {
byte[] b = new byte[8];
int i;
while ((i = fis.read(b)) != -1) {
fos.write(b, 0, i);
}
}

private boolean isPdfAppAvailable() {
PackageManager packageManager = context.getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}

private void startPdfIntent(File file) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
context.startActivity(intent);
}

private void showPdfWarning() {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Please install an app to view PDF file");
builder.setCancelable(false);
builder.setPositiveButton("Install", getButtonListener());
builder.setNegativeButton("Cancel", null);
builder.setTitle("PDF Viewer");
AlertDialog alert = builder.create();
alert.show();
}

private DialogInterface.OnClickListener getButtonListener() {
return new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
goToGooglePlayStoreEntry();
}
};
}

private void goToGooglePlayStoreEntry() {
context.startActivity(getAppListingIntent());
}

private Intent getAppListingIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW);
String pdfAppPackageName = "com.adobe.reader";
intent.setData(Uri.parse("market://details?id=" + pdfAppPackageName));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent;
}

private Context context;

}


Related Topics



Leave a reply



Submit