Create a PDF reader android App in Sketchware

To create a simple pdf reader in Sketchware follow the instructions given below.

1. Create a new project in Sketchware and create a VIEW as shown in image below:
linear2: A LinearH for the buttons/tools.
linear3: A LinearV for displaying images. Set it's padding to 0.
button1: A Button for picking PDF files.
edittext1: An EditText for displaying the page number. Set it's input type to numberSigned.
textview4: A TextView for displaying total number of pages.
textview3: A Button to move to page number entered in edittext1.
textview1: A Button to move to previous page.
textview2: A Button to move to next page.

2. Remove Toolbar and Status Bar of this View to make it full screen.

3. Add a File Picker component file_picker: application/pdf.

4. Add two number variables page and pageCount, and a String variable pdfFile. Also add a String list.

5. Add two more blocks: extra and display page(i).

6. In onCreate event use add source directly block and put following code.
touch = new ZoomableImageView(this);
linear3.addView(touch);
This code creates a new ZoomableImageView (defined as a new class later) and adds it to linear3.

7. In the event button1 onClick, Close renderer if it is open and use FilePicker pick files Block.
In the add source directly block use following code:
if (renderer != null){
renderer.close(); }

8. Define the More Block 'extra' using following codes:
i. Declare PdfRenderer and ZoomableImageView.
} private android.graphics.pdf.PdfRenderer renderer;
ZoomableImageView touch;

ii. Define a new View called ZoomableImageView.
public class ZoomableImageView extends ImageView {

Matrix matrix = new Matrix();
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
static final int CLICK = 3;
int mode = NONE;
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 4f;
float[] m;
float redundantXSpace, redundantYSpace;
float width, height;
float saveScale = 1f;
float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
ScaleGestureDetector mScaleDetector;
Context context;

public ZoomableImageView(Context context) {
super(context);
super.setClickable(true);
this.context = context;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
matrix.setTranslate(1f, 1f);
m = new float[9];
setImageMatrix(matrix); setScaleType(ScaleType.MATRIX);

setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
PointF curr = new PointF(event.getX(), event.getY());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: last.set(event.getX(), event.getY()); start.set(last); mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN: last.set(event.getX(), event.getY()); start.set(last);
mode = ZOOM;
break;
case MotionEvent.ACTION_MOVE:
if (mode == ZOOM || (mode == DRAG && saveScale > minScale)) {
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float scaleWidth = Math.round(origWidth * saveScale);
float scaleHeight = Math.round(origHeight * saveScale);
if (scaleWidth < width) {
deltaX = 0;
if (y + deltaY > 0) deltaY = -y;
else if (y + deltaY < -bottom) deltaY = -(y + bottom);
} else if (scaleHeight < height) {
deltaY = 0;
if (x + deltaX > 0) deltaX = -x;
else if (x + deltaX < -right) deltaX = -(x + right);
} else {
if (x + deltaX > 0) deltaX = -x;
else if (x + deltaX < -right) deltaX = -(x + right);
if (y + deltaY > 0) deltaY = -y;
else if (y + deltaY < -bottom) deltaY = -(y + bottom);
}
matrix.postTranslate(deltaX, deltaY);
last.set(curr.x, curr.y);
}
break;
case MotionEvent.ACTION_UP:
mode = NONE;
int xDiff = (int) Math.abs(curr.x - start.x);
int yDiff = (int) Math.abs(curr.y - start.y);
if (xDiff < CLICK && yDiff < CLICK) performClick();
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
setImageMatrix(matrix);
invalidate();
return true;
}
});
}

@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
bmWidth = bm.getWidth();
bmHeight = bm.getHeight(); }

public void setMaxZoom(float x) {
maxScale = x; }

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mode = ZOOM;
return true;}
@Override
public boolean onScale(ScaleGestureDetector detector) {
float mScaleFactor = detector.getScaleFactor();
float origScale = saveScale;
saveScale *= mScaleFactor;
if (saveScale > maxScale){
saveScale = maxScale;
mScaleFactor = maxScale / origScale;
} else if (saveScale < minScale) {
saveScale = minScale;
mScaleFactor = minScale / origScale;}
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
if (origWidth * saveScale <= width || origHeight * saveScale <= height) {
matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
if (mScaleFactor < 1) {
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (Math.round(origWidth * saveScale) < width) {
if (y < -bottom) matrix.postTranslate(0, -(y + bottom));
else if (y > 0) matrix.postTranslate(0, -y);
} else {
if (x < -right) matrix.postTranslate(-(x + right), 0);
else if (x > 0) matrix.postTranslate(-x, 0);}
}
}
} else {
matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY()); matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (x < -right) matrix.postTranslate(-(x + right), 0);
else if (x > 0) matrix.postTranslate(-x, 0);
if (y < -bottom) matrix.postTranslate(0, -(y + bottom));
else if (y > 0) matrix.postTranslate(0, -y);}
}
return true;
}
}

@Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
float scale;
float scaleX = width / bmWidth;
float scaleY = height / bmHeight;
scale = Math.min(scaleX, scaleY); matrix.setScale(scale, scale); setImageMatrix(matrix);
saveScale = 1f;
redundantYSpace = height - (scale * bmHeight) ;
redundantXSpace = width - (scale * bmWidth);
redundantYSpace /= 2;
redundantXSpace /= 2; matrix.postTranslate(redundantXSpace, redundantYSpace);
origWidth = width - 2 * redundantXSpace;
origHeight = height - 2 * redundantYSpace;
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); setImageMatrix(matrix);}
}

iii. In the end put another add source directly block with following code.
 {

8. Next define the More Block display page (i).
i. In an add source directly block put following code (This code will open the pdf page using PdfRenderer and display it in the ZoomableImageView):
android.graphics.pdf.PdfRenderer.Page page = renderer.openPage((int)_i);
Bitmap mBitmap = Bitmap.createBitmap((int)getDip(page.getWidth()), (int)getDip(page.getHeight()), Bitmap.Config.ARGB_8888);
page.render(mBitmap, null, null, android.graphics.pdf.PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
touch.setImageBitmap(mBitmap);
page.close();

Here (int)_i represent the number variable i in the more Block.

ii. Use the blocks to display i+1 in EditText.

9. In the event file_picker onFilesPicked, use blocks as shown in image below:
i. Set the String pdfFile to path of the file picked.
ii. Set number variable page to 0.
iii. Use a try{ } catch (Exception){} code and  define the renderer and set pageCount to the pageCount obtained from the renderer. Use following code in add source directly block:
try {
renderer = new android.graphics.pdf.PdfRenderer(new ParcelFileDescriptor(ParcelFileDescriptor.open(new java.io.File(pdfFile), ParcelFileDescriptor.MODE_READ_ONLY)));
pageCount = renderer.getPageCount();

iv. Display the first page using the More Block display page (page).
v. Set the text of textview4 to pageCount.
vi. Catch Exception using following code:
} catch (Exception e){ }

10. In the event textview1 onClick, move to previous page. Use blocks as shown in image below:
11. In the event textview2 onClick, move to next page. Use blocks as shown in image below:
12. In the event textview3 onClick, move to the page number entered in edittext1. Use blocks as shown in image below:
13. Save and run the project. Now you can pick PDF files and view it in the ZoomableImageView added to linear3.

Watch this:




Convert PDF file to Android App in Android Studio or AIDE:

Comments

  1. ----------
    1. ERROR in /storage/emulated/0/.sketchware/mysc/606/app/src/main/java/com/my/newproject4/MainActivity.java (at line 138)
    touch = new ZoomableImageView(this);
    ^^^^^
    touch cannot be resolved to a variable
    ----------
    2. ERROR in /storage/emulated/0/.sketchware/mysc/606/app/src/main/java/com/my/newproject4/MainActivity.java (at line 139)
    linear3.addView(touch);
    ^^^^^
    touch cannot be resolved to a variable
    ----------
    3. ERROR in /storage/emulated/0/.sketchware/mysc/606/app/src/main/java/com/my/newproject4/MainActivity.java (at line 349)
    touch.setImageBitmap(mBitmap);
    ^^^^^
    touch cannot be resolved
    ----------
    3 problems (3 errors)

    ReplyDelete
    Replies
    1. ZoomableImageView touch;

      Put this in the more Block 'extra'.

      Delete
    2. To: Media Ahmed-
      If that happend then go to library menu and close compact design...

      Delete
  2. Plz how to make pdf book to apk with sketchware ?

    ReplyDelete
  3. We know that the scketchware is really important to get your own sketch/ You should try this to get some app which will assist you .

    ReplyDelete
  4. Replies
    1. display_page:
      more block
      create
      display_page
      variable= number
      then make sure add variable name then click add then create

      Delete
  5. Please how to zoom the page please reply me and the video for me.

    ReplyDelete
    Replies
    1. The ZoomableImageView class used in this tutorial can be used to pinch zoom the page.

      Delete
    2. Please bro i can't know how to do it please teach with video. How to zoom the page in sketchware tutorial.

      Delete
  6. How to make another block with display page []?

    ReplyDelete
  7. When I click on "open" button, it shows "Invalid Intent Operation: No activity found to handle intent"

    ReplyDelete
  8. how to make random numbers without duplicates?

    ReplyDelete
  9. Hello. Error message:" syntax error on token invalid character delete this token"
    Where's the problem?

    ReplyDelete
    Replies
    1. Remove the extra spaces from the locations where it is showing invalid character

      Delete
    2. This comment has been removed by the author.

      Delete
  10. I made a listview with my PDF files ..how do I just view them in an imageview

    ReplyDelete
  11. How to make book app please reply sir

    ReplyDelete
  12. Sanjeev, thanks so much for the great job. Inbox me please.

    ReplyDelete
  13. How can I search for words in the pdf

    ReplyDelete
  14. How to read and download PDF file from webpage on Sketchware. Pls teach me.

    ReplyDelete
  15. Great job,, i have successfully made it,, but how can i show multiple page , like Adobe PDF reader?

    ReplyDelete
  16. 1. Upload your pdf using <-iframe src="pdf_path"-> into a html file
    2. Upload html and pdf into google drive folder
    3. Set sharing to everyone
    4. Go to drv.tw and log in with your google account
    5. Click on first link
    6. If pdf open at new tab ok if no something is wrong
    7. Create sketchware project
    8. Add webview
    9. Add a code that load your page to on create
    10. build

    ReplyDelete
  17. This comment has been removed by the author.

    ReplyDelete
  18. Sir....

    When I click on "open" button, it shows "Invalid Intent Operation: No activity found to handle intent"

    Please help me....

    ReplyDelete
  19. Sir How can I modify it to open a password protected PDF file??
    Please tell it is not opening a password protected PDF file

    ReplyDelete
  20. https://s.docworkspace.com/d/ABtxbbzx4bYr4d-L58udFA

    Sir above application code i have done many errors in sketchware app , I didn't know how to slove it please clarify that errors and give me correct solution for the problem.

    I attached errors above link
    which I had been faced.

    Thank you.

    ReplyDelete
    Replies
    1. Your errors are, linear3 cannot be resolved, _display_page(page) is not defined, and syntax errors.

      The linear in which I display the pages is linear3. Your linear is different. So either change the id or change it in code.

      You did some changes in naming the display page (page) more block.

      You missed ]; in
      float x = m[Matrix.MTRANS_X];
      float y = m[Matrix.MTRANS_Y];

      You did some mistake in { curly brackets. Either you missed one or added extra.

      Delete
  21. https://s.docworkspace.com/d/ABtxbbzx4bYr4d-L58udFA

    Sir above application code i have done many errors in sketchware app , I didn't know how to slove it please clarify that errors and give me correct solution for the problem.

    I attached errors above link
    which I had been faced.

    Thank you.

    ReplyDelete
    Replies
    1. Sir app run without error but pdf file didn't open .i can't open any file in document to test the app. Please give me a solution sir or you send link for the same app to download .
      Thank you again to send me reply

      Delete
    2. Here's the link to the file:

      https://s.docworkspace.com/d/AMm_5zTx4bYrwYWt_8udFA
      Sir now facing this error give me a right solution sir.


      Thank you.

      Delete
  22. How to load firebase PDF in sketchware please create for this... Online PDF viewer without using Google Drive

    ReplyDelete
  23. I have followed all your steps but there doesn't come any pdf image after opening pdf...How to fix it

    ReplyDelete
  24. 1. ERROR in /storage/emulated/0/.sketchware/mysc/ 603/app/src/main/java/com/aptech/pdfreader/ MainActivity.java (at line 169) renderer = new android.graphics.pdf.PdfRenderer(new ParcelFileDescriptor(ParcelFileDescriptor.open(new java.io.File(pdfFile), ParcelFileDescriptor.MODE_READ_ONLY))); The constructor File(ArrayList) is undefined 1 problem (1 error)


    Please slove it sir

    ReplyDelete
  25. I've been trying to create a display page block but am not getting it.
    I entered the name like this: display page(i) according to the instruction, buy it's not creating the block. I believe it's Boolean right?

    ReplyDelete
  26. HEi plz help mee
    How to creat an app when click one button an open a pdf file in my sd card

    ReplyDelete
  27. Can You Share The Pdf Reader Project Cause I Already Build It But I Forget To Save,Please👍👍👍👍👍👍👍👍

    ReplyDelete
  28. Hi there to everyone, the contents present at this web page are actually amazing for people knowledge, well, you can also visit RPA Consultants for more Webuters Technologies Pvt. Ltd. related information and knowledge. Keep up the good work.

    ReplyDelete
  29. This blog will help to get more ideas. This is very helpful for Software Testing learners. Thank you
    for sharing this wonderful site. If someone wants to know about Software QA services this is the right
    place for you
    Exchange Migration
    know more

    ReplyDelete
  30. Sigsync Office 365 email signature
    Office 365 email signatures are used by businesses of all sizes to enhance their brand and marketing programs. Email signature marketing is easy to adapt to achieve a number of sales goals. In addition, this strategy can support content downloads ads, increase page visits, promote an event, encourage social media engagement and much more.
    Email signatures are very effective in leaving a lasting impression on an the audience. Email signature software supports company branding by including the company logo, social media icons, any product links and mobile apps links that gives brand acknowledgement to your organization.
    Sigsync is centralized, secure Office 365 email signaturesoftware that ensures complete control over your company email signatures. Sigsync provides the best opportunity to brand your business. It helps to design an attractive and professional company-wide email signature on every email across all the email clients and devices.

    ReplyDelete
  31. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  32. I found this one pretty fascinating and it should go into my collection. Very good work! I am Impressed.
    Poker Game Development Company

    ReplyDelete
  33. how can i fix touch can't be resolved to avirable ( 3 errors )

    ReplyDelete

Post a Comment

Popular posts from this blog

Simple car racing android game in Sketchware

Creating a Drawing View in Sketchware

Enable Fullscreen for Youtube videos in WebView

How to enable upload from webview in Sketchware?

List of Calendar Format symbols valid in Sketchware