I'm trying to activate camera with intent by the following codes :
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private ImageView mImageView;
static final int REQUEST_IMAGE_CAPTURE = 1;
static final int REQUEST_TAKE_PHOTO = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
mImageView = findViewById(R.id.imageView);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "clicked", Toast.LENGTH_SHORT).show();
dispatchTakePictureIntent();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult: 0");
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Log.d(TAG, "onActivityResult: 1");
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
private void dispatchTakePictureIntent() {
Log.d(TAG, "dispatchTakePictureIntent: 0");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
Log.d(TAG, "dispatchTakePictureIntent: 1");
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
The app crashes every time I click the button(it's supposed to open the camera). I can get "dispatchTakePictureIntent: 1" from logcat, so takePictureIntent.resolveActivity(getPackageManager()) isn't returning null. I think it's startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE) that causes the app to crash.
The codes are replicated from the official documents : https://developer.android.com/training/camera/photobasics#java.
I've tried dispatchTakePictureIntent(View v), but the app still crashed. I've also replaced dispatchTakePictureIntent() with the method below and it still crashed.
private void TakePicture(){
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);
}
I've been trying other solutions I found on the internet, non of them helped. What could be the problem that causes my app to crash?
I think you have not used any permission check because for an android device below 23 need not to ask for permssion but above 23 you need to declare or ask user to access features of an android.
If the device is running Android 6.0 (API level 23) or higher, and the app's targetSdkVersion is 23 or higher, the user isn't notified of any app permissions at install time. Your app must ask the user to grant the dangerous permissions at runtime. When your app requests permission, the user sees a system dialog (as shown in figure 1, left) telling the user which permission group your app is trying to access. The dialog includes a Deny and Allow button.
According to this Doc..
https://developer.android.com/guide/topics/permissions/overview
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
}
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted
}
Sample code from Android doc
https://developer.android.com/training/permissions/requesting#java
Please try to give the permission of camera in android manifest file.
<uses-permission android:name="android.permission.CAMERA"> </uses-permission>.
and then try replace your intent code with this Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivity(intent);
if you don't want to use device camera then you can also make you own Custom camera with the help of this library https://github.com/natario1/CameraView
you can use this way
public static final int REQUEST_PICTURE_FROM_GALLERY = 10001;
public static final int REQUEST_PICTURE_FROM_CAMERA = 10002;
private File tempFileFromSource = null;
private Uri tempUriFromSource = null;
public void selectImageFromGallery() {
try {
tempFileFromSource = File.createTempFile("choose", "png", context.getExternalCacheDir());
tempUriFromSource = Uri.fromFile(tempFileFromSource);
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivityForResult(intent, REQUEST_PICTURE_FROM_GALLERY);
} catch (IOException e) {
e.printStackTrace();
}
}
public void takePhotoWithCamera() {
try {
tempFileFromSource = File.createTempFile("choose_", ".png", context.getExternalCacheDir());
tempUriFromSource = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", tempFileFromSource);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivityForResult(intent, REQUEST_PICTURE_FROM_CAMERA);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((requestCode == REQUEST_PICTURE_FROM_GALLERY) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image selected from gallery");
prepareImage(data.getData(), tempFileFromSource);
} else if ((requestCode == REQUEST_PICTURE_FROM_CAMERA) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image selected from camera");
prepareImage(tempUriFromSource, tempFileFromSource);
}
}
private void prepareImage(Uri uri, File imageFile) {
try {
if (uri == null)
return;
Bitmap bitmap = BitmapUtils.decodeBitmap(context, uri, 300, 300);
if (bitmap == null)
return;
// now you have bitmap
} catch (IOException e) {
e.printStackTrace();
}
}
public static Bitmap decodeBitmap(Context context, Uri uri, int maxWidth, int maxHeight) throws IOException {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream imageStream = context.getContentResolver().openInputStream(uri);
BitmapFactory.decodeStream(imageStream, null, options);
if (imageStream != null)
imageStream.close();
// Calculate inSampleSize
options.inSampleSize = calculateSize(options, maxWidth, maxHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
imageStream = context.getContentResolver().openInputStream(uri);
Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);
img = rotateImageIfRequired(context, img, uri);
return img;
}
Related
I am developing an android mobile application in which i am trying to upload the picture on server from android app. The .php files are working fine but the java code is not working and showing error that path is null. I have tried the several types of code but not working at all. Please help.
Thank you
Here is the code.
package com.example.pt_connect.attachmentuploadingandgetting;
import android.Manifest;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import net.gotev.uploadservice.MultipartUploadRequest;
import net.gotev.uploadservice.UploadNotificationConfig;
import java.io.IOException;
import java.util.UUID;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//Declaring views
private Button buttonChoose;
private Button buttonUpload;
private ImageView imageView;
private EditText editText;
//Image request code
private int PICK_IMAGE_REQUEST = 1;
//storage permission code
private static final int STORAGE_PERMISSION_CODE = 123;
//Bitmap to get image from gallery
private Bitmap bitmap;
//Uri to store the image uri
private Uri filePath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Requesting storage permission
requestStoragePermission();
//Initializing views
buttonChoose = (Button) findViewById(R.id.buttonChoose);
buttonUpload = (Button) findViewById(R.id.buttonUpload);
imageView = (ImageView) findViewById(R.id.imageView);
editText = (EditText) findViewById(R.id.editTextName);
//Setting clicklistener
buttonChoose.setOnClickListener(this);
buttonUpload.setOnClickListener(this);
}
/*
* This is the method responsible for image upload
* We need the full image path and the name for the image in this method
* */
**public void uploadMultipart() {
//getting name for the image
String name = editText.getText().toString().trim();
//getting the actual path of the image
String path = getPath(MainActivity.this,filePath);
//Uploading code
try {
String uploadId = UUID.randomUUID().toString();
//Creating a multi part request
new MultipartUploadRequest(this, uploadId, Constants.UPLOAD_URL)
.addFileToUpload(path, "image") //Adding file
.addParameter("name", name) //Adding text parameter to the request
.setNotificationConfig(new UploadNotificationConfig())
.setMaxRetries(2)
.startUpload(); //Starting the upload
} catch (Exception exc) {
Toast.makeText(this, exc.getMessage(), Toast.LENGTH_SHORT).show();
}
}**
//method to show file chooser
private void showFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
//handling the image chooser activity result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
//Bitmap photo = (Bitmap) data.getData().getPath();
filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
//method to get the file path from uri
public String getPath(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
//Requesting permission
private void requestStoragePermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
return;
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
//If the user has denied the permission previously your code will come to this block
//Here you can explain why you need this permission
//Explain here why you need this permission
}
//And finally ask for the permission
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
//This method will be called when the user will tap on allow or deny
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//Checking the request code of our request
if (requestCode == STORAGE_PERMISSION_CODE) {
//If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
Toast.makeText(this, "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onClick(View v) {
if (v == buttonChoose) {
showFileChooser();
}
if (v == buttonUpload) {
uploadMultipart();
}Error
}
}
You have to get the file path like below
String FilePath = data.getData().getPath();
String FileName = data.getData().getLastPathSegment();
on the onActivityResult. I made change to your code. Check below
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
//Bitmap photo = (Bitmap) data.getData().getPath();
filePath = data.getData().getPath();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I think it will work. If not comment here, we will go for another method
This question already has answers here:
Low picture/image quality when capture from camera
(3 answers)
Closed 5 years ago.
I want to take a picture from the Camera and Upload it to Server, but when I take a Picture from the Camera and Upload the Picture is low Resolution.
Code :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CaptureImageFromCamera = (ImageView)findViewById(R.id.imageView);
CaptureImageFromCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, 1);
}
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 1)
try {
onCaptureImageResult(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void onCaptureImageResult(Intent data) throws IOException {
bitmap = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes;
bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
"DCA/Attachment/" + System.currentTimeMillis() + ".png");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ImageViewHolder.setImageBitmap(bitmap);
}
Can be seen that the image quality is low resolution.
Is there a way to solve this problem?
[UPDATE] HOW I TO SOLVE THIS
I read the article here to solve this problem
Note: Read from the start page
package com.example.admin.camsdemo;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
Button captureimage;
ContentValues cv;
Uri imageUri;
ImageView imgView;
public static final int PICTURE_RESULT=111;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
captureimage=(Button)findViewById(R.id.opencamera);
imgView=(ImageView)findViewById(R.id.img);
captureimage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
cv = new ContentValues();
cv.put(MediaStore.Images.Media.TITLE, "My Picture");
cv.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
imageUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cv);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PICTURE_RESULT);
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICTURE_RESULT:
if (requestCode == PICTURE_RESULT)
if (resultCode == Activity.RESULT_OK) {
try {
Bitmap thumbnail = MediaStore.Images.Media.getBitmap(
getContentResolver(), imageUri);
imgView.setImageBitmap(thumbnail);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
Try using TextureView.SurfaceTextureListener and camera.takePicture(shutterCallback, rawCallback, pictureCallback)
For images taken from camera, you should consider JPEG compression. PNG is more suitable for icons where the colors used are few.
I'm using ACTION_IMAGE_CAPTURE with a predetermined target Uri pretty much as suggested in the documentation. However, when I try to decode the image immediately after my activity gets it, decodeStream() fails. If I try it again a few seconds later, it works fine. I suppose the file is being written asynchronously in the background. How can I find out when it's available for use?
Here are the key parts of my code:
Determining the target file name:
String filename = String.format("pic%d.jpg", new Date().getTime());
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename);
try {
file.createNewFile();
} catch (IOException e) {
file = new File(context.getFilesDir(), filename);
}
targetUri = Uri.fromFile(photoFile);
Taking the picture:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, targetUri);
fragment.startActivityForResult(takePictureIntent, RESULT_TAKE_PICTURE);
In onActivityResult():
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
// Note that data.getData() is null here.
InputStream is = getContentResolver().openInputStream(targetUri);
if (is != null) {
Bitmap bm = BitmapFactory.decodeStream(is);
decodeStream returns null. If I make the same call again a few seconds later, it succeeds. Is there anything that tells me when the file is available?
UPDATE: Following greenapps' suggestion, I'm doing a decodeStream call with inJustDecodeBounds first to get the dimensions to see if it's a memory issue. Turns out this first bounds-only decode pass fails, but now the actual decodeStream call that immediately follows succeeds! If I then do both again, they both succeed!
So it seems like the first call to decodeStream always fails, and all the others after that are good, even if they happen immediately afterwards (=within the same method). So it's probably not a problem with an asynchronous write. But something else. But what?
if (requestCode == Utility.GALLERY_PICTURE) {
Uri selectedImageUri = null;
try {
selectedImageUri = data.getData();
if (mImgProfilePic != null) {
// mImgProfilePic.setImageURI(selectedImageUri);
mImgProfilePic.setImageBitmap(decodeUri(getActivity(),
selectedImageUri, 60));
// decodeUri
}
} catch (Exception e) {
}
// //////////////
try {
// Bundle extras = data.getExtras();
// // get the cropped bitmap
// Bitmap thePic = extras.getParcelable("data");
// mImgProfilePic.setImageBitmap(thePic);
final Uri tempUri = selectedImageUri;
Log.d("check", "uri " + tempUri);
// http://dev1.brainpulse.org/quickmanhelp/webservice/api.php?act=companylogo
upLoadServerUri = "http://dev1.brainpulse.org/quickmanhelp/webservice/api.php?act=employee_profile_pic&image=";
upLoadServerUri = Utility.EMPLOYEE_PROFILE_PIC_URL
+ "&employee_id=" + empId;
dialog = ProgressDialog.show(getActivity(), "",
"Uploading file...", true);
new Thread(new Runnable() {
public void run() {
getActivity().runOnUiThread(new Runnable() {
public void run() {
// messageText.setText("uploading started.....");
}
});
uploadFilePath = getRealPathFromURI(tempUri);
uploadFile(uploadFilePath + "");
// uploadFile(tempUri+"");
}
}).start();
} catch (Exception e) {
}
// ///////
}
public static void updateFile(File file ,Context context) {
MediaScannerConnection.scanFile(context,
new String[]{file.getAbsolutePath()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
}
}
);
}
I think you can use this to update before you openInputStream.
From the snippet you shared I thiiink problem is that you are setting Image file to File variable file
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename);
But you are setting image Uri from File photoFile which is probably null
targetUri = Uri.fromFile(photoFile);
So basically you need to replace targetUri = Uri.fromFile(photoFile); with targetUri = Uri.fromFile(file);
Or even better data.getData() will return Image URi directlty like this
InputStream is = null;
try {
is = getContentResolver().openInputStream(data.getData());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (is != null) {
Bitmap bm = BitmapFactory.decodeStream(is);
((ImageView) findViewById(R.id.imageView1)).setImageBitmap(bm);
}
You still need to decode bitmap to avoid OOM exception you can use Glide to load image using image URI.
Complete Class Tested on Xpria C
package com.example.test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
public class TestActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
findViewById(R.id.take_picture).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
}
static final int REQUEST_TAKE_PHOTO = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
protected static final int RESULT_TAKE_PICTURE = 100;
private File createImageFile() throws IOException {
// Create an image file name
String filename = String.format("pic%d.jpg", new Date().getTime());
File file = new File(
getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename);
try {
file.createNewFile();
} catch (IOException e) {
file = new File(getFilesDir(), filename);
}
return file;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
InputStream is = null;
try {
is = getContentResolver().openInputStream(data.getData());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (is != null) {
Bitmap bm = BitmapFactory.decodeStream(is);
((ImageView) findViewById(R.id.imageView1)).setImageBitmap(bm);
}
}
}
}
This is code i'm using
Intent i = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, cameraData);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
try {
InputStream is = getContentResolver().openInputStream(data.getData());
Main.this.getContentResolver().delete(data.getData(), null,
null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
String error = e.toString();
Dialog d = new Dialog(this);
TextView tv = new TextView(this);
tv.setText(error);
d.setContentView(tv);
d.show();
}
} else {
is = null;
}
}
I'm doing this way because i don't want to save pics to dcim folder.
It is working fine on samsung, htc and some other devices but it crashes on alcatel one touch 5020x Jelly Bean 4.1.1,
returns null pointer exception.
Is there another way to do this, but not to save pics to dcim folder.
I have seen many solutions to do this but all of them save a pic to dcim folder
Thanx
I'm doing this way because i don't want to save pics to dcim folder.
Then include EXTRA_OUTPUT in your ACTION_IMAGE_CAPTURE Intent, to tell whichever camera app handles your request where to put the image. Quoting the documentation:
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field.
Your code is written to not do anything of what is documented. Instead, you are assuming that the camera app will return a Uri of where an image is. This is not part of the documented protocol, and so your code will fail when interacting with many camera apps.
Is there another way to do this, but not to save pics to dcim folder.
This code will put the image in another spot on external storage:
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import java.io.File;
public class CameraContentDemoActivity extends Activity {
private static final int CONTENT_REQUEST=1337;
private File output=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
output=new File(getExternalFilesDir(null), "CameraContentDemo.jpeg");
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(output));
startActivityForResult(i, CONTENT_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == CONTENT_REQUEST) {
if (resultCode == RESULT_OK) {
// use the output File object
}
}
}
}
This is not the best solution but it works!
final static int cameraData = 13579;
final static int camera2Data = 97531;
InputStream is = null;
int camera2 = 0;
SharedPreferences spData;
public static String spName = "MySharedString";
camera start:
if (camera2 == 1) {
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
output = new File(getExternalFilesDir(null),
"CameraContentDemo.jpg");
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(output));
startActivityForResult(i, camera2Data);
} else {
Intent i = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, cameraData);
}
onActivitrForResult:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == cameraData) {
if (resultCode == RESULT_OK) {
try {
is = getContentResolver().openInputStream(data.getData());
Main.this.getContentResolver().delete(data.getData(), null,
null);
} catch (Exception e) {
// TODO Auto-generated catch block
camera2 = 1;
if (camera2 == 1) {
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
output = new File(getExternalFilesDir(null),
"CameraContentDemo.jpeg");
i.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(output));
startActivityForResult(i, camera2Data);
}
SharedPreferences.Editor editor = spData.edit();
editor.putInt("cam2", 1);
editor.commit();
}
} else {
is = null;
}
}
if (requestCode == camera2Data) {
if (resultCode == RESULT_OK) {
try {
is = new FileInputStream(output);
} catch (Exception e) {
// TODO Auto-generated catch block
SharedPreferences.Editor editor = spData.edit();
editor.putInt("cam2", 0);
editor.commit();
}
} else {
is = null;
}
}
}
So, like i said, its not the best solution but it works.
When the app starts for the first time on Alcatel, it starts with the old code, crashes and catcher the exception, saves camera2 variable to be 1, and starts the camera again with the second code that works fine.
When i load on other devices, it works fine to and no pics are saved to DCIM folder
on click
takePic.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent m_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageUri = getImageUri();
m_intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(m_intent, REQUEST_IMAGE_CAPTURE);
}
});
On Result:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE
&& resultCode == RESULT_OK) {
Log.d("test1",""+imageUri);
Intent shareIntent = new Intent(this, SharePicForm.class);
shareIntent.putExtra("photo",""+imageUri);
startActivity(shareIntent);
}
}
getImageUri()
private Uri getImageUri(){
Uri m_imgUri = null;
File m_file;
try {
SimpleDateFormat m_sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
m_curentDateandTime = m_sdf.format(new Date());
m_imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + m_curentDateandTime + ".jpg";
m_file = new File(m_imagePath);
m_imgUri = Uri.fromFile(m_file);
} catch (Exception p_e) {
}
return m_imgUri;
}
What I would like to achieve is very simple, call camera intent and get the uri of the result photo. But it seems there is an inconsistent of different device and on my device it isn't work at all. I tried to store the path on a public variable but when I retrieve it , it is null, is there formal and standard way to implement it and should be work on all device? Also, are there any way for not provide the custom path but get the default uri path from the camera intent ?
Thanks for helping
If your device does not respect cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, you still can use
Uri imageUri = data.getData();
in onActivityResult(int requestCode, int resultCode, Intent data). But in most cases, the problem is that RAM is limited, and the system destroys your activity to give enough memory to the camera app to fulfill your intent. Therefore, when the result is returned, the fields of your activity are not initialized, and you should follow Amit's suggestion and implement onSavedInstance() and onRestoreInstanceState().
First of all make sure that your directory is created......
final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ "/Folder/";
File newdir = new File(dir);
newdir.mkdirs();
on button click call this function.
private void capturarFoto() {
String file = dir+DateFormat.format("yyyy-MM-dd_hhmmss", new Date()).toString()+".jpg";
File newfile = new File(file);
try {
newfile.createNewFile();
} catch (IOException e) {}
Uri outputFileUri = Uri.fromFile(newfile);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
Log.d("Demo Pic", "Picture is saved");
}
}
Make sure You add permission in manifest
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
To just get the thumbnail, you can use this:
val imageBitmap = data.extras.get("data") as Bitmap
To get the full picture:
See the specific steps from here (official docs)
You can read more from the docs.
After a lot of research I found this solution. Just to make things clear I created an entire app for this question which serves the purpose of opening the camera clicking a photo and setting the image as the ImageBitmap of an ImageView. The code asked in this question starts at the second block i.e. the setView() method which is below the onCreate() method following which we have the onActivityResult() method
Here is a demo of the app.
Below I have Attached the MainActivity.java file
package com.cr7.opencamera;
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private Button buttonCaptureImageFromCamera;
private Uri imageUri;
private ImageView imageViewCameraImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Button that will open the camera
buttonCaptureImageFromCamera = findViewById(R.id.buttonCaptureImageFromCamera);
// ImageView that will store the image
imageViewCameraImage = findViewById(R.id.imageViewCameraImage);
askPermission();
}
This what you need for geting the Uri of the image here imageUri is a global variable so that it can be used in the onActivityResult() method
// Sets OnClickListener for the button if storage permission is given
private void setView() {
buttonCaptureImageFromCamera.setOnClickListener(v -> {
String fileName = "new-photo-name.jpg";
// Create parameters for Intent with filename
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
values.put(MediaStore.Images.Media.DESCRIPTION, "Image capture by camera");
imageUri =
getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, 1231);
});
}
This is the onActivityResult method. Here I've used imageUri i.e. the global variable of type Uri which was initialized in the OnClickListener of the button in the setView() method above.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1231 && resultCode == Activity.RESULT_OK) {
try {
ContentResolver cr = getContentResolver();
try {
// Creating a Bitmap with the image Captured
Bitmap bitmap = MediaStore.Images.Media.getBitmap(cr, imageUri);
// Setting the bitmap as the image of the
imageViewCameraImage.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
} catch (IllegalArgumentException e) {
if (e.getMessage() != null)
Log.e("Exception", e.getMessage());
else
Log.e("Exception", "Exception");
e.printStackTrace();
}
}
}
Remaining code...
// Asking user for storage permission
public void askPermission() {
// Checking if the permissions are not granted.
if (
ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.READ_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
// If not granted requesting Read and Write storage
ActivityCompat.requestPermissions(this, /*You can ask for multiple request by adding
more permissions to the string*/new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 60);
} else {
// If permissions are granted we proceed by setting an OnClickListener for the button
// which helps the user pick the image
setView();
}
}
// This method is called after the permissions have been asked i.e. the dialog that says
// allow or deny
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// Now by default we assume that the permission has not been granted
boolean allPermissionsGranted = false;
// Now we check if the permission was granted
if ( requestCode == 60 && grantResults.length > 0) {
// If all the permissions are granted allPermissionsGranted is set to true else false
allPermissionsGranted = grantResults[0] == PackageManager.PERMISSION_GRANTED
&&
grantResults[1] == PackageManager.PERMISSION_GRANTED;
}
// If permissions are granted we call the setView Method which prompts the user to pick
// an Image either by the clicking it now or picking from the gallery
if ( allPermissionsGranted ) {
setView();
}
}
}
These blocks of code are in sequence i.e. if you merge all these blocks you get the complete MainActivity.java class.
If you wan to Implement this app you need yo create a layout file with an ImageView with an id "imageViewCameraImage"and a button with an id "buttonCaptureImageFromCamera".
Hope this helps. I know this is long and I'm making it longer by writing this.
Regards,
Joel
simply use this Uri imageUri = data.getData();