In my application I will receive a byte stream and convert it to a pdf file in the phone memory. How do I render that to a pdf? And show it on an activity?
Some phones (like the Nexus One) come with a version of Quickoffice pre-installed so it may be as easy as sending the appropriate Intent once you've saved the file to the SD card.
public class OpenPdf extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.OpenPdfButton);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
File file = new File("/sdcard/example.pdf");
if (file.exists()) {
Uri path = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(path, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(intent);
}
catch (ActivityNotFoundException e) {
Toast.makeText(OpenPdf.this,
"No Application Available to View PDF",
Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
Open pdf file in webview.
public class MyPdfViewActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView mWebView=new WebView(MyPdfViewActivity.this);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setPluginsEnabled(true);
mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+LinkTo);
setContentView(mWebView);
}
}
Android-Lollipop (api 21) introduce a new API : PdfRenderer
This API allows you to create a Bitmap from a page in a PDF document.
Shortly :
get a seekable file descriptor from your pdf document :
ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
create the PdfRenderer
PdfRenderer renderer = new PdfRenderer(fd);
prepare the Bitmap
Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_4444);
get the PdfRenderer.Page to render
PdfRenderer.Page page = renderer.openPage(pageIndex);
render the page on the prepared bitmap
page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
now you can do what you want with the bitmap.
note that the 2 null args may allow you to clip some portion in the page and perform a transformation (using a Matrix) of the clip
there is another rendering mode : RENDER_MODE_FOR_PRINT. If you need this mode there are some guidelines to use it properly : here are the details.
This library is simple and works well:
Android Pdf Viewer
https://github.com/barteksc/AndroidPdfViewer
Old Reply...
I think that Joan Zapata give us the better and simple solution:
https://github.com/JoanZapata/android-pdfview
I assure you that it works!
1: https://github.com/JoanZapata/android-pdfview
For the local pdf files, you can render them through the third party libraries. for example, use the MuPDF library, its supported file types include PDF, PNG and JPEG.
One shortcoming of MuPDF is that it uses native library to fulfill the target, so it won't be easy to port the application on BlackBerry platform later.
To open a pdf from a byte array, you can use RadaeePDF, you can do the following into your activity:
private PDFReader m_vPDF = null;
private Document doc = new Document();
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Global.Init(this);
m_vPDF = new PDFReader(this);
doc.Close();
int ret = m_doc.OpenMem(data, password);
switch( ret )
{
case -1://need input password
finish();
break;
case -2://unknown encryption
finish();
break;
case -3://damaged or invalid format
finish();
break;
case -10://access denied or invalid file path
finish();
break;
case 0://succeeded, and continue
break;
default://unknown error
finish();
break;
}
m_vPDF.open(doc);
setContentView( m_vPDF );
}
Related
I would like to enter multiple text fields for example
name
email
password
address
And then I would like to generate a QR code from this input. How can I do that in android studio?
Setting up the library and manifest
Open App level gradle file and import the library.
implementation 'androidmads.library.qrgenearator:QRGenearator:1.0.3'
The, click “Sync Now”.
Then, open your Manifest file and add the following permissions. It is used to save QR Code to file storage.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
We need to handle runtime permissions from Android Version 6.0.
Generating QR Code
QRGEncoder qrgEncoder = new QRGEncoder(inputValue, null, QRGContents.Type.TEXT, smallerDimension);
Here, inputValue is an input to be converted to QR Code.
Input Type also can be specified while initializing the library.
We can specify the dimensions also.
Then, add the following lines to create QR Code and encode that into Bitmap Format.
try {
// Getting QR-Code as Bitmap
bitmap = qrgEncoder.encodeAsBitmap();
// Setting Bitmap to ImageView
qrImage.setImageBitmap(bitmap);
} catch (WriterException e) {
Log.v(TAG, e.toString());
}
qrImage is an ImageView used to preview the generated QR code bitmap.
Saving QR Code
QR Generator has an option to save the generated QR Code Bitmap to storage using the following lines.
// Save with location, value, bitmap returned and type of Image(JPG/PNG).
QRGSaver.save(savePath, edtValue.getText().toString().trim(), bitmap, QRGContents.ImageType.IMAGE_JPEG);
We can save QR Code in PNG & JPG format also. We have to handle runtime permissions from Android version 6.0.
Your particular case:
Combine the information you want to encode in the QR code, and add it as the inputValue for the QRGEncoder. Here is an example code for clarity:
public class MainActivity extends AppCompatActivity {
String TAG = "GenerateQRCode";
EditText edtValue;
ImageView qrImage;
Button start, save;
String inputValue;
String savePath = Environment.getExternalStorageDirectory().getPath() + "/QRCode/";
Bitmap bitmap;
QRGEncoder qrgEncoder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
qrImage = (ImageView) findViewById(R.id.QR_Image);
edtValue = (EditText) findViewById(R.id.edt_value);
start = (Button) findViewById(R.id.start);
save = (Button) findViewById(R.id.save);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
inputValue = edtValue.getText().toString().trim();
if (inputValue.length() > 0) {
WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point point = new Point();
display.getSize(point);
int width = point.x;
int height = point.y;
int smallerDimension = width < height ? width : height;
smallerDimension = smallerDimension * 3 / 4;
qrgEncoder = new QRGEncoder(
inputValue, null,
QRGContents.Type.TEXT,
smallerDimension);
try {
bitmap = qrgEncoder.encodeAsBitmap();
qrImage.setImageBitmap(bitmap);
} catch (WriterException e) {
Log.v(TAG, e.toString());
}
} else {
edtValue.setError("Required");
}
}
});
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean save;
String result;
try {
save = QRGSaver.save(savePath, edtValue.getText().toString().trim(), bitmap, QRGContents.ImageType.IMAGE_JPEG);
result = save ? "Image Saved" : "Image Not Saved";
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
Article: https://www.c-sharpcorner.com/article/how-to-generate-qr-code-in-android/
Concatenate all the information in a string and do a hash on said string. Next use a library such as (https://github.com/zxing/zxing) to generate the QR code.
Use this for generating qr code online. Then use picasso to load the image. ( Use your data in the url parameter )
https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=data
I found it as the best way.
I tried all examples both from the docs and from online help, but I can't get a simple image I have in the storage to display on an image view.
assuming I have pictures in the storage in a folder called pictures so photo1.jpg is stored in the reference:
StorageReference storageReference = FirebaseStorage.getInstance().getReference();
StorageReference photoReference= storageReference.child("pictures/photo1.jpg");
But how do I set it and replace the contents with an existing image view that I find by id:
ImageView photoView= (ImageView) findViewById(R.id.photo_view);
I keep getting failure on the listener to get Uri:
storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
profileImage.setImageURI(uri);
Log.d("Test"," Success!");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.d("Test"," Failed!");
}
});
Using below code you can set image on ImageView:
StorageReference storageReference = FirebaseStorage.getInstance().getReference();
StorageReference photoReference= storageReference.child("pictures/photo1.jpg");
final long ONE_MEGABYTE = 1024 * 1024;
photoReference.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
imageView.setImageBitmap(bmp);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(getApplicationContext(), "No Such file or Path found!!", Toast.LENGTH_LONG).show();
}
});
You can use the Uri as well, for that you need to save the byte array to a file. Use below code for the same:
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "test.jpg");
f.createNewFile();
//write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
// remember close de FileOutput
fo.close();
There may be something going wrong with the uri you have retrieved from the Firebase Storage, try putting it on log, like this:
Log.d("uri:",uri.toString());
This may give you a hint, what is going wrong with retrieving the value. If you choose to use Glide or Picasso, then do refer their GitHub pages from the links above, and see what you need.
Using Glide and Picasso both is simple, and here's an example of how to use Glide to store the images in your imageView.
// Reference to an image file in Cloud Storage
StorageReference storageReference = = FirebaseStorage.getInstance().getReference().child("yourImageReferencePath");
ImageView image = (ImageView)findViewById(R.id.imageView);
// Load the image using Glide
Glide.with(this /* context */)
.using(new FirebaseImageLoader())
.load(storageReference)
.into(image );
If you don't want to use any external library and want to retrieve the image, then do refer this answer, it might help.
Try to get the download URL of the image that you have uploaded in the database and use Picasso or GLIDE library to load it into the imageview you desire.
So, I'm (still) trying to build a simple camera app and what I have so far is an Image Controller which is able to take a picture, save it into the storage and pass the filepath with an intent to another activity.
In my new activity the first step I'm tying to achieve is, to get my final Image loaded into an ImageView, so I did the following:
ImageView finalImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_after);
Intent getIntent = getIntent();
String filePath = getIntent.getExtras().getString("filePath");
File imgFile = new File(filePath);
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
finalImage = (ImageView) findViewById(R.id.finalImage);
finalImage.setImageBitmap(myBitmap);
}
But, its not working, and I dont quite unterstand why not... :( The Activity starts completely fine, but the ImageView just does nothing.
There are few things you must know in the process of saving Image in Android
ccv2WithPreview.takePicture();
In this line the method executed is
public void takePicture() {
try {
// This is how to tell the camera to lock focus.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
// Tell #mCaptureCallback to wait for the lock.
mState = STATE_WAITING_LOCK;
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Toast.makeText(activity.getApplicationContext(), file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
}
In this method, capture() call is asynchronous. Since you are ending the activity soon after calling it and starting new Activity, so by the time your code saves the Image in Image Saver, you are starting new Activity already and your file is not yet ready.
You button implementation works because by the time you click button, Image will be saved.
To solve this problem,
CameraHelper.java
public interface CameraHelper{
void fileSaved(String filePath);
}
MainActivity.java
public class MainActivity extends AppCompatActivity
implements SensorEventListener, ActivityCompat.OnRequestPermissionsResultCallback, CameraHelper{
...
#Override
public void fileSaved(String file){
Intent intent = new Intent(this, AfterActivity.class);
intent.putExtra("filePath", file);
startActivity(intent);
finish();
}
}
in onCreate of MainActivity
ccv2WithPreview = new CameraControllerV2WithPreview(MainActivity.this, textureView, MainActivity.this);
in your camera class
private CameraHelper cameraHelper; //Initialize in constructor
Then in ImageSaver
private boolean imageSaved = false;
public void run() {
if(!imageSaved) {
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
try (FileOutputStream output = new FileOutputStream(mFile)) {
output.write(bytes);
imageSaved = true;
cameraHelper.fileSaved(mFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
} finally {
mImage.close();
}
}
}
This is how you must handle any Asynchronous tasks you get in future. Callback based implementations.
Can you try to invalidate() the ImageView after setting the bitmap?
(I'm pretty much guessing here, but working with GUIs a couple of years ago, i remember that if a view changed you have to tell the view to about it, so that it can be redrawn.)
Please also see: How to refresh image view immediately
I am pretty new to Android development and I'm trying to figure out how to tap an image in my app and save it to the device. When the image is tapped I want a Save button to appear and when that is pressed, a toast should appear saying the picture was saved. On iOS I am able to do this with UIActionSheet.
I should also mention that the image view image is downloaded from a URL using Picasso.
I just tried this and it says the image saved but when I go to the photos app on my phone, the image is not there.
largeImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
saveButton.setVisibility(View.VISIBLE);
}
});
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
largeImage.getDrawable();
Bitmap bitmap = ((BitmapDrawable)largeImage.getDrawable()).getBitmap();
OutputStream outStream = null;
File file = new File(storageDirectory, "er.PNG");
try {
outStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
Toast.makeText(FlickrImageActivity.this, "Saved", Toast.LENGTH_LONG).show();
}
catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(FlickrImageActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
catch (IOException e) {
e.printStackTrace();
Toast.makeText(FlickrImageActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
saveButton.setVisibility(View.GONE);
}
});
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Manifest permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You can use RelativeLayout to contain a ImageView and a Button.
Align both of them center in parent
inside the activity, set the button visibility to "gone"
call setOnClickListener of the ImageView and Button to your Activity
implement OnClickListener in your Activity
inside onClick(View v), if the view clicked is the ImageView, set the visibility of Button to "visible"
inside onClick(View v), if the view clicked is the Button, save the image to disk
** how to save image to disk
if the image source is drawable resources, use BitmapFactory.decodeResource to create a Bitmap then use Bitmap.compress to export to a specific path
specific path is recommended to be obtained from Environment.getExternalStoragePublicDirectory
then notify the Android to refresh gallery
MediaScannerConnection.scanFile(context,
new String[] { imagePath }, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
//....
}
});
Then use a Toast.makeText(context, "message here").show(); to show the message to user
See below steps to acheive this in Android :
1. Create layout with ImageView & 'Save' named Button
2.By deafult set 'Save' Button's visibility = gone/invisible
3. Apply click listener on both the views (ImageView & Button)
4. OnClick of ImageView, set 'Save' Button's visibility = visible
5. onclick of save button click call your save image to sdcard logic. Check below link for that.
http://android-er.blogspot.in/2010/07/save-file-to-sd-card.html
Hope this will help you.
public class OpenPdf extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.OpenPdfButton);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
File file = new File("/sdcard/example.pdf");
if (file.exists()) {
Uri path = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(path, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(intent);
}
catch (ActivityNotFoundException e) {
Toast.makeText(OpenPdf.this,
"No Application Available to View PDF",
Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
I have tried this above code but no output can been seen on emulator.Please help me to solve my problem of reading a PDF on emulator
I think the issue is in the Activity where you're trying to show the .pdf.
I haven't tried opening any .pdf files in any of my apps, but a cursory search says there is no native, easy way to do it. In other words, there is no Android class that makes it a snap to show your .pdf files - so you'll have to use a third party library, or roll your own.
See Render a PDF file using Java on Android