Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I know this question has been asked many times but it's still unclear for me if there is an existing and properly working library to natively display PDF documents.
I only want to view a PDF document which is stored inside my app. Opening a new Activity is ok for me, I don't need to display it inside an existing view. I've already built a piece of code to launch an activity intent for reading my local PDF file, but of course, if no PDF Viewer app is already installed on the device, then nothing happens.
I've heard about APV, VuDroid, droidreader, etc but it seems that they all are APKs, not libraries that can be used inside my app code.
So, is there any real Android library to achieve this?
Thanks in advance.
This one you can try it which works in offline mode
https://github.com/bitfield66/PdfViewerAndroid_Offline
which just accepts pdf path.
Firstly to view a pdf in android you have to convert the pdf into images then display them to the user. (i am going to use a webview)
So to do this we need this library. It is my edited version of this git.
After you have imported the library into your project you need to create your activity.
The XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/webView1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
The java onCreate:
//Imports:
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.webkit.WebView;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFImage;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.PDFPaint;
import net.sf.andpdf.nio.ByteBuffer;
import net.sf.andpdf.refs.HardReference;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
//Globals:
private WebView wv;
private int ViewSize = 0;
//OnCreate Method:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Settings
PDFImage.sShowImages = true; // show images
PDFPaint.s_doAntiAlias = true; // make text smooth
HardReference.sKeepCaches = true; // save images in cache
//Setup webview
wv = (WebView)findViewById(R.id.webView1);
wv.getSettings().setBuiltInZoomControls(true);//show zoom buttons
wv.getSettings().setSupportZoom(true);//allow zoom
//get the width of the webview
wv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
ViewSize = wv.getWidth();
wv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
pdfLoadImages();//load images
}
Load Images:
private void pdfLoadImages()
{
try
{
// run async
new AsyncTask<Void, Void, Void>()
{
// create and show a progress dialog
ProgressDialog progressDialog = ProgressDialog.show(MainActivity.this, "", "Opening...");
#Override
protected void onPostExecute(Void result)
{
//after async close progress dialog
progressDialog.dismiss();
}
#Override
protected Void doInBackground(Void... params)
{
try
{
// select a document and get bytes
File file = new File(Environment.getExternalStorageDirectory().getPath()+"/randompdf.pdf");
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer bb = ByteBuffer.NEW(channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()));
raf.close();
// create a pdf doc
PDFFile pdf = new PDFFile(bb);
//Get the first page from the pdf doc
PDFPage PDFpage = pdf.getPage(1, true);
//create a scaling value according to the WebView Width
final float scale = ViewSize / PDFpage.getWidth() * 0.95f;
//convert the page into a bitmap with a scaling value
Bitmap page = PDFpage.getImage((int)(PDFpage.getWidth() * scale), (int)(PDFpage.getHeight() * scale), null, true, true);
//save the bitmap to a byte array
ByteArrayOutputStream stream = new ByteArrayOutputStream();
page.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
byte[] byteArray = stream.toByteArray();
//convert the byte array to a base64 string
String base64 = Base64.encodeToString(byteArray, Base64.DEFAULT);
//create the html + add the first image to the html
String html = "<!DOCTYPE html><html><body bgcolor=\"#7f7f7f\"><img src=\"data:image/png;base64,"+base64+"\" hspace=10 vspace=10><br>";
//loop through the rest of the pages and repeat the above
for(int i = 2; i <= pdf.getNumPages(); i++)
{
PDFpage = pdf.getPage(i, true);
page = PDFpage.getImage((int)(PDFpage.getWidth() * scale), (int)(PDFpage.getHeight() * scale), null, true, true);
stream = new ByteArrayOutputStream();
page.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
byteArray = stream.toByteArray();
base64 = Base64.encodeToString(byteArray, Base64.DEFAULT);
html += "<img src=\"data:image/png;base64,"+base64+"\" hspace=10 vspace=10><br>";
}
html += "</body></html>";
//load the html in the webview
wv.loadDataWithBaseURL("", html, "text/html","UTF-8", "");
}
catch (Exception e)
{
Log.d("CounterA", e.toString());
}
return null;
}
}.execute();
System.gc();// run GC
}
catch (Exception e)
{
Log.d("error", e.toString());
}
}
I like the MuPDF Adnroid lib since it written in C++/NDK and it has unique features like clickable images (I mean an URL linked to the image) - met no other lib with this feature and I was really need it.
You actually can open PDF using no lib at all: using WebView via google docs but I don't like this way due to IC is required all the time while using MuPDF I can DL pdf file and freely open it offline any time. Also WebView way is more "hard" for device meaning battery draining + lags + CPU heating and it uses more trafic (if compared to DL&show way).
Related
I was wondering if anybody knows a way or method to display on as3 a webview external html page to the back of a display abject?
here is my code
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.filesystem.File;
var fPath:String = "http://mysite.com/demo.php";
var webView = new StageWebView();
webView.stage = stage;
webView.viewPort = new Rectangle(15, 283, 340, 327);
webView.addEventListener(Event.COMPLETE, onComplete);
webView.loadURL( fPath );
function onComplete(event:Event):void{
trace("event = ", event);
trace("event.target = ", event.target);
}
StageWebView is always on top of the display list. There is a work around where you can draw it to BitmapData object and then display that in a Bitmap in the back of the display list using drawViewPortToBitmapData
Obviously the drawn version is not interactive.
hth.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am new to Android. I am developing an application that requires a user signature. How can I capture a signature in Android?
Your question is a little too broad. Try asking a question about a specific problem, not "how do I do something general". See the FAQ for more information about how to ask a question.
Here is a vague idea though:
You'll want to have a canvas object that can allow the user to draw to the screen. Here is a link on SO about it. Android drawing a line to follow your finger
Then you'll want to output that bitmap as a file: Save bitmap to location
You can do this in two ways:
1. Your own Implementation
You can use canvas to draw signatures. Use paint object to set signature stroke size & color.
2. Simply use library
See SignatureView library. It will do all, what you want.
https://github.com/zahid-ali-shah/SignatureView
Here's how I have capture human signature and save image using this example:
https://demonuts.com/android-capture-digital-signature/
First add following to your gradle:
repositories {
jcenter()
}
repositories {
maven {
url 'https://dl.bintray.com/zahid/maven/'
}
}
dependencies {
compile 'com.kyanogen.signatureview:signature-view:1.0'
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.parsaniahardik.signaturedemo.MainActivity">
<com.kyanogen.signatureview.SignatureView
xmlns:sign="http://schemas.android.com/apk/res-auto"
android:id="#+id/signature_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
sign:penSize="5dp"
sign:backgroundColor="#ffffff"
sign:penColor="#000000"
sign:enableSignature="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/clear"
android:text="clear"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/save"
android:text="save"/>
</LinearLayout>
MainActivity.java:
package com.example.parsaniahardik.signaturedemo;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.kyanogen.signatureview.SignatureView;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity {
Bitmap bitmap;
Button clear,save;
SignatureView signatureView;
String path;
private static final String IMAGE_DIRECTORY = "/signdemo";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
signatureView = (SignatureView) findViewById(R.id.signature_view);
clear = (Button) findViewById(R.id.clear);
save = (Button) findViewById(R.id.save);
clear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signatureView.clearCanvas();
}
});
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bitmap = signatureView.getSignatureBitmap();
path = saveImage(bitmap);
}
});
}
public String saveImage(Bitmap myBitmap) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File wallpaperDirectory = new File(
Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY /*iDyme folder*/);
// have the object build the directory structure, if needed.
if (!wallpaperDirectory.exists()) {
wallpaperDirectory.mkdirs();
Log.d("hhhhh",wallpaperDirectory.toString());
}
try {
File f = new File(wallpaperDirectory, Calendar.getInstance()
.getTimeInMillis() + ".jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
MediaScannerConnection.scanFile(MainActivity.this,
new String[]{f.getPath()},
new String[]{"image/jpeg"}, null);
fo.close();
Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
}
Don't forget to give READ-WRITE permission in manifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Many applications ask their users to accept an agreement, but I can't think of one I've used that's asked me for my actual signature.
Is there a good reason that your users aren't able to accept yr agreement in the usual way? (via a check box or by hitting a button marked 'I accept'?)
Why is a graphical representation of the users signature required?
It's difficult to write using a finger, and it's even more difficult to
write (using a finger) on a smart phone screen.
There are also privacy concerns relating to obtaining a graphical representation of a user's signature. Once obtained, I have no idea what your company will do with my signature. A signature is a valuable piece of personal information, which could ultimately be used for identity theft.
hi i want to display my html image on android emulator, please help
package com.Htmlview;
import ja va.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.webkit.WebView;
public class Htmlview extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
WebView webview = new WebView(this);
setContentView(webview);
try {
String imageString="<html><body>" +
"<h2>Norwegian Mountain Trip</h2>" +
"<img src=\"C:/Users/Public/Pictures/Sample Pictures/pulpit.jpg\" alt=\"Pulpit rock\" width=\"304\" height=\"228\" /></body></html>";
AssetManager mgr = this.getAssets();
InputStream is = mgr.open("index3.html");
BufferedInputStream in = new BufferedInputStream(is); // read the contents of the file
webview.loadData(MessageFormat.format(imageString,arguments),"text/html", "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
}
}
You're never going to be able to access something on your workstation's hard drive from within Android. What you want to do is put the image into the assets folder in your Android app (which will then get bundled into the app) and link to it appropriately with file:///android_assets/. There are other ways of dealing with the issue, but that is the simplest.
I want to make a dynamic webpage that can display my sqlite database's element in tabular format. How can I create a dynamic webpage in android?
I make a static HTML page and put in assest folder. It works but now I want a dynamic webpage. Please help:
package com.Htmlview;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class Htmlview extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
WebView webview = new WebView(this);
setContentView(webview);
try {
InputStream fin = getAssets().open("index3.html");
byte[] buffer = new byte[fin.available()];
fin.read(buffer);
fin.close();
webview.loadData(new String(buffer), "text/html", "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
}
}
This page works ...
Help to make it dynamic through code.
gaurav gupta
Use java.text.MessageFormat:
Put "{0}" markers in your html file.
Read your html file into a string
Create an arguments array from the database record
Call MessageFormat.format(htmlString, dbArgs)
Load the resulting string into the webview.
You can't modify the asset folder in runtime as it compiled at build time. So, you have 2 variants:
You content from database as it is. Just read the bytes and pass them to the webview without storing to anywhere.
Store the content to the file in internal memory and do like you did it with assets. But there is no sence as you already have your data in db.
I'm writing an app which will read XML from a webservice (probably via kSOAP2). I'm fairly happy with SAX parsing, as I've done XML parsing iPhone apps.
Unfortunately the webservice isn't public yet so for initial testing I have some files containing the XML I need to parse. In this early dev phase I just need to read the XML from the files and pass it into the XML parser
Xml.parse(this.testXML, root.getContentHandler());
How do I read the XML from a file/resource into a string to pass into this method. I want to crack on and test the parser, but this simple step is holding me up.
Thanks
Create a raw folder under res
Put your XML file in there, eg. testXML.xml:
/res/raw/testXML.xml
You should be able to use your XML parser using that as an inputstream:
Xml.parse(getResources().openRawResource(R.raw.testXML), Xml.Encoding.UTF_8, root.getContentHandler());
Try that.
I found a solution. Using Assets.
Here is the simple code example of how I did it.
I know I could have used XmlPullParser to simply load an xml file from res, but I wanted to use SAX parsing. This allows me to simply throw an XML string into the SAX parser for testing before I plug in the webservice.
It just uses a simple view with a Button to kick off the file load and a TextView to display the XML for now. I can get on with my parser :)
package com.martins.XmlParserTest
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class Main extends Activity {
Button btn;
TextView tvXml;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Load XML for parsing.
AssetManager assetManager = getAssets();
InputStream inputStream = null;
try {
inputStream = assetManager.open("textxml.xml");
} catch (IOException e) {
Log.e("tag", e.getMessage());
}
String s = readTextFile(inputStream);
TextView tv = (TextView)findViewById(R.id.textView1);
tv.setText(s);
}
});
}
private String readTextFile(InputStream inputStream) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, len);
}
outputStream.close();
inputStream.close();
} catch (IOException e) {
}
return outputStream.toString();
}
}
Raises exception due to incorrectly formed XML (line1,Pos0).
You tell parser that the encoding is UTF-8 and if it isn't you may get various errors (depending on parsers). If you are using non-xml editor to edit your XML it may save the file in a different encoding regardless what you declared it to be in the XML document.