Android Java NullPointerException on openInputStream from Camera Intent data - java

When I try to get the result from the camera I keep getting a "NullPointerException: uri" at the line:
InputStream stream = getContentResolver().openInputStream(data.getData());
from the code:
if (requestCode == CAMERA_PIC_REQUEST) {
try {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
pic.setImageBitmap(thumbnail);
InputStream stream = getContentResolver().openInputStream(data.getData());
bitmapPic = BitmapFactory.decodeStream(stream);
Being pic an ImageViewer and the image is successfully placed in the ImageViewer I can't seem to find the reason as to why this is not working.
Also here's the code for the Intent that starts the image capturer.
pic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
});
And the part of the code that I will use it on after this is working, or at least trying to:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmapPic.compress(Bitmap.CompressFormat.JPEG, 50, baos);
byte[] data = baos.toByteArray();
mStorageRef.child(animal.getPictureID()).putBytes(data);
Being the last line Firebase related.
Also bitmapPic is a Bitmap.
Edit 1: Tried a suggestion by adding global variable:
private FileProvider mImageUri;
then
public void onClick(View view) {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(Intent.EXTRA_STREAM, mImageUri);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
But it says that putExtra combination doesn't exist. Not sure if that's what you meant.
Edit 2: Managed to get it working. As of now it only sends the Thumbnail but at least it's something here's how I did it:
if (requestCode == CAMERA_PIC_REQUEST) {
try {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
pic.setImageBitmap(thumbnail);
encodeBitmap(thumbnail);
}
where:
ByteArrayOutputStream baos;
public void encodeBitmap(Bitmap bitmap) {
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
}
And finally to send it to firebase I used this:
byte[] data = baos.toByteArray();
mStorageRef.child(animal.getPictureID()).putBytes(data);

Related

Pass bitmab back from activity to fragment

I have a fragment that contains an image view and button when I click on the button am going to an activity that has an image as a bitmap and in the activity, I have a button (save) that should finish the activity and go back to the fragment with the bitmap data.
I tried to use intents and bundles but nothing worked.
You need to convert your Bitmap data to an byte array then put it into the Bundle
ByteArrayOutputStream mStream = new ByteArrayOutputStream();
yourBitmapImage.compress(Bitmap.CompressFormat.PNG, 100, mStream);
byte[] byteArray = mStream.toByteArray();
Bundle mBundle = new Bundle();
mBundle.putByteArray("image",byteArray);
Passing Bitmap Object via bundle intents is very dangerous and you may end up getting errors especially for bitmaps of uknown lengths since there is even a limit for the size of the Parcelable extra.its highly unrecomended .Better solution would be to save it to a file then the path to a String value and pass it to the next activity or even to shared prefrence just in case it might be needed even after the app closes or even needed elsewhere in your code without using up your memory.Bitmaps especially are a great threat to memory if mishandled.See
public class Bitmap_saver{
public static String my_bitmap_path(Context act) {
SharedPreferences prefs = act.getSharedPreferences("SHAREDpREFname", act.MODE_PRIVATE);
return prefs.getString("my_bitmap_address", null);
}
public static void set_my_bitmap_address(Context act, String path) {
SharedPreferences.Editor saver = act.getSharedPreferences("SHAREDpREFname", act.MODE_PRIVATE).edit();
saver.putString("my_bitmap_address", path);
saver.commit();
}
public static String save_to_file(Bitmap fpb)
{
String img_name="BIT_"+ System.currentTimeMillis()+".JPG";
OutputStream fOutputStream = null;
File file = new File( Environment.getExternalStorageDirectory().toString() + "/YOUR_APP_DATA/");
if (!file.exists()) {
Log.e("Creating data dir=>",""+ String.valueOf(file.mkdirs()));
}
file = new File(Environment.getExternalStorageDirectory().toString() + "/YOUR_APP_DATA/", img_name);
try {
fOutputStream = new FileOutputStream(file);
fpb.compress(Bitmap.CompressFormat.JPEG, 100, fOutputStream);
fOutputStream.flush();
fOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
return "error";
} catch (IOException e) {
e.printStackTrace();
// Toast.makeText(this, "Save Failed", Toast.LENGTH_SHORT).show();
return "error";
}
return file.getAbsolutePath();
}
}
Call it like this to save Bitmap_saver.set_my_bitmap_path(your_context,Bitmap_saver.save_to_file(your_bitmap));
from your retreiving fragment/activity/class call this Bitmap myBitmap = BitmapFactory.decodeFile(Bitmap_saver.my_bitmap_path(your_context));
I end up using this approach:
in your fragment:
Intent signatureIntent = new Intent(getActivity(), SignatureActivity.class);
startActivityForResult(signatureIntent, your_request_code);
#Override
public void onActivityResult(int requestCode, int resultCode,
#Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == your_request_code&& resultCode == Activity.RESULT_OK){
String received = data.getStringExtra("extra");
byte[] decodedString = Base64.decode(received, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0,
decodedString.length);
}
}
in your activity:
bitmap = signatureView.getSignatureBitmap();
Intent resultIntent = new Intent();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
resultIntent .putExtra("extra",encoded);
setResult(Activity.RESULT_OK, resultIntent);
finish();

When sharing Animate Gif to Twitter by using Intent, Twitter makes it static image (Android)

When I share animate gif to Twitter by using Intent, Twitter makes it static image.
It works to share to Facebook Messenger.
How to create an animated GIF from JPEGs in Android (development)
I use this class to create Animated gif.
Can anyone help me?
Here is my code below.
public byte[] generateGIF(ArrayList<Bitmap> bitmaps) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start(bos);
for (Bitmap bitmap : bitmaps) {
encoder.addFrame(bitmap);
}
encoder.finish();
return bos.toByteArray();
}
private void shareGif (byte[] bytes,String fileName) {
try {
File file = new File(getApplicationContext().getCacheDir(), fileName + ".gif");
FileOutputStream fOut = new FileOutputStream(file);
fOut.write(bytes);
fOut.close();
file.setReadable(true, false);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType("image/gif");
startActivity(Intent.createChooser(intent , "Send image using.."));
} catch (Exception e) {
e.printStackTrace();
}
}

How to transfer the image by Intent?

I connected to the camera via API. When a function
camera.takePicture(null, null, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
returns an array of byte [] data. If I understand correctly, this is our picture. How can I pass this array of bytes by Intent and set the resulting image next Activiti?
You could try:
Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data.length());
Then assuming the data you want to pass implements Serializable(which it should), passing it through an Intent should be as simple as:
from one activity:
i.putExtra("image", bitmap);
startActivity(i);
into the next next activity:
Intent i = getIntent();
Bitmap data = (Bitmap)i.getSerializableExtra("image");
i have success whit this way
First part
public void takePicture(View view) {
camera.takePicture(null, null, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Intent intent = new Intent(context, AcceptNotAccept.class);
intent.putExtra("picture", data);
startActivity(intent);
}
}
}
and then got this Intent
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_accept_not_accept);
Bundle extras = getIntent().getExtras();
byte[] byteArray = extras.getByteArray("picture");
bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
((ImageView)findViewById(R.id.ivForAcceptPicture)).setImageBitmap(bitmap);
}
The idea here is to save the image into your External/Internal memory (prefer: External like SD) and use the full path of the image e.g.
Intent i = new Intent(...);
i.putExtra("myimage","path://example.path/image.jpg");
startActivity(i);
The receiving activity can get the image by calling its path:
String imagePath = getIntent().getStringExtra("myimage");

Pictures saved on sdcard on android

I had a problem when saving picture on sdcard from my app.
that when i am taking a picture and saving it on sdcard and go to my app and take a new one and save it on sdcard the previous preview picture appear and when view it on my computer it appear corrupted ?
why this problem ?
public static void save(Bitmap bm, String path) {
OutputStream outStream = null;
try {
outStream = new FileOutputStream(new File(path));
bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
bm.recycle();
System.gc();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
enter code here
Use this method to store the image and display it.This is used to store the image
//create new directory to store image
File photo = new File(Environment.getExternalStorageDirectory()+"/Android/data/"+getApplicationContext().getPackageName()+"/files/Receipt");
boolean success = false;
if(!photo.exists())
{
success = photo.mkdirs();
}
//if exists save the image in specified path
if(!success)
{
dbimgguid = UUID.randomUUID();
imagename =dbimgguid.toString();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
photo = new File(Environment.getExternalStorageDirectory()+"/Android/data/"+getApplicationContext().getPackageName()+"/files/Receipt", imagename+".png");
intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photo));
imageurl = Uri.fromFile(photo);
startActivityForResult(intent, CAMERA_RECEIPTREQUEST);
}
To view the image
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode)
{
case CAMERA_RECEIPTREQUEST:
if(resultCode== Activity.RESULT_OK)
{
//Toast.makeText(this, "Receipt Image Saved", Toast.LENGTH_SHORT).show();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
ImageView jpgView = (ImageView)findViewById(R.id.imageView1);
Bitmap receipt = BitmapFactory.decodeFile(photo.toString(),options);
jpgView.setImageBitmap(receipt);
}
break;
}
I hope this will help you..
}
Do you have permissions to store to the SD card? I believe you need save and save to sd permissions.

Android application: how to use the camera and grab the image bytes?

I'm trying to create a small app for Android that takes a picture using the device's camera and put's a PNG frame on top of it. This way the final saved picture will have a beach on top of it, or hats, or anything. Does anyone have any sample programs with this behavior?
Have a look at the SDK documentation on using the image capture intent here.
I start my image capture intent like this:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE is a private member in my activity:
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
Then get the byte array back from the camera by using the following onActivityResult handler:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
Bitmap bmp = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
AddImage(byteArray);
} else if (resultCode == Activity.RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
After that you can do all the processing you want on the image.

Categories