I need help with Kotlin. I need to capture and save an image in my media store.
My code:
class MainActivity : AppCompatActivity() {
var ListadeProductos = ArrayList<Notas>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
camera.setOnClickListener {
val intentCamera = Intent("android.media.action.IMAGE_CAPTURE")
startActivity(intentCamera)
}
}
}
I think maybe the next code can help you half way. Just capture the image from camera and display it in an ImageView.
I used it (found in Creating camera intent app using Kotlin on android - Displaying thumbnail).
val CAMERA_REQUEST_CODE = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
val callCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (callCameraIntent.resolveActivity(packageManager) != null) {
startActivityForResult(callCameraIntent, CAMERA_REQUEST_CODE)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode) {
CAMERA_REQUEST_CODE -> {
if (resultCode == Activity.RESULT_OK && data != null) {
imageView.setImageBitmap(data.extras.get("data") as Bitmap)
}
}
else -> {
Toast.makeText(this, "Unrecognized request code", Toast.LENGTH_SHORT)
}
}
}
The simplest code is to, open the native camera app to take a picture and handle result in the OnActivityResult method, as shown in the article Capture Picture with Camera in Kotlin – Android.
val REQUEST_CODE = 200
fun capturePhoto() {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE && data != null){
imageView.setImageBitmap(data.extras.get("data") as Bitmap)
}
}
That's it.
This blog explains how take picture from camera and show in an imagview in android/kotlin -- very simple
Complete code for pick image and crop it
Step 1: Add this gradle
implementation 'com.theartofdev.edmodo:android-image-cropper:1.2.1'
Step 2: Add two activities in your package and in manifest
<activity android:name=".ui.activities.CropImageActivity"
android:label="Crop Image"></activity>
<activity android:name=".ui.activities.ImagePickerActivity"
android:label="Pick Image"></activity>
CropImageActivity class
public class CropImageActivity extends AppCompatActivity implements CropImageView.OnSetImageUriCompleteListener, CropImageView.OnGetCroppedImageCompleteListener {
private static final int DEFAULT_ASPECT_RATIO_VALUES = 100;
public static final String CROPPED_IMAGE_PATH = "cropped_image_path";
public static final String EXTRA_IMAGE_URI = "cropped_image_path";
public static final String FIXED_ASPECT_RATIO = "extra_fixed_aspect_ratio";
public static final String EXTRA_ASPECT_RATIO_X = "extra_aspect_ratio_x";
public static final String EXTRA_ASPECT_RATIO_Y = "extra_aspect_ratio_y";
private static final String ASPECT_RATIO_X = "ASPECT_RATIO_X";
private static final String ASPECT_RATIO_Y = "ASPECT_RATIO_Y";
private CropImageView mCropImageView;
private int mAspectRatioX = DEFAULT_ASPECT_RATIO_VALUES;
private int mAspectRatioY = DEFAULT_ASPECT_RATIO_VALUES;
private boolean isFixedAspectRatio = false;
Bitmap croppedImage;
//endregion
private TextView tv_cancel, tv_crop;
// Saves the state upon rotating the screen/restarting the activity
#Override
protected void onSaveInstanceState(#SuppressWarnings("NullableProblems") Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putInt(ASPECT_RATIO_X, mAspectRatioX);
bundle.putInt(ASPECT_RATIO_Y, mAspectRatioY);
}
// Restores the state upon rotating the screen/restarting the activity
#Override
protected void onRestoreInstanceState(#SuppressWarnings("NullableProblems") Bundle bundle) {
super.onRestoreInstanceState(bundle);
mAspectRatioX = bundle.getInt(ASPECT_RATIO_X);
mAspectRatioY = bundle.getInt(ASPECT_RATIO_Y);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crop_image);
tv_cancel = (TextView)findViewById(R.id.tv_cancel);
tv_crop = (TextView)findViewById(R.id.tv_crop);
if (!getIntent().hasExtra(EXTRA_IMAGE_URI)) {
cropFailed();
return;
}
isFixedAspectRatio = getIntent().getBooleanExtra(FIXED_ASPECT_RATIO, false);
mAspectRatioX = getIntent().getIntExtra(EXTRA_ASPECT_RATIO_X, DEFAULT_ASPECT_RATIO_VALUES);
mAspectRatioY = getIntent().getIntExtra(EXTRA_ASPECT_RATIO_Y, DEFAULT_ASPECT_RATIO_VALUES);
Uri imageUri = Uri.parse(getIntent().getStringExtra(EXTRA_IMAGE_URI));
// Initialize components of the app
mCropImageView = (CropImageView) findViewById(R.id.CropImageView);
// If you want to fix the aspect ratio, set it to 'true'
mCropImageView.setFixedAspectRatio(isFixedAspectRatio);
if (savedInstanceState == null) {
mCropImageView.setImageUriAsync(imageUri);
}
tv_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cropFailed();
}
});
tv_crop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCropImageView.getCroppedImageAsync(mCropImageView.getCropShape(), 0, 0);
}
});
}
private void cropFailed() {
Toast.makeText(mCropImageView.getContext(), "Image crop failed", Toast.LENGTH_LONG).show();
setResult(RESULT_CANCELED);
finish();
}
#Override
protected void onStart() {
super.onStart();
mCropImageView.setOnSetImageUriCompleteListener(this);
mCropImageView.setOnGetCroppedImageCompleteListener(this);
}
#Override
protected void onStop() {
super.onStop();
mCropImageView.setOnSetImageUriCompleteListener(null);
mCropImageView.setOnGetCroppedImageCompleteListener(null);
}
#Override
public void onSetImageUriComplete(CropImageView view, Uri uri, Exception error) {
if (error == null) {
//Toast.makeText(mCropImageView.getContext(), "Image load successful", Toast.LENGTH_SHORT).show();
}
else {
//Toast.makeText(mCropImageView.getContext(), "Image load failed: " + error.getMessage(), Toast.LENGTH_LONG).show();
Toast.makeText(mCropImageView.getContext(), "Unable to load image", Toast.LENGTH_LONG).show();
}
}
#Override
public void onGetCroppedImageComplete(CropImageView view, Bitmap bitmap, Exception error) {
if (error == null) {
croppedImage = bitmap;
try {
String path = saveToInternalStorage(this, bitmap);
Intent resultIntent = new Intent();
resultIntent.putExtra(CROPPED_IMAGE_PATH, path);
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
catch (IOException e) {
e.printStackTrace();
cropFailed();
}
}
else {
cropFailed();
}
}
private String saveToInternalStorage(Context context, Bitmap bitmapImage) throws IOException {
ContextWrapper cw = new ContextWrapper(context);
// Path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Create imageDir
File mypath = new File(directory, "image.jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
//Bitmap scaledBitmap = getCompressedBitmap(bitmapImage);
bitmapImage.compress(Bitmap.CompressFormat.PNG, 70, fos);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
fos.close();
}
return directory.getAbsolutePath();
}
}
ImagePickerActivity class
public class ImagePickerActivity extends AppCompatActivity {
private static final int REQUEST_PICK_IMAGE = 2365;
private static final int REQUEST_CROP_IMAGE = 2342;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startActivityForResult(getPickImageChooserIntent(), REQUEST_PICK_IMAGE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if(requestCode == REQUEST_PICK_IMAGE) {
Intent intent = new Intent(this, CropImageActivity.class);
Uri imageUri = getPickImageResultUri(data);
intent.putExtra(CropImageActivity.EXTRA_IMAGE_URI, imageUri.toString());
startActivityForResult(intent, REQUEST_CROP_IMAGE);
}
else
if(requestCode == REQUEST_CROP_IMAGE) {
System.out.println("Image crop success:" + data.getStringExtra(CropImageActivity.CROPPED_IMAGE_PATH));
String imagePath = new File(data.getStringExtra(CropImageActivity.CROPPED_IMAGE_PATH), "image.jpg").getAbsolutePath();
Intent result = new Intent();
result.putExtra("image_path", imagePath);
setResult(Activity.RESULT_OK, result);
finish();
}
}
else {
System.out.println("Image crop failed");
setResult(Activity.RESULT_CANCELED);
finish();
}
}
/**
* Create a chooser intent to select the source to get image from.<br/>
* The source can be camera's (ACTION_IMAGE_CAPTURE) or gallery's (ACTION_GET_CONTENT).<br/>
* All possible sources are added to the intent chooser.
*/
public Intent getPickImageChooserIntent() {
// Determine URI of camera image to save.
Uri outputFileUri = getCaptureImageOutputUri();
List<Intent> allIntents = new ArrayList<>();
PackageManager packageManager = getPackageManager();
// Collect all camera intents
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
if (outputFileUri != null) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
}
allIntents.add(intent);
}
// Collect all gallery intents
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
List<ResolveInfo> listGallery = packageManager.queryIntentActivities(galleryIntent, 0);
for (ResolveInfo res : listGallery) {
Intent intent = new Intent(galleryIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
allIntents.add(intent);
}
// The main intent is the last in the list, so pickup the useless one
Intent mainIntent = allIntents.get(allIntents.size() - 1);
for (Intent intent : allIntents) {
if (intent.getComponent().getClassName().equals("com.android.documentsui.DocumentsActivity")) {
mainIntent = intent;
break;
}
}
allIntents.remove(mainIntent);
// Create a chooser from the main intent
Intent chooserIntent = Intent.createChooser(mainIntent, "Select source");
// Add all other intents
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()]));
return chooserIntent;
}
/**
* Get URI to image received from capture by camera.
*/
private Uri getCaptureImageOutputUri() {
Uri outputFileUri = null;
File getImage = getExternalCacheDir();
if (getImage != null) {
outputFileUri = Uri.fromFile(new File(getImage.getPath(), "pickImageResult.jpeg"));
}
return outputFileUri;
}
/**
* Get the URI of the selected image from {#link #getPickImageChooserIntent()}.<br/>
* Will return the correct URI for camera and gallery image.
*
* #param data the returned data of the activity result
*/
public Uri getPickImageResultUri(Intent data) {
boolean isCamera = true;
if (data != null) {
String action = data.getAction();
isCamera = action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE);
}
return isCamera ? getCaptureImageOutputUri() : data.getData();
}
}
activity_crop_image.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#color/colorblue"
android:padding="15dp">
<TextView
android:id="#+id/tv_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:text="Cancel"
android:textColor="#color/colorwhite"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_crop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/tv_title"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:text="Crop"
android:textColor="#color/colorwhite"
android:textSize="18sp"
android:textStyle="bold" />
</RelativeLayout>
<com.theartofdev.edmodo.cropper.CropImageView
android:id="#+id/CropImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/header"
android:layout_gravity="center"
app:cropFixAspectRatio="true" />
</RelativeLayout>
Step 3: Usage in fragment or activity class
private val REQUEST_PICK_IMAGE = 1002
profile_pic1.setOnClickListener {
startActivityForResult(Intent(activity, ImagePickerActivity::class.java), REQUEST_PICK_IMAGE)
}
fun setImage(imagePath: String) {
profile_pic1.setImageBitmap(getImageFromStorage(imagePath));
}
fun getImageFromStorage(path: String): Bitmap {
var f = File(path);
var options = BitmapFactory.Options();
options.inJustDecodeBounds = false;
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, 512, 512);
return BitmapFactory.decodeStream(FileInputStream(f), null, options)
}
private fun calculateInSampleSize(
options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
// Raw height and width of image
val height = options.outHeight
val width = options.outWidth
var inSampleSize = 1
if (height > reqHeight || width > reqWidth) {
val halfHeight = height / 2
val halfWidth = width / 2
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while (halfHeight / inSampleSize > reqHeight && halfWidth / inSampleSize > reqWidth) {
inSampleSize *= 2
}
}
return inSampleSize
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == requestCode) {
var imagePath = data!!.getStringExtra("image_path");
setImage(imagePath);
}
else {
System.out.println("Failed to load image");
}
}
NOTE: declare write/read and camera permission in the manifest and
runtime permissions as well
Related
I am creating a Intent chooser to choose between a the phone camera app and the gallery/file manager.
Intent chooserIntent = Intent.createChooser(clickPhoto(),"Set Image Using");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,openGallery());
startActivityForResult.launch(chooserIntent);
Click Photo method:
private Intent clickPhoto() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
ComponentName componentName = takePictureIntent.resolveActivity(requireActivity().getPackageManager());
if (componentName != null) {
try {
createImageFile();
mimeType = "image/*";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, getNewFileName());
values.put(MediaStore.Images.Media.MIME_TYPE, mimeType);
values.put(MediaStore.Images.Media.RELATIVE_PATH, getImageDirectoryPath());
Uri imageUri = requireActivity().getContentResolver().insert(MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL), values);
if (imageUri != null) {
currentPhotoPath = imageUri.toString();
shareUri = imageUri;
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
// initRequestCode(takePictureIntent, requestCode);
} catch (IOException ioException) {
Toast.makeText(requireContext(), ioException.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}
return takePictureIntent;
}
Open gallery method:
private Intent openGallery(){
mimeType = "image/*";
Intent intent = new Intent();
Uri collection = MediaStore.Video.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL);
try {
intent =
new Intent(Intent.ACTION_PICK, collection).setType(mimeType);
intent.resolveActivity(requireActivity().getPackageManager());
// initRequestCode(intent, requestCode);
} catch (ActivityNotFoundException e) {
Toast.makeText(requireContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
return intent;
}
The ActivityResultLauncher:
ActivityResultLauncher<Intent> startActivityForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
//how to tell which intent the user selected ?
}
});
how do I know if the user took a piture using the camera or picked an image with the file picker ?
You can put an extra integer to each intent before returning them which you can access in result, say:
Global variables
final String SOURCE = "source";
final int SOURCE_CAMERA = 0;
final int SOURCE_GALLERY = 1;
final int SOURCE_UNKNOWN = 2;
For camera
...
takePictureIntent.putExtra(SOURCE, SOURCE_CAMERA);
return takePictureIntent;
For gallery
..
intent.putExtra(SOURCE, SOURCE_GALLERY);
return intent;
ActivityResultLauncher
if (result.getResultCode() == Activity.RESULT_OK) {
//Identify source
int mySource = result.getData().getIntExtra(SOURCE, SOURCE_UNKNOWN )
}
You can differentiate like this,
If one method is for camera intent,
private fun openCamera() {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent.resolveActivity(packageManager) != null) {
cameraImageFile = getTempFile()
cameraImageFile?.let {
val imageUri = FileProvider.getUriForFile(
this,
"${BuildConfig.APPLICATION_ID}.fileprovider",
it
)
cameraLauncher.launch(imageUri)
}
}
}
and another method is for gallery intent
private fun openGallery() {
galleryLauncher.launch("image/*")
}
Then you can define them like below in activity,
//Todo for gallery
private val galleryLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) {
//code here for gallery
}
//Todo for camera
private val cameraLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) {
//code here for camera
}
That's it!
Declare some variables
companion object{
private const val CAMERA_ACTION =1
private const val GALLERY_ACTION =2
private const val CHOOSER_INTENT_ACTION =3
}
private var mActionTriggered =0
then follow
private fun openCamera() {
mActionTriggered = CAMERA_ACTION
}
private fun openGallery() {
mActionTriggered =GALLERY_ACTION
}
private fun openChooser() {
mActionTriggered =CHOOSER_INTENT_ACTION
}
onResult
private val startActivityForResult = registerForActivityResult(
StartActivityForResult()
) { result: ActivityResult ->
if (result.resultCode == RESULT_OK) {
when (mActionTriggered) {
CAMERA_ACTION -> {
mActionTriggered = 0
//TODO your logics
}
GALLERY_ACTION -> {
mActionTriggered = 0
//TODO your logics
}
else -> {
mActionTriggered = 0
//TODO your logics
}
}
}else{
mActionTriggered = 0
}
}
It feels a little overkill, but you can use the refinement mechanism of the chooser activity.
You need to implement the refinement activity yourself, but you can use the EXTRA_RESULT_RECEIVER that the chooser passes along to send back the result.
Intent refinementIntent = new Intent(this, RefinementActivity.class);
PendingIntent refinementPendingIntent = PendingIntent.getActivity(this, 0, refinementIntent, 0);
Intent clickPhotoIntent = clickPhoto();
Intent chooserIntent = Intent.createChooser(clickPhoto(),"Set Image Using");
chooserIntent.putExtra(
Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER, refinementPendingIntent.getIntentSender());
chooserIntent.putExtra(Intent.EXTRA_RESULT_RECEIVER, new ResultReceiver() {
#Override
public void onReceive(int resultCode, Bundle resultData) {
Intent startedIntent = resultData.getParcelable("extra_selected_intent");
// Check which intent was selected.
// Note that this is called when the selection happened, before the
// started activity returned. Probably what you want to do here is
// cache the value in a field and then check it when you get
// the activity result.
}
});
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, openGallery());
startActivityForResult.launch(chooserIntent);
And then in RefinementActivity.java, you will need to send the selected intent back to the sender
#Override
public void onCreate(Bundle savedInstanceState) {
Intent selectedIntent = getIntent().getParcelableExtra(Intent.EXTRA_INTENT);
ResultReceiver receiver = getIntent().getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
Bundle resultData = new Bundle();
resultData.putParcelable("extra_selected_intent", selectedIntent);
receiver.send(RESULT_OK, resultData);
startActivity(selectedIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT));
finish();
}
You can initialize Global Boolean value name isGallery and set it true in openGallery() and false in clickPhoto()
Like the code below:
private boolean isGallery ;
private Intent clickPhoto() {
isGallery = false;
}
private Intent openGallery() {
isGallery = true;
}
Now your ActivityResultLauncher will be like this:
ActivityResultLauncher<Intent> startActivityForResult =
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
if (isGallery) {
// user picked an image with the file picker
} else {
// user took a picture using the camera
}
}
});
I am facing a problem where in when I am trying to crop an image after it has picked from Gallery or Camera.
When I choose the image from gallery it gets cropped correctly without any problem. When I choose image from camera, the cropping is done properly but it shows me an "intermediate" screen as seen below without taking me directly to the crop screen.
Note: Picture above is just for representation purposes to show the "intermediate" Recent screen.
I don't want this "intermediate" Recent screen to be displayed. Instead I want to directly navigate to the crop intent. In apps like Whatsapp this behavior is not seen when someone changes his/her profile pic. It directly navigates to crop intent without showing "intermediate" screen.
Can someone help solve this problem?
Here is my complete code
/**
* This activity is used to display profile picture and update the same
*
*/
public class ChangeProfilePhotoActivity extends BaseActivity implements
View.OnClickListener {
private TextView mTvTitle;
private ImageView mBtnChangePhoto;
private ImageView mIvProfileImage;
public static final int CROP_PIC_REQUEST_CODE = 3;
public static final int TAKE_PICTURE = 1;
public static final int GALLERY_IMAGE = 2;
public static final int IMAGE_CHOOSER_INTENT = 4;
int PERMISSION_ALL = 10;
String[] PERMISSIONS = { Manifest.permission.CAMERA};
//private Uri mImageUri;
//private Uri mCropImageUri;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile_photo);
initUI();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
private void initUI() {
mBtnChangePhoto = (ImageView) findViewById(R.id.btnChangePhoto);
mIvProfileImage = (ImageView) findViewById(R.id.profile_image);
mBtnChangePhoto.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnChangePhoto:
//launch intent chooser
getPickImageIntent(this);
break;
default:
break;
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case IMAGE_CHOOSER_INTENT:
if(data!=null){
String action = data.getAction();
Uri selectedImageUri = data.getData();
//send image for cropping
doCrop(selectedImageUri);
}
break;
case CROP_PIC_REQUEST_CODE:
if(data!=null){
Bundle extras = data.getExtras();
if(extras != null) {
Bitmap bmp = (Bitmap) extras.get("data");
mIvProfileImage.setImageBitmap(bmp);
}
}
break;
default:
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void doCrop(Uri picUri) {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 128);
cropIntent.putExtra("outputY", 128);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, CROP_PIC_REQUEST_CODE);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe) {
// display an error message
String errorMessage = "Your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
public void getPickImageIntent(Context context) {
Intent chooserIntent = null;
List<Intent> intentList = new ArrayList<>();
Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
//startActivityForResult(pickIntent, GALLERY_IMAGE);
Intent takePhotoIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
/* String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/crop_image.jpg";
File imageFile = new File(imageFilePath);
Uri picUri = Uri.fromFile(imageFile); // convert path to Uri
takePhotoIntent.putExtra( MediaStore.EXTRA_OUTPUT, picUri );*/
//takePhotoIntent.putExtra("return-data", false);
//startActivityForResult(takePhotoIntent, TAKE_PICTURE);
intentList = addIntentsToList(context, intentList, pickIntent);
intentList = addIntentsToList(context, intentList, takePhotoIntent);
if (intentList.size() > 0) {
chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1),
context.getString(R.string.pick_image_intent_text));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[intentList.size()]));
}
startActivityForResult(chooserIntent, IMAGE_CHOOSER_INTENT);
}
private static List<Intent> addIntentsToList(Context context, List<Intent> list, Intent intent) {
try {
List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resInfo) {
String packageName = resolveInfo.activityInfo.packageName;
Intent targetedIntent = new Intent(intent);
targetedIntent.setPackage(packageName);
list.add(targetedIntent);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return list;
}
}
You're launching an intent. That means you're handing control off to another app. After that, you have no control over what happens. Of course what happens will be different on every device, as some OEMs will use their own Gallery app or Camera app that may behave completely differently.
So no, there's no way to prevent them from doing that extra screen. If you want total control, take the picture yourself via the camera or camera2 apis instead of calling an Intent. (Note: I don't actually suggest this, but if you want control its the only way).
I have tried to solve this problem from many different links but does not worked for me.I am using Android Image Cropper library for cropping images. Whenever i click on the button "upload image" it start the cropping activity and when i am done the cropped image is set in an imageview in "upload image" activity and after clicking "Proceed" button login is successful and i am directed to login activity but when i back press the login activity the "Upload image" activity is still there and is not destroyed. I have another activity called Update Activity that uses this Cropping activity and that activity also behaves in the same manner. So i want the "Upload image" to destroy. Thanks in advance
package com.donateblood.blooddonation;
public class CroppingActivity extends AppCompatActivity {
private CropImageView mCropImageView;
public static Bitmap finalImage = null;
public static Bitmap newImage = null;
private Uri mCropImageUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crop);
mCropImageView = (CropImageView) findViewById(R.id.CropImageView);
}
/**
* On load image button click, start pick image chooser activity.
*/
public void onLoadImageClick(View view) {
startActivityForResult(getPickImageChooserIntent(), 200);
}
public void onSetImageClick(View view) {
if(UpdateActivity.UpdatingPhoto){
newImage = mCropImageView.getCroppedImage(200, 200);
try {
Intent intent = new Intent(getApplicationContext(), UpdateActivity.class);
startActivity(intent);
finish();
} catch (Exception e) {
Toast.makeText(CroppingActivity.this, "Oppss..Error occured.", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}else {
finalImage = mCropImageView.getCroppedImage(200, 200);
try {
Intent intent = new Intent(getApplicationContext(), UploadImage.class);
startActivity(intent);
finish();
} catch (Exception e) {
Toast.makeText(CroppingActivity.this, "Oppss..Error occured.", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
/**
* Crop the image and set it back to the cropping view.
*/
public void onCropImageClick(View view) {
Bitmap cropped = mCropImageView.getCroppedImage(500, 500);
if (cropped != null)
mCropImageView.setImageBitmap(cropped);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
Uri imageUri = getPickImageResultUri(data);
// For API >= 23 we need to check specifically that we have permissions to read external storage,
// but we don't know if we need to for the URI so the simplest is to try open the stream and see if we get error.
boolean requirePermissions = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
isUriRequiresPermissions(imageUri)) {
// request permissions and handle the result in onRequestPermissionsResult()
requirePermissions = true;
mCropImageUri = imageUri;
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
}
if (!requirePermissions) {
mCropImageView.setImageUriAsync(imageUri);
}
}
}
#Override
public void onBackPressed() {
UpdateActivity.UpdatingPhoto = false;
super.onBackPressed();
finish();
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (mCropImageUri != null && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mCropImageView.setImageUriAsync(mCropImageUri);
} else {
Toast.makeText(this, "Required permissions are not granted", Toast.LENGTH_LONG).show();
}
}
/**
* Create a chooser intent to select the source to get image from.<br/>
* The source can be camera's (ACTION_IMAGE_CAPTURE) or gallery's (ACTION_GET_CONTENT).<br/>
* All possible sources are added to the intent chooser.
*/
public Intent getPickImageChooserIntent() {
// Determine Uri of camera image to save.
Uri outputFileUri = getCaptureImageOutputUri();
List<Intent> allIntents = new ArrayList<>();
PackageManager packageManager = getPackageManager();
// collect all camera intents
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
if (outputFileUri != null) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
}
allIntents.add(intent);
}
// collect all gallery intents
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
List<ResolveInfo> listGallery = packageManager.queryIntentActivities(galleryIntent, 0);
for (ResolveInfo res : listGallery) {
Intent intent = new Intent(galleryIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
allIntents.add(intent);
}
// the main intent is the last in the list (Foolish android) so pickup the useless one
Intent mainIntent = allIntents.get(allIntents.size() - 1);
for (Intent intent : allIntents) {
if (intent.getComponent().getClassName().equals("com.android.documentsui.DocumentsActivity")) {
mainIntent = intent;
break;
}
}
allIntents.remove(mainIntent);
// Create a chooser from the main intent
Intent chooserIntent = Intent.createChooser(mainIntent, "Select source");
// Add all other intents
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()]));
return chooserIntent;
}
/**
* Get URI to image received from capture by camera.
*/
private Uri getCaptureImageOutputUri() {
Uri outputFileUri = null;
File getImage = getExternalCacheDir();
if (getImage != null) {
outputFileUri = Uri.fromFile(new File(getImage.getPath(), "pickImageResult.jpeg"));
}
return outputFileUri;
}
/**
* Get the URI of the selected image from {#link #getPickImageChooserIntent()}.<br/>
* Will return the correct URI for camera and gallery image.
*
* #param data the returned data of the activity result
*/
public Uri getPickImageResultUri(Intent data) {
boolean isCamera = true;
if (data != null && data.getData() != null) {
String action = data.getAction();
isCamera = action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE);
}
return isCamera ? getCaptureImageOutputUri() : data.getData();
}
/**
* Test if we can open the given Android URI to test if permission required error is thrown.<br>
*/
public boolean isUriRequiresPermissions(Uri uri) {
try {
ContentResolver resolver = getContentResolver();
InputStream stream = resolver.openInputStream(uri);
stream.close();
return false;
} catch (FileNotFoundException e) {
if (e.getCause() instanceof ErrnoException) {
return true;
}
} catch (Exception e) {
}
return false;
}
}
package com.donateblood.blooddonation;
public double longitude;
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.uploadimage);
code = (EditText) findViewById(R.id.code);
ButterKnife.inject(this);
myimage = CroppingActivity.finalImage;
CheckImage();
// Upload image ====================================
Btn_Upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), CroppingActivity.class);
startActivity(intent);
}
});
Btn_Proceed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(code.length()==0){
Toast.makeText(getBaseContext(), "Enter verification code", Toast.LENGTH_LONG).show();
}
else {
Prcoess();
}
}
});
}
public void CheckImage(){
if(myimage!=null){
// set the image
// myimage = getRoundedShape(myimage);
Uri uri = getImageUri(myimage);
String url = getRealPathFromURI(uri);
File file = new File(url);
Picasso.with(UploadImage.this).load(file).resize(200,200).placeholder(R.drawable.user).error(R.drawable.error)
.transform(new CircleTransform()).centerCrop()
.into(ImageUpload);
}else {
encodedPhotoString= null;
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
public String getRealPathFromURI(Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = UploadImage.this.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();
}
}
}
public Uri getImageUri( Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(UploadImage.this.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
// Processing and adding user to database from here ====================================
public void Prcoess(){
String userentered=code.getText().toString();
String sentcode = SignupActivity.Code;
// resize the image to store to database
//myimage= getResizedBitmap(myimage,200,200);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myimage.compress(Bitmap.CompressFormat.JPEG, 50, stream);
byte[] byte_arr = stream.toByteArray();
encodedPhotoString = Base64.encodeToString(byte_arr, 0);
if(userentered.equals(sentcode) && encodedPhotoString!=null ){
new AddUserAsync().execute();
}
else {
Toast.makeText(getBaseContext(), "Wrong code or No image uploaded", Toast.LENGTH_LONG).show();
}
}
public class AddUserAsync extends AsyncTask<Void,Void,Void> {
JSONObject json =null;
boolean added = false;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UploadImage.this);
pDialog.setMessage("Creating Account...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... voids) {
GetUserDetails();
GenerateGCMID();
email= email.trim().toLowerCase();
HashMap<String ,String> userDetails = new HashMap<>();
latitude = GPSTracker.getLatitude();
longitude = GPSTracker.getLongitude();
userDetails.put("ID",ID);
userDetails.put("Name",name);
userDetails.put("email",email);
userDetails.put("password",password);
userDetails.put("age",age);
userDetails.put("number",number);
userDetails.put("bloodgroup",bloodgroup);
userDetails.put("lat",latitude+"");
userDetails.put("longi",longitude+"");
userDetails.put("image",encodedPhotoString);
json = new HttpCall().postForJSON("http://abdulbasit.website/blood_app/Adduser.php",userDetails);
if(json!=null){
added = true;
}else {
added = false;
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
pDialog.dismiss();
if(added==true){
Toast.makeText(getBaseContext(), "Created Successfully", Toast.LENGTH_LONG).show();
onSignupSuccess();
}else {
Toast.makeText(getBaseContext(), "Error creating account. Try again", Toast.LENGTH_LONG).show();
}
}
}
public void GenerateGCMID(){
GCMClientManager pushClientManager = new GCMClientManager(this, "921544902369");
pushClientManager.registerIfNeeded(new GCMClientManager.RegistrationCompletedHandler() {
#Override
public void onSuccess(String registrationId, boolean isNewRegistration) {
Log.d("Registration id", registrationId);
ID = registrationId;
Log.e("reg",ID);
}
#Override
public void onFailure(String ex) {
super.onFailure(ex);
}
});
}
// Go to another activity on success ====================================
public void onSignupSuccess() {
// stop the service we got the latitude and longitude now
stopService(new Intent(this, GPSTracker.class));
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(intent);
finish();
}
// fetch user details ====================================
public void GetUserDetails(){
bloodgroup = SignupActivity.bloodgroup.toString();
name = SignupActivity.name.toString();
email = SignupActivity.email.toString();
password = SignupActivity.password.toString();
number = SignupActivity.number.toString();
age = SignupActivity.age.toString();
}
// Resize the image ====================================
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth)
{
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
}
check this method you are not finishing the UploadActivity here:-
Btn_Upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), CroppingActivity.class);
startActivity(intent);
UploadActivity.this.finish();
}
});
I want to take a picture without crop and I follow tutorial from Developer Android. This is my class:
Fisrt, I make dialog to show and to get the picture.
public void uploadPO() {
final Dialog d = new Dialog(TransDetailActivity.this);
d.requestWindowFeature(Window.FEATURE_NO_TITLE);
d.getWindow().setBackgroundDrawable(new ColorDrawable((Color.TRANSPARENT)));
d.setContentView(R.layout.upload_po);
final ImageView ivImage1 = (ImageView) d.findViewById(R.id.iv_image1);
final ImageView ivImage2 = (ImageView) d.findViewById(R.id.iv_image2);
final ImageView ivImage3 = (ImageView) d.findViewById(R.id.iv_image3);
final ImageView ivImage4 = (ImageView) d.findViewById(R.id.iv_image4);
ivImage1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectImagePO();
statusOnUpload = 1;
}
});
ivImage2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectImagePO();
statusOnUpload = 2;
}
});
ivImage3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectImagePO();
statusOnUpload = 3;
}
});
ivImage4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectImagePO();
statusOnUpload = 4;
}
});
d.show();
}
Next, i make method for chosing take a photo or choose from gallery.
private void selectImagePO() {
final CharSequence[] options = {"Take Photo", "Choose from Gallery", "Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Add Photo PO!");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Take Photo")) {
selectFrom(PICK_FROM_CAMERA);
/*Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, 1);*/
} else if (options[item].equals("Choose from Gallery")) {
selectFrom(PICK_FROM_GALLERY);
/*Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 2);*/
} else if (options[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
Next, based on previous selection, I made a function in accordance with the selection.
private void selectFrom(int from) {
if (from == PICK_FROM_CAMERA) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, PICK_FROM_CAMERA);
}
} else {
if(Build.VERSION.SDK_INT <19) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), from);
}else{
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_PICK);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), from);
}
}
}
And, i get the error in this class.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//Toast.makeText(getActivity(),""+resultCode+"", Toast.LENGTH_SHORT).show();
if (resultCode == RESULT_OK) {
if (requestCode == PICK_FROM_CAMERA) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap imageBitmap = (Bitmap) extras.get("data");
/*Picasso.with(this)
.load()
.transform(new CircleTransform())
.into(imageProfile);*/
if(statusOnUpload == 1){
ivImage1.setImageBitmap(imageBitmap);
} else if(statusOnUpload == 2){
ivImage2.setImageBitmap(imageBitmap);
}else if(statusOnUpload == 3){
ivImage3.setImageBitmap(imageBitmap);
}else{
ivImage4.setImageBitmap(imageBitmap);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
byte[] b = baos.toByteArray();
if (statusOnUpload == 1) {
encodedImageString1 = Base64.encodeToString(b, Base64.NO_WRAP);
Log.d(TAG, encodedImageString1.toString());
} else if (statusOnUpload == 2) {
encodedImageString2 = Base64.encodeToString(b, Base64.NO_WRAP);
} else if (statusOnUpload == 3) {
encodedImageString3 = Base64.encodeToString(b, Base64.NO_WRAP);
} else if (statusOnUpload == 4) {
encodedImageString4 = Base64.encodeToString(b, Base64.NO_WRAP);
}
//Log.i("")
//Toast.makeText(getApplicationContext(),""+encodedImageString+"",Toast.LENGTH_SHORT).show();
//DialogDeal dialogDeal=new DialogDeal(EditProfileActivity.this,"imageBase64",encodedImageString,"Cancel");
//dialogDeal.show();
} else {
//LogManager.logI("extras == null");
}
} else if (requestCode == PICK_FROM_GALLERY) {
mImageCaptureUri = data.getData();
doCrop();
}
}
}
What's the problem of my development?
First make sure you the correct permissions in your manifest. I know you're using a camera app as a service, but I think you may need:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
If that doesn't help you may want to try using this class below. Dealing with hardware like camera is never simple. I suggest using this base activity. I found it somewhere a long time ago here on SO. It handles some fragmentation issues.
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.util.Date;
import java.util.Locale;
public abstract class BaseCameraIntentActivity extends BaseActivity
{
private static final String PACKAGE_NAME = "com.your.package";
private static final String DATE_CAMERA_INTENT_STARTED_STATE =
PACKAGE_NAME+"dateCameraIntentStarted";
private static final String CAMERA_PIC_URI_STATE =
PACKAGE_NAME+"CAMERA_PIC_URI_STATE";
private static final String PHOTO_URI_STATE =
PACKAGE_NAME+"PHOTO_URI_STATE";
private static final String ROTATE_X_DEGREES_STATE =
PACKAGE_NAME+"ROTATE_X_DEGREES_STATE";
/**
* Date and time the camera intent was started.
*/
protected static Date dateCameraIntentStarted = null;
/**
* Default location where we want the photo to be ideally stored.
*/
protected static Uri preDefinedCameraUri = null;
/**
* Potential 3rd location of photo data.
*/
protected static Uri photoUriIn3rdLocation = null;
/**
* Retrieved location of the photo.
*/
protected static Uri photoUri = null;
/**
* Orientation of the retrieved photo.
*/
protected static int rotateXDegrees = 0;
private final static int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
/**
* Saves the current state of the activity.
*/
#Override
protected void onSaveInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
if (dateCameraIntentStarted != null) {
savedInstanceState.putString(
DATE_CAMERA_INTENT_STARTED_STATE,
DateHelper.dateToString(dateCameraIntentStarted));
}
if (preDefinedCameraUri != null) {
savedInstanceState.putString(
CAMERA_PIC_URI_STATE,
preDefinedCameraUri.toString());
}
if (photoUri != null) {
savedInstanceState.putString(
PHOTO_URI_STATE,
photoUri.toString());
}
savedInstanceState.putInt(
ROTATE_X_DEGREES_STATE,
rotateXDegrees);
}
/**
* Re-initializes a saved state of the activity.
*/
#Override
protected void onRestoreInstanceState(#NonNull Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState.containsKey(DATE_CAMERA_INTENT_STARTED_STATE)) {
dateCameraIntentStarted = DateHelper.stringToDate(
savedInstanceState.getString(DATE_CAMERA_INTENT_STARTED_STATE));
}
if (savedInstanceState.containsKey(CAMERA_PIC_URI_STATE)) {
preDefinedCameraUri = Uri.parse(savedInstanceState.getString(CAMERA_PIC_URI_STATE));
}
if (savedInstanceState.containsKey(PHOTO_URI_STATE)) {
photoUri = Uri.parse(savedInstanceState.getString(PHOTO_URI_STATE));
}
rotateXDegrees = savedInstanceState.getInt(ROTATE_X_DEGREES_STATE);
}
/**
* Starts the camera intent depending on the device configuration.
* <p/>
* <b>for Samsung and Sony devices:</b>
* We call the camera activity with the method call to startActivityForResult.
* We only set the constant CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE. We do NOT set any other intent extras.
* <p/>
* <b>for all other devices:</b>
* We call the camera activity with the method call to startActivityForResult as previously.
* This time, however, we additionally set the intent extra MediaStore.EXTRA_OUTPUT
* and provide an URI, where we want the image to be stored.
* <p/>
* In both cases we remember the time the camera activity was started.
*/
public void startCameraIntent()
{
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
try {
// NOTE: Do NOT SET: intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraPicUri)
// on Samsung Galaxy S2/S3/.. for the following reasons:
// 1.) it will break the correct picture orientation
// 2.) the photo will be stored in two locations (the given path and, additionally, in the MediaStore)
String manufacturer = android.os.Build.MANUFACTURER.toLowerCase(Locale.ENGLISH);
String model = android.os.Build.MODEL.toLowerCase(Locale.ENGLISH);
String buildType = android.os.Build.TYPE.toLowerCase(Locale.ENGLISH);
String buildDevice = android.os.Build.DEVICE.toLowerCase(Locale.ENGLISH);
String buildId = android.os.Build.ID.toLowerCase(Locale.ENGLISH);
// String sdkVersion = android.os.Build.VERSION.RELEASE.toLowerCase(Locale.ENGLISH);
boolean setPreDefinedCameraUri = false;
if (!(manufacturer.contains("samsung")) && !(manufacturer.contains("sony"))) {
setPreDefinedCameraUri = true;
}
if (manufacturer.contains("samsung") && model.contains("galaxy nexus")) { //TESTED
setPreDefinedCameraUri = true;
}
if (manufacturer.contains("samsung") && model.contains("gt-n7000") && buildId.contains("imm76l")) { //TESTED
setPreDefinedCameraUri = true;
}
if (buildType.contains("userdebug") && buildDevice.contains("ariesve")) { //TESTED
setPreDefinedCameraUri = true;
}
if (buildType.contains("userdebug") && buildDevice.contains("crespo")) { //TESTED
setPreDefinedCameraUri = true;
}
if (buildType.contains("userdebug") && buildDevice.contains("gt-i9100")) { //TESTED
setPreDefinedCameraUri = true;
}
///////////////////////////////////////////////////////////////////////////
// TEST
if (manufacturer.contains("samsung") && model.contains("sgh-t999l")) { //T-Mobile LTE enabled Samsung S3
setPreDefinedCameraUri = true;
}
if (buildDevice.contains("cooper")) {
setPreDefinedCameraUri = true;
}
if (buildType.contains("userdebug") && buildDevice.contains("t0lte")) {
setPreDefinedCameraUri = true;
}
if (buildType.contains("userdebug") && buildDevice.contains("kot49h")) {
setPreDefinedCameraUri = true;
}
if (buildType.contains("userdebug") && buildDevice.contains("t03g")) {
setPreDefinedCameraUri = true;
}
if (buildType.contains("userdebug") && buildDevice.contains("gt-i9300")) {
setPreDefinedCameraUri = true;
}
if (buildType.contains("userdebug") && buildDevice.contains("gt-i9195")) {
setPreDefinedCameraUri = true;
}
if (buildType.contains("userdebug") && buildDevice.contains("xperia u")) {
setPreDefinedCameraUri = true;
}
///////////////////////////////////////////////////////////////////////////
dateCameraIntentStarted = new Date();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (setPreDefinedCameraUri) {
// String filename = ImageConfig.getTempFileName();
String filename = System.currentTimeMillis() + ".jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, filename);
preDefinedCameraUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values);
intent.putExtra(MediaStore.EXTRA_OUTPUT, preDefinedCameraUri);
}
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
} catch (ActivityNotFoundException e) {
logException(e);
onCouldNotTakePhoto();
}
} else {
onSdCardNotMounted();
}
}
/**
* Receives all activity results and triggers onCameraIntentResult if
* the requestCode matches.
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
super.onActivityResult(requestCode, resultCode, intent);
switch (requestCode) {
case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE: {
onCameraIntentResult(requestCode, resultCode, intent);
break;
}
}
}
/**
* On camera activity result, we try to locate the photo.
* <p/>
* <b>Mediastore:</b>
* First, we try to read the photo being captured from the MediaStore.
* Using a ContentResolver on the MediaStore content, we retrieve the latest image being taken,
* as well as its orientation property and its timestamp.
* If we find an image and it was not taken before the camera intent was called,
* it is the image we were looking for.
* Otherwise, we dismiss the result and try one of the following approaches.
* <b>Intent extra:</b>
* Second, we try to get an image Uri from intent.getData() of the returning intent.
* If this is not successful either, we continue with step 3.
* <b>Default photo Uri:</b>
* If all of the above mentioned steps did not work, we use the image Uri we passed to the camera activity.
*
* #param requestCode
* #param resultCode
* #param intent
*/
protected void onCameraIntentResult(int requestCode, int resultCode, Intent intent)
{
if (resultCode == RESULT_OK) {
Cursor myCursor = null;
Date dateOfPicture = null;
try {
// Create a Cursor to obtain the file Path for the large image
String[] largeFileProjection = {MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.ImageColumns.ORIENTATION,
MediaStore.Images.ImageColumns.DATE_TAKEN};
String largeFileSort = MediaStore.Images.ImageColumns._ID + " DESC";
myCursor = getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
largeFileProjection,
null, null,
largeFileSort);
myCursor.moveToFirst();
if (!myCursor.isAfterLast()) {
// This will actually give you the file path location of the image.
String largeImagePath = myCursor.getString(
myCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA)
);
photoUri = Uri.fromFile(new File(largeImagePath));
if (photoUri != null) {
dateOfPicture = new Date(
myCursor.getLong(
myCursor.getColumnIndexOrThrow(
MediaStore.Images.ImageColumns.DATE_TAKEN)));
if (dateOfPicture != null && dateOfPicture.after(dateCameraIntentStarted)) {
rotateXDegrees = myCursor.getInt(myCursor
.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.ORIENTATION));
} else {
photoUri = null;
}
}
if (myCursor.moveToNext() && !myCursor.isAfterLast()) {
String largeImagePath3rdLocation = myCursor.getString(myCursor
.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
Date dateOfPicture3rdLocation = new Date(
myCursor.getLong(myCursor.getColumnIndexOrThrow(
MediaStore.Images.ImageColumns.DATE_TAKEN))
);
if (dateOfPicture3rdLocation != null && dateOfPicture3rdLocation.after(dateCameraIntentStarted)) {
photoUriIn3rdLocation = Uri.fromFile(new File(largeImagePath3rdLocation));
}
}
}
} catch (Exception e) {
logException(e);
} finally {
if (myCursor != null && !myCursor.isClosed()) {
myCursor.close();
}
}
if (photoUri == null) {
try {
photoUri = intent.getData();
} catch (Exception e) {
}
}
if (photoUri == null) {
photoUri = preDefinedCameraUri;
}
try {
if (photoUri != null && new File(photoUri.getPath()).length() <= 0) {
if (preDefinedCameraUri != null) {
Uri tempUri = photoUri;
photoUri = preDefinedCameraUri;
preDefinedCameraUri = tempUri;
}
}
} catch (Exception e) {
}
photoUri = getFileUriFromContentUri(photoUri);
preDefinedCameraUri = getFileUriFromContentUri(preDefinedCameraUri);
try {
if (photoUriIn3rdLocation != null) {
if (photoUriIn3rdLocation.equals(photoUri)
|| photoUriIn3rdLocation.equals(preDefinedCameraUri)) {
photoUriIn3rdLocation = null;
} else {
photoUriIn3rdLocation = getFileUriFromContentUri(photoUriIn3rdLocation);
}
}
} catch (Exception e) {
}
if (photoUri != null) {
onPhotoUriFound();
} else {
onPhotoUriNotFound();
}
} else if (resultCode == Activity.RESULT_CANCELED) {
onCanceled();
} else {
onCanceled();
}
}
/**
* Being called if the photo could be located. The photo's Uri
* and its orientation could be retrieved.
*/
protected void onPhotoUriFound()
{
logMessage("Your photo is stored under: " + photoUri.toString());
}
/**
* Being called if the photo could not be located (Uri == null).
*/
protected void onPhotoUriNotFound()
{
logMessage("Could not find a photoUri that is != null");
}
/**
* Being called if the camera intent could not be started or something else went wrong.
*/
protected void onCouldNotTakePhoto()
{
Toast.makeText(getApplicationContext(), getString(R.string.error_could_not_take_photo), Toast.LENGTH_LONG).show();
}
/**
* Being called if the SD card (or the internal mass storage respectively) is not mounted.
*/
protected void onSdCardNotMounted()
{
Toast.makeText(getApplicationContext(), getString(R.string.error_sd_card_not_mounted), Toast.LENGTH_LONG).show();
}
/**
* Being called if the camera intent was canceled.
*/
protected void onCanceled()
{
logMessage("Camera Intent was canceled");
}
/**
* Logs the passed exception.
*
* #param exception
*/
protected void logException(Exception exception)
{
logMessage(exception.toString());
}
/**
* Logs the passed exception messages.
*
* #param exceptionMessage
*/
protected void logMessage(String exceptionMessage)
{
Log.d(getClass().getName(), exceptionMessage);
}
/**
* Given an Uri that is a content Uri (e.g.
* content://media/external/images/media/1884) this function returns the
* respective file Uri, that is e.g. file://media/external/DCIM/abc.jpg
*
* #param cameraPicUri
* #return Uri
*/
private Uri getFileUriFromContentUri(Uri cameraPicUri)
{
try {
if (cameraPicUri != null
&& cameraPicUri.toString().startsWith("content")) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(cameraPicUri, proj, null, null, null);
cursor.moveToFirst();
// This will actually give you the file path location of the image.
String largeImagePath = cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
cursor.close();
return Uri.fromFile(new File(largeImagePath));
}
return cameraPicUri;
} catch (Exception e) {
return cameraPicUri;
}
}
}
The complete code of my Fragment:
public class ProfileEditPictureFragment extends BaseFragment implements OnClickListener {
private ImageView imageView = null;
private Button buttonPick = null;
private Button buttonSave = null;
private Button buttonCancel = null;
private File tempFile = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRetainInstance(true);
this.sessionProfilePreferences = new SessionProfilePreferences(this.getActivity());
this.sessionLoginPreferences = new SessionLoginPreferences(this.getActivity());
this.sessionLoginSingleton = SessionLoginSingleton.getInstance(this.getActivity());
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
this.tempFile = new File(Environment.getExternalStorageDirectory(), "temp_photo.jpg");
}
else {
this.tempFile = new File(this.getActivity().getFilesDir(), "temp_photo.jpg");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_profile_picture_edit, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
this.imageView = (ImageView) view.findViewById(R.id.profile_picture_edit_imageview_photo);
this.buttonPick = (Button) view.findViewById(R.id.profile_picture_edit_button_pick);
this.buttonPick.setOnClickListener(this);
this.buttonSave = (Button) view.findViewById(R.id.profile_picture_edit_button_save);
this.buttonSave.setOnClickListener(this);
this.buttonCancel = (Button) view.findViewById(R.id.profile_picture_edit_button_cancel);
this.buttonCancel.setOnClickListener(this);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.v("ProfileEditPicture", "requestCode: " + requestCode);
Log.v("ProfileEditPicture", "resultCode: " + resultCode);
Log.v("ProfileEditPicture", "data: " + data);
Bitmap bitmap = null;
if(resultCode == Activity.RESULT_OK) {
if (requestCode == Globals.REQUEST_PICK_PHOTO) {
try {
InputStream inputStream = this.getActivity().getContentResolver().openInputStream(data.getData());
FileOutputStream fileOutputStream = new FileOutputStream(this.tempFile);
Helper.copyStream(inputStream, fileOutputStream);
fileOutputStream.close();
inputStream.close();
this.startCropImage();
} catch (Exception e) {}
} else if (requestCode == Globals.REQUEST_CROP_PHOTO) {
String path = data.getStringExtra(CropActivity.IMAGE_PATH);
if (path == null) {
return;
}
bitmap = BitmapFactory.decodeFile(this.tempFile.getPath());
this.imageView.setImageBitmap(bitmap);
}
}
}
#Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.profile_picture_edit_button_pick : {
this.pickPicture();
} break;
case R.id.profile_picture_edit_button_save : {
} break;
case R.id.profile_picture_edit_button_cancel : {
this.getActivity().finish();
}
}
}
private void pickPicture() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
this.startActivityForResult(Intent.createChooser(intent, "Select Picture"), Globals.REQUEST_PICK_PHOTO);
}
private void startCropImage() {
Intent intent = new Intent(this.getActivity(), CropActivity.class);
intent.putExtra(CropActivity.IMAGE_PATH, this.tempFile.getPath());
intent.putExtra(CropActivity.SCALE, true);
intent.putExtra(CropActivity.ASPECT_X, 3);
intent.putExtra(CropActivity.ASPECT_Y, 2);
this.startActivityForResult(intent, Globals.REQUEST_CROP_PHOTO);
}
}
But the resultCode is always 0 and the data is always null. Permissions are set ofcourse.
So how can i pick images from the gallery?
I test it on Nexus 4 with Android 5.0.1
Try ACTION_PICK like this
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
And on Activity result
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK
&& null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imgDecodableString = cursor.getString(columnIndex);
cursor.close();
ImageView imgView = (ImageView) findViewById(R.id.imgView);
imgView.setImageBitmap(BitmapFactory
.decodeFile(imgDecodableString));
} else {
Toast.makeText(this, "You haven't picked Image",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
.show();
}
}
I was having same problem in one of my activities when I set launchMode="singleInstance" in manifest for that activity. It works fine when I remove that attribute. Although I don't know reason for this behaviour.