Can't see the newest taken picture in the gallery? - android

I am creating an android app where I take a picture using camera intent, then store the picture in the picture directory. Then my app required to upload it. But, As I take the first picture from the app I can't see it in the gallery. But, from the second picture I take I can see them in the gallery. What to do?
here is my code: Here I display my pic on an image button:
mImageSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Intent galleryIntent=new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent,GALLERY_REQUEST);
}catch (Exception e){
Toast.makeText(getApplicationContext(),"There was an ERROR: "+e,Toast.LENGTH_LONG).show();
Intent intent=new Intent(PostActivity.this,AllPosts.class);
}
}
});
// I am saving it with mediastore.
MediaScannerConnection.scanFile(HomeActivity.this,
new String[] {imageFile.getAbsolutePath()},
new String[] {"image/jpeg"},null);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(imageFile)));

Use below method for API level below 19 to scan media file.
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
For API level 19 or above scan media file like below.
private void scanFile(String path) {
MediaScannerConnection.scanFile(MainActivity.this,
new String[] { path }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("TAG", "Finished scanning " + path);
}
});
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File("file://"+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
else
{
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}

Related

Image is not showing in gallery after save

Hi I am trying to save image in my gallery but the issue is that, not able to see in my gallery, following is my code can any one help?
public void OnClickSave(View view)
{
Bitmap bitmap =getBitmapFromView(idForSaveView);
try {
ContextWrapper wrapper = new ContextWrapper(context);
File file = wrapper.getDir("MilMilaImages",MODE_PRIVATE);
// Create a file to save the image
file = new File(file, "MilMila"+".jpg");
try{
OutputStream stream = null;
stream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);
stream.flush();
stream.close();
}catch (IOException e) // Catch the exception
{
e.printStackTrace();
}
// Parse the gallery image url to uri
final Uri savedImageURI = Uri.parse(file.getAbsolutePath());
// Display the saved image to ImageView
System.out.println("HLL"+savedImageURI);
iv.setImageURI(savedImageURI);
MediaScannerConnection.scanFile(context, new String[] { file.getAbsolutePath()},
null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);
} else {
context.sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"
+ Environment.getRootDirectory())));
}
// Display saved image uri to TextView
// Toast.makeText(context,"Saved Successfully",Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
I have used this code and it works for me :
// show the image in the device gallery
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
val contentUri = Uri.fromFile(compressFile) //out is your output file
mediaScanIntent.data = contentUri
this.sendBroadcast(mediaScanIntent)
} else {
sendBroadcast(Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())))
}// // show the image in the device gallery

How to convert saved jpg image to pdf to view image in adobe reader in android

I have save jpg file to internal storage code given below;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File folderPath = new File(Environment.getExternalStorageDirectory() + "/OCR");
if (!folderPath.exists()) {
if (folderPath.mkdir()) ; //directory is created;
} else {
File photo = new File(folderPath, "OCRPIC" + UUID.randomUUID().toString().substring(0, 5) + ".jpg");
imageUri = FileProvider.getUriForFile(MainActivity.this,
BuildConfig.APPLICATION_ID + ".provider", photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PHOTO_REQUEST);
}
Now I wanted jpg image to covert and show in pdf reader. I have tried some code given below but throws errors says not supported file formate.
private void viewPdf(File file) {
Intent intent;
intent = new Intent(Intent.ACTION_VIEW);
Uri photoURI = FileProvider.getUriForFile(MyFileActivity.this, BuildConfig.APPLICATION_ID + ".provider", file);
MyFileActivity.this.grantUriPermission("com.android.camera", photoURI,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ?
android.support.v4.content.FileProvider.getUriForFile(MyFileActivity.this, BuildConfig.APPLICATION_ID + ".provider", file) : Uri.fromFile(file), "application/pdf").addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("No Application Found");
builder.setMessage("Download one from Android Market?");
builder.setPositiveButton("Yes, Please",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent marketIntent = new Intent(Intent.ACTION_VIEW);
marketIntent.setData(Uri.parse("market://details?id=com.adobe.reader"));
startActivity(marketIntent);
}
});
builder.setNegativeButton("No, Thanks", null);
builder.create().show();
}
}
Any suggestion or sample other than itext libray to solve this conversion.

Android: Refreshing the Gallery after saving new images

So in my application I at one point save a bunch of images to a temporary folder, and I want them to show up immediately in the Gallery. Off of a reboot, they do, but otherwise they don't.
I've tried using the sendBroadcast method:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
But I get a permission error:
E/AndroidRuntime( 2628): java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.MEDIA_MOUNTED from pid=2628, uid=10068
Could I be missing a permission in my AndroidManifest, or is this just no longer supported? Thanks
Code provided by Petrus in another answer works for me on Kitkat (4.4):
MediaScannerConnection.scanFile(this, new String[] { Environment.getExternalStorageDirectory().toString() }, null, new MediaScannerConnection.OnScanCompletedListener() {
/*
* (non-Javadoc)
* #see android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted(java.lang.String, android.net.Uri)
*/
public void onScanCompleted(String path, Uri uri)
{
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
I tried Environment.getExternalStorageDirectory().toString(), but it didn't find my custom folder.
I just wanted to share my experience to solving this issue.
At the end, I had MediaScannerConnection configured to scan one file at a time and now missing folder that was holding those images showed up. Every time I download each image, I called MediaScannerConnection and file path as Uri instead of folder itself.
Also, many people asked why sendBroadcast stop working on kitkat and the answer is that sendBroadcast was abused and called too many times and causing system to drain battery or slowdown, so they removed the direct call to prevent abuse which makes sense. I was hoping to use above solution to the folder that hold all images, but it didn't work on the folder. I was hoping that finding folder would expose rest of the files within the custom folder, but it didn't in my case. I am hoping to find better answer in the future...
Here's snippet of my code.
MediaScannerConnection.scanFile(ApplicationContext.context, new String[] { imageFile.getPath() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.i(TAG, "Scanned " + path);
}
});
Try this one:
after saving your file to folder,write below code
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File("your image path"))));
Below code work all device for refreshing the gallery after saving image.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f1 = new File("file://" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
Uri contentUri = Uri.fromFile(f1);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
} else {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File("your image path"))));
Implement MediaScannerConnectionClient and add the below code.Works perfectly in 4.4 :)
MediaScannerConnection conn;
public void startScan(String url) {
imagepath = url;
if (conn != null)
conn.disconnect();
conn = new MediaScannerConnection(activity.this, activity.this);
conn.connect();
}
#Override
public void onMediaScannerConnected() {
try {
conn.scanFile(imagepath, getMimeType(imagepath));
} catch (java.lang.IllegalStateException e) {
//Do something
}
}
#Override
public void onScanCompleted(String path, Uri uri) {
conn.disconnect();
}
I know its late but try this can working in all versions:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(out); //out is your file you saved/deleted/moved/copied
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
} else {
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
}
Use MediaScannerConnection instead of SendBroadcast..
MediaScannerConnection.MediaScannerConnectionClient(
{
#Override
public void onScanCompleted(String path, Uri uri) {
if (path.equals(**your filename**.getAbsolutePath()))
{
Log.i("Scan Status", "Completed");
Log.i("uri: ",uri.toString());
conn.disconnect();
}
}
#Override
public void onMediaScannerConnected()
{
// TODO Auto-generated method stub
conn.scanFile(**your file name**.getAbsolutePath(),null);
}
});
conn.connect();
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
//Gallery Refresh Code
MediaScannerConnection.scanFile(getActivity(), new String[] { Environment.getExternalStorageDirectory().toString() }, null, new MediaScannerConnection.OnScanCompletedListener() {
/*
* (non-Javadoc)
* #see android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted(java.lang.String, android.net.Uri)
*/
public void onScanCompleted(String path, Uri uri)
{
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
out.close();

Custom photo folder showing up in Gallery

I'm working on an app that uses the camera and saves the pictures to DCIM/MyAppFolder. My first question is should I be saving it to DCIM or Pictures? If it even matters. My second question is I noticed it takes a while for the folder/pictures to show up in the native gallery app. After testing this with other apps (Instagram, Snapseed, ect) those photos show up immediately. Is there a piece of code I'm missing to accomplish this? My code is as followed:
public void takePhoto() {
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
//folder stuff
File imagesFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "MyAppFolder");
imagesFolder.mkdirs();
//String filePath = "/MyImages/QR_" + timeStamp + ".png" ;
File image = new File(imagesFolder, "IMG_" + timeStamp + ".jpg");
imageUri = Uri.fromFile(image);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(imageIntent, TAKE_PICTURE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
ContentResolver cr = getContentResolver();
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media
.getBitmap(cr, selectedImage);
Toast.makeText(this, selectedImage.toString(),
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT)
.show();
Log.e("Camera", e.toString());
}
}
}
}
to update the gallery app. simply after you click save just put this simple code after saving.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
this code will tell the gallery app that something has been added so please rescan for media now :D.

How to get camera result as a uri in data folder?

I am creating an application in which I want to capture a image and then I want to send that image in the email as a attachment.
I am opening a camera using android.provider.MediaStore.ACTION_IMAGE_CAPTURE intent action and I am passing the Uri of the file as a parameter EXTRA_OUTPUT to get the image back to the file. This is working perfectly and I am able to get the captured image if I use the external storage uri as a EXTRA_OUTPUT but if I use the data folder uri it is not working and the camera is not closing and its all buttons are not working.
Here is my code for get the result in the external storage directory
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File out = Environment.getExternalStorageDirectory();
out = new File(out, imagename);
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
startActivityForResult(i, CAMERA_RESULT);
And this code is for get the image in the data folder
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File out = getFilesDir();
out = new File(out, MyPharmacyOptions.PRESCRIPTION_IMAGE_NAME);
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
startActivityForResult(i, CAMERA_RESULT);
I knew that the data folder is not accessible to third application so may be this causes an issue so I have create one content provider to share the file.
Here is my content provide class
public class MyContentProvider extends ContentProvider {
private static final String Tag = RingtonContentProvider.class.getName();
public static final Uri CONTENT_URI = Uri
.parse("content://x.y.z/");
private static final HashMap<String, String> MIME_TYPES = new HashMap<String, String>();
static {
MIME_TYPES.put(".mp3", "audio/mp3");
MIME_TYPES.put(".wav", "audio/mp3");
MIME_TYPES.put(".jpg", "image/jpeg");
}
#Override
public boolean onCreate() {
return true;
}
#Override
public String getType(Uri uri) {
String path = uri.toString();
for (String extension : MIME_TYPES.keySet()) {
if (path.endsWith(extension)) {
return (MIME_TYPES.get(extension));
}
}
return (null);
}
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
File f = new File(getContext().getFilesDir(), uri.getPath());
if (f.exists()) {
return (ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY));
}
throw new FileNotFoundException(uri.getPath());
}
#Override
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
throw new RuntimeException("Operation not supported");
}
#Override
public Uri insert(Uri uri, ContentValues initialValues) {
File file = new File(getContext().getFilesDir(), uri.getPath());
if(file.exists()) file.delete();
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Uri.fromFile(file);
}
#Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
#Override
public int delete(Uri uri, String where, String[] whereArgs) {
File f = new File(getContext().getFilesDir(), "image1.jpg");
if(f.exists()) f.delete();
f = new File(getContext().getFilesDir(), "image2.jpg");
if(f.exists()) f.delete();
getContext().getContentResolver().notifyChange(CONTENT_URI, null);
}
}
So to use this content provide I am using following code to pass the uri to the camera activity
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Uri uri = MyContentProvider.CONTENT_URI;
uri = Uri.withAppendedPath(uri, imagename);
getContentResolver().insert(uri, null);
getContentResolver().notifyChange(RingtonContentProvider.CONTENT_URI, null);
Log.d(Tag, uri.toString());
i.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(i, CAMERA_RESULT);
Now if I pass the url other then external storage directory the camera is opening but it is not closing in emulator but in device the camera is going to closed but I am not getting the result.
I have declared this content provide in the manifest file
<provider
android:name=".contentproviders.MyContentProvider"
android:authorities="x.y.z" />
Also I have given the permission to write the external storage and also for use the camera.
I am able to capture the image using the external storage but I want to store the image in the data directory instead of external storage because if the external storage in not available I want to capture the image and want to send mail.
If I create content provide then I can also share my image to the email application.
If we not provide the extras with the camera intent it will return the image as a byte[] in the activity result as a data extra but this is for the purpose of the thumbnail so I can't get the high resolution image using this way.
There are two ways to solve this problem.
1. Save bitmap which you received from onActivityResult method
You can start camera through intent to capture photo using below code
Intent cameraIntent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
After capture photo, you will get bitmap in onActivityResult method
if (requestCode == CAMERA_REQUEST) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
}
Now you can simply save this bitmap to internal storage
Note: Here bitmap object consists of thumb image, it will not have a full resolution image
2. Save bitmap directly to internal storage using content provider
Here we will create content provider class to allow permission of local storage directory to camera activity
Sample provider example as per below
public class MyFileContentProvider extends ContentProvider {
public static final Uri CONTENT_URI = Uri.parse
("content://com.example.camerademo/");
private static final HashMap<String, String> MIME_TYPES =
new HashMap<String, String>();
static {
MIME_TYPES.put(".jpg", "image/jpeg");
MIME_TYPES.put(".jpeg", "image/jpeg");
}
#Override
public boolean onCreate() {
try {
File mFile = new File(getContext().getFilesDir(), "newImage.jpg");
if(!mFile.exists()) {
mFile.createNewFile();
}
getContext().getContentResolver().notifyChange(CONTENT_URI, null);
return (true);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
#Override
public String getType(Uri uri) {
String path = uri.toString();
for (String extension : MIME_TYPES.keySet()) {
if (path.endsWith(extension)) {
return (MIME_TYPES.get(extension));
}
}
return (null);
}
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
File f = new File(getContext().getFilesDir(), "newImage.jpg");
if (f.exists()) {
return (ParcelFileDescriptor.open(f,
ParcelFileDescriptor.MODE_READ_WRITE));
}
throw new FileNotFoundException(uri.getPath());
}
}
After that you can simply use the URI to pass to camera activity using the below code
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, MyFileContentProvider.CONTENT_URI);
startActivityForResult(i, CAMERA_RESULT);
If you don't want to create your own provider then you can use FileProvider from support-library-v4. For detailed help you can look into this post
Best solution I found is: FileProvider (needs support-library-v4)
It uses the internal storage!
https://developer.android.com/reference/android/support/v4/content/FileProvider.html
Define your FileProvider in Manifest in Application element:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="your.package.name.fileprovider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/image_path" />
</provider>
Add permissions in manifest root element:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
Define your image paths in for example res/xml/image_path.xml:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="captured_image" path="your/path/"/>
</paths>
Java:
private static final int IMAGE_REQUEST_CODE = 1;
// your authority, must be the same as in your manifest file
private static final String CAPTURE_IMAGE_FILE_PROVIDER = "your.package.name.fileprovider";
4.1 capture intent:
File path = new File(activity.getFilesDir(), "your/path");
if (!path.exists()) path.mkdirs();
File image = new File(path, "image.jpg");
Uri imageUri = FileProvider.getUriForFile(activity, CAPTURE_IMAGE_FILE_PROVIDER, image);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, IMAGE_REQUEST_CODE);
4.2 onActivityResult():
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == IMAGE_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
File path = new File(getFilesDir(), "your/path");
if (!path.exists()) path.mkdirs();
File imageFile = new File(path, "image.jpg");
// use imageFile to open your image
}
}
super.onActivityResult(requestCode, resultCode, intent);
}
Intent to call to capture photo,
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
Then Take Bitmap in ActivityResult
if (requestCode == CAMERA_REQUEST) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
}
Then Write that Into Internal Memory, see this
// The openfileOutput() method creates a file on the phone/internal storage in the context of your application
final FileOutputStream fos = openFileOutput("my_new_image.jpg", Context.MODE_PRIVATE);
// Use the compress method on the BitMap object to write image to the OutputStream
bm.compress(CompressFormat.JPEG, 90, fos);
Then next time to read that file,
Bitmap bitmap = BitmapFactory.decodeFile(file);
At first save came photo in your external storage and try it -
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.imageView = (ImageView)this.findViewById(R.id.imageView1);
Button photoButton = (Button) this.findViewById(R.id.button1);
photoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST) {
Bitmap bmp = intent.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray(); // convert camera photo to byte array
// save it in your external storage.
FileOutputStream fo = new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/_camera.png"));
fo.write(byteArray);
fo.flush();
fo.close();
}
}
Next target -
File cameraFile = new File(Environment.getExternalStorageDirectory() + "/_camera.png");
startActivityForResult(Intent.createChooser(new Intent(Intent.ACTION_SEND)
.setType("image/jpg")
.putExtra(Intent.EXTRA_SUBJECT, "Subject")
.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(cameraFile))
.putExtra(Intent.EXTRA_TEXT, textBody), "Send your message using"), Constant.EMAIL);
You can also do this without needing a content provider since you will need the sd card to open the camera image capture intent anyway. You can of course hack around the presence of the sd card but not with the camera intent capture....So you are checking for external storage but need it at this point.... FYI you should also check out a crop library like crop-image instead of using native, as it is not well supported across devices.
File mediaStorageDir;
String photoFileName = "photo.jpg";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// page = getArguments().getInt("someInt", 0);
// title = getArguments().getString("someTitle");
// Get safe storage directory for photos
mediaStorageDir = new File(
Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
APP_TAG);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()) {
Log.d(APP_TAG, "Directory exists: " + mediaStorageDir.isDirectory());
Log.d(APP_TAG, "Directory exists: " + mediaStorageDir.getPath());
Log.d(APP_TAG,
"Directory exists: "
+ Environment.getExternalStorageState());
Log.d(APP_TAG, "failed to create directory");
}
}
in your 'take the pic' code:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, getPhotoFileUri(photoFileName));
...
public Uri getPhotoFileUri(String fileName) {
return Uri.fromFile(new File(mediaStorageDir.getPath() + File.separator
+ fileName));
}
After researching this bug for some time, I have noticed that the activity that called the camera intent is only restarted when the phone is running out of memory.
so because the activity is restarted, the object holding the path or Uri to the captured image is refreshed (nulled)
so I would suggest you catch/ detect the null object in the onActivityResult, and prompt the user to free up space on their device or restart their phone for a quick temporary fix.

Categories

Resources