Im taking a photo with the following code
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photoPath = new File(getExternalFilesDir(null), "postcard.jpg");
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoPath));
log.debug("start camera for {}", photoPath.getAbsolutePath());
startActivityForResult(takePhotoIntent, REQUEST_TAKE_PHOTO);
...
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO) {
if (resultCode == RESULT_OK) {
log.debug("photo successfully created");
} else {
log.error("problem to take photo resultCode={}", resultCode);
}
} else {
log.debug("not my request: {}", requestCode);
}
}
This works fine on Android 5, but fails on Android 6 with resultCode=0 (RESULT_CANCELED) and the logcat error message:
03-09 07:56:13.759 878-3735/? W/ActivityManager: Appop Denial:
starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3
cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity
clip={text/uri-list
U:file:///storage/emulated/0/Android/data/censored.package.name.here/files/postcard.jpg}
(has extras) } from ProcessRecord{55cce35
21309:censored.package.name.here/u0a136} (pid=21309, uid=10136)
requires android:camera
I have the following in the Android Manifest:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
I also check if the application really has the camera permission, this check passes.
checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
Also worth noting, I include an aar in the project that also uses the camera. This included library has this in the manifest:
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
<uses-feature android:name="android.hardware.screen.landscape" android:required="false" />
<uses-feature android:name="android.hardware.wifi" android:required="false"/>
Does anybody have an idea what the error message means or how to fix this? Google wasn't helpful in this case.
Up to now, I wasn't successful to reproduce the problem with a small example. It seems to be some interaction with another app part.
After more than a day experimenting and debugging it works now. The code is still exactly the same.
I guess, retracting the camera permission via the settings and then re-enabling it did the trick but I am not completely sure.
Posting this as an answer if somebody runs into the same problem.
-- Complete code for capturing image ,saving to SD card , pick from gallery,compress,rotate image,etc.. 200% working.
public class A extends AppCompatActivity implements View.OnClickListener, AsyncTaskCompleteListener {
private static final String IMAGE_DIRECTORY = "/idyme";
private static int MAX_IMAGE_DIMENSION = 200;
private final String TAG = "RegisterFragment";
private Button btnVerify, btnUploadImage;
private String ImgPath = null, filePath = null,
profileImageFilePath, profileImageData = null,imageVideoType = "", imageVideoPath = "";
private ImageView ivImage;
private AQuery aQuery;
private Uri uri = null;
private ImageOptions imageOptions;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vip_registration);
ivImage = (ImageView) findViewById(R.id.ivProfile);
aQuery = new AQuery(this);
imageOptions = new ImageOptions();
imageOptions.memCache = true;
imageOptions.fileCache = true;
imageOptions.fallback = R.drawable.userimage;
}
#Override
public void onClick(View v) {
// onRegisterButtonClick();
switch (v.getId()) {
case R.id.btnUploadImage:
showPictureDialog();
}
}
private void showPictureDialog() {
AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
pictureDialog.setTitle(getResources().getString(
R.string.dialog_chhose_photo));
String[] pictureDialogItems = {
getResources().getString(R.string.dialog_from_gallery),
getResources().getString(R.string.dialog_from_camera)};
pictureDialog.setItems(pictureDialogItems,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
choosePhotoFromGallary();
break;
case 1:
takePhotoFromCamera();
break;
}
}
});
pictureDialog.show();
}
private void choosePhotoFromGallary() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, Constants.CHOOSE_PHOTO);
}
private void takePhotoFromCamera() {
Calendar cal = Calendar.getInstance();
File file = new File(Environment.getExternalStorageDirectory(),
(cal.getTimeInMillis() + ".jpg"));
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
} else {
file.delete();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
// uri = Uri.fromFile(file);
uri = getOutputMediaFileUri();
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(cameraIntent, Constants.TAKE_PHOTO);
}
public Uri getOutputMediaFileUri() {
return Uri.fromFile(getOutputMediaFile());
}
private String getRealPathFromURI(Uri contentURI) {
String result;
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = this.getContentResolver().query(contentURI, proj, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file
// path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == this.RESULT_CANCELED) {
return;
}
if (requestCode == Constants.CHOOSE_PHOTO) {
if (data != null) {
Uri contentURI = data.getData();
profileImageData = getRealPathFromURI(contentURI);
// new AQuery(getApplicationContext()).id(ivMeme).image(
// profileImageData, imageOptions);
try {
String path = saveImage(scaleImage(this, contentURI));
imageVideoPath = path;
aQuery.id(R.id.ivProfile).image(
imageVideoPath, imageOptions);
} catch (IOException e) {
e.printStackTrace();
Utils.showToast("Failed", this);
}
}
} else if (requestCode == Constants.TAKE_PHOTO) {
// old
if (uri != null) {
profileImageFilePath = uri.getPath();
if (profileImageFilePath != null
&& profileImageFilePath.length() > 0) {
File myFile = new File(profileImageFilePath);
String path = saveImage(BitmapFactory
.decodeFile(profileImageFilePath));
imageVideoPath = path;
aQuery.id(R.id.ivProfile).image(
imageVideoPath, imageOptions);
} else {
Utils.showToast("Failed", this);
}
} else {
Utils.showToast("Failed", this);
}
}
}
public String saveImage(Bitmap myBitmap) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File wallpaperDirectory = new File(
Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
// have the object build the directory structure, if needed.
if (!wallpaperDirectory.exists()) {
wallpaperDirectory.mkdirs();
}
try {
File f = new File(wallpaperDirectory, Calendar.getInstance()
.getTimeInMillis() + ".jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
MediaScannerConnection.scanFile(this,
new String[]{f.getPath()},
new String[]{"image/jpeg"}, null);
fo.close();
AppLog.Log("TAG", "File Saved::-> " + f.getAbsolutePath());
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
private static File getOutputMediaFile() {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY, "Oops! Failed create " + IMAGE_DIRECTORY
+ " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
return mediaFile;
}
public static Bitmap scaleImage(Context context, Uri photoUri)
throws IOException {
InputStream is = context.getContentResolver().openInputStream(photoUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();
int rotatedWidth, rotatedHeight;
int orientation = getOrientation(context, photoUri);
if (orientation == 90 || orientation == 270) {
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
if (rotatedWidth > MAX_IMAGE_DIMENSION
|| rotatedHeight > MAX_IMAGE_DIMENSION) {
float widthRatio = ((float) rotatedWidth)
/ ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight)
/ ((float) MAX_IMAGE_DIMENSION);
float maxRatio = Math.max(widthRatio, heightRatio);
// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
srcBitmap = BitmapFactory.decodeStream(is);
}
is.close();
/*
* if the orientation is not 0 (or -1, which means we don't know), we
* have to do a rotation.
*/
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0,
srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true);
}
String type = context.getContentResolver().getType(photoUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (type.equals("image/png")) {
srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
} else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
byte[] bMapArray = baos.toByteArray();
baos.close();
return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);
}
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[]{MediaStore.Images.ImageColumns.ORIENTATION},
null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
}
-- Permission required :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
Related
I am trying to capture an image using the camera, however on saving the file I get the following error:
java.lang.NullPointerException: file
at android.net.Uri.fromFile(Uri.java:452)
at com.example.denny.lostandfound.ReportFoundItem.dispatchTakePictureIntent(ReportFoundItem.java:84)
at com.example.denny.lostandfound.ReportFoundItem.access$000(ReportFoundItem.java:39)
at com.example.denny.lostandfound.ReportFoundItem$1.onClick(ReportFoundItem.java:169)
at android.view.View.performClick(View.java:5265)
at android.view.View$PerformClick.run(View.java:21534)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5728)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
I want to capture image directly from the camera and save it to a database. How can this be fixed?
AndroidManifest.xml file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/icon"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.denny.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepaths" />
</provider>
<activity android:name=".Home">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>....
My ReportFoundItem.xml:
public class ReportFoundItem extends AppCompatActivity {
private DatabaseReference databaseFound;
private static final int CAPTURE_IMAGE = 1;
private Uri picUri;
private StorageReference mStorage;
private ProgressDialog mProgress;
private EditText etemail;
private EditText etphone;
private Spinner etcategory;
private Spinner etsub_category;
private Button btncapture;
private ImageView imageView;
private EditText etdate_found;
private EditText etlocation_found;
private EditText etdetails;
private void dispatchTakePictureIntent() {
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File file = getOutputMediaFile(1);
picUri = Uri.fromFile(file);
i.putExtra(MediaStore.EXTRA_OUTPUT,picUri); // set the image file
startActivityForResult(i, CAPTURE_IMAGE);
}
public File getOutputMediaFile(int type) {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "TRARC");
/**Create the storage directory if it does not exist*/
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
/**Create a media file name*/
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == 1){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".png");
} else {
return null;
}
return mediaFile;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_report_found_item);
mStorage = FirebaseStorage.getInstance().getReference();
databaseFound = FirebaseDatabase.getInstance().getReference("found");
etemail = (EditText)findViewById(R.id.etemail);
etphone = (EditText)findViewById(R.id.etphone);
etcategory = (Spinner)findViewById(R.id.etcategory);
etsub_category = (Spinner)findViewById(R.id.etsub_category);
btncapture = (Button)findViewById(R.id.btncapture);
imageView = (ImageView)findViewById(R.id.imageView);
etdate_found = (EditText) findViewById(R.id.etdate_found);
etlocation_found = (EditText) findViewById(R.id.etlocation_found);
etdetails = (EditText) findViewById(R.id.etdetails);
mProgress = new ProgressDialog(this);
btncapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dispatchTakePictureIntent();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAPTURE_IMAGE && resultCode == RESULT_OK){
mProgress.setMessage("Uploading Image...Please wait...");
mProgress.show();
final StorageReference filepath = mStorage.child("Found_Photos").child(uri.getLastPathSegment());
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
mProgress.dismiss();
//creating the upload object to store uploaded image details
Upload upload = new Upload(uri.toString(),taskSnapshot.getDownloadUrl().toString());
//adding an upload to firebase database
String uploadId = databaseFound.push().getKey();
databaseFound.child(uploadId).setValue(upload);
Uri downloadUri = taskSnapshot.getDownloadUrl();
Picasso.with(ReportFoundItem.this).load(downloadUri).fit().centerCrop().into(imageView);
//Toast.makeText(ReportFoundItem.this, "Uploading finished...", Toast.LENGTH_LONG).show();
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
mProgress.setMessage("Uploaded " + ((int) progress) + "%...");
}
});//add on failure listener
}
}
private void reportFoundItem() {
String email = etemail.getText().toString().trim();
String phone = etphone.getText().toString().trim();
String category = etcategory.getSelectedItem().toString().trim();
String sub_category = etsub_category.getSelectedItem().toString().trim();
String date_found = etdate_found.getText().toString().trim();
String location_found = etlocation_found.getText().toString().trim();
String details = etdetails.getText().toString().trim();
//check if empty
if (!TextUtils.isEmpty(email)){
//getting the key
String id = databaseFound.push().getKey();
//save the data under lost
Found found = new Found(id, email, phone, category, sub_category, date_found, location_found, details);
//set the value under the id
databaseFound.child(id).setValue(found);
Toast.makeText(this, "Found Item added successfully!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Please enter all Fields!", Toast.LENGTH_SHORT).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.savetodb, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
reportFoundItem();
ClearEditTextAfterDoneTask();
}
return true;
}
#Override
public void onBackPressed()
{
super.onBackPressed();
startActivity(new Intent(ReportFoundItem.this, Home.class));
finish();
}
public void ClearEditTextAfterDoneTask() {
etemail.getText().clear();
etphone.getText().clear();
etdate_found.getText().clear();
etlocation_found.getText().clear();
etdetails.getText().clear();
}
}
I expect to save the picture directly once I capture it from the camera.
Try this one ...
Image Captured....
private int REQUEST_IMAGE_CAPTURE = 100;
on Click ....
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
on ActivityResult ....
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
// Bundle extras = data.getExtras();
Bitmap bitmap = ImageUtils.getBitmapFromIntent(this, data);
mImage.setImageBitmap(bitmap);// mImage is a ImageView which is bind previously.
String imgPath = ImageUtils.createFile(this, bitmap);
File imageFile = new File(imgPath);
}
and other Method....
public class ImageUtils {
public static Bitmap getBitmapFromIntent(Context context,Intent data) {
Bitmap bitmap = null;
if (data.getData() == null) {
bitmap = (Bitmap) data.getExtras().get("data");
} else {
try {
bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
return bitmap;
}
public static String createFile(Context context, Bitmap data) {
Uri selectedImage = getImageUri(context,data);
String[] filePath = {MediaStore.Images.Media.DATA};
Cursor c = context.getContentResolver().query(selectedImage, filePath, null, null, null);
c.moveToFirst();
c.getColumnIndex(filePath[0]);
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
return picturePath;
}
public static Uri getImageUri(Context context, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), inImage, "Pet_Image", null);
return Uri.parse(path);
}
}
Note:- you are getting URI null because the image you capturing doesn't have any path. So URI return null..
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_FILE)
onSelectFromGalleryResult(data);
else if (requestCode == REQUEST_CAMERA)
onCaptureImageResult(data);
}
}
private void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
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();
}
user_image.setImageBitmap(thumbnail);
}
private void onSelectFromGalleryResult(Intent data) {
Bitmap bm = null;
if (data != null) {
try {
bm =
MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(),
data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
user_image.setImageBitmap(bm);
}
check data is !=null to avoid nullpointer exception
this is how I did it in my project .
public void openCamera() {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File file = createImageFile();
boolean isDirectoryCreated = file.getParentFile().mkdirs();
Log.d("===PickFragment", "openCamera: isDirectoryCreated: " + isDirectoryCreated);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri tempFileUri = FileProvider.getUriForFile(getActivity().getApplicationContext(),
"com.scanlibrary.provider", // As defined in Manifest
file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempFileUri);
} else {
Uri tempFileUri = Uri.fromFile(file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempFileUri);
}
startActivityForResult(cameraIntent, ScanConstants.START_CAMERA_REQUEST_CODE);
}
private File createImageFile() {
clearTempImages();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new
Date());
File file = new File(Environment
.getExternalStorageDirectory().getPath(), "IMG_" + timeStamp +
".jpg");
fileUri = Uri.fromFile(file);
return file;
}
This question already has answers here:
Android marshmallow request permission?
(26 answers)
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 1 year ago.
I have two problems with my app. First problem is that I get an IOException:permission denied even tho I would think I have already all the permissions that I need.
The method dispatchTakePictureIntent when I run photoFile = createImageFile() triggers the permission error.
The othe problem that I have is that I want to separate all the camera-stuff and file creation-stuff to separate classes. But what is the best way to pass information/variable data between classes in a good way. Is this something I should use callbacks or observers for? I would really be glad if someone could provide a simple example of how to do this.
MainActivity:
public class MainActivity extends AppCompatActivity {
EncodeToBase64 encode = new EncodeToBase64();
String lastPhotoAsBase64;
ImageView mImageView;
ImageView mBackground;
private static int RESULT = 1;
static final int REQUEST_TAKE_PHOTO = 1;
static final int PICK_IMAGE_REQUEST = 2;
String mCurrentPhotoPath;
TextView textView;
ProgressBar progress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RESULT);
}
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageView);
mBackground = findViewById(R.id.backgroundImage);
Button cameraButton = findViewById(R.id.cameraButton);
Button galleryButton = findViewById(R.id.galleryButton);
textView = findViewById(R.id.textView);
progress = findViewById(R.id.progressBar);
cameraButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
galleryButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, PICK_IMAGE_REQUEST);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
try {
setPic();
} catch (IOException e) {
e.printStackTrace();
}
} else if (requestCode == PICK_IMAGE_REQUEST && data.getData() != null) {
Uri selectedImage = data.getData();
try {
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
mCurrentPhotoPath = picturePath;
cursor.close();
setPic();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalStoragePublicDirectory(DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
galleryAddPic();
return image;
}
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
}
return 0;
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
public void setPic() throws IOException {
// Get the dimensions of the View
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
//BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
ExifInterface exif = new ExifInterface(mCurrentPhotoPath);
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
//int deg = rotationInDegrees;
Matrix matrix = new Matrix();
if (rotation != 0f) {
matrix.preRotate(rotationInDegrees);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
lastPhotoAsBase64 = encode.encode(bitmap);
if (lastPhotoAsBase64 != null) {
new postData().execute(lastPhotoAsBase64);
} else {
Toast.makeText(MainActivity.this, "No base64 data found!", Toast.LENGTH_LONG).show();
}
mImageView.setImageBitmap(bitmap);
}
public 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
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
public class postData extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... strings) {
HttpConnectionActivity hh = new HttpConnectionActivity();
String temp = hh.HttpConnection(strings[0]);
return temp;
}
#Override
protected void onPreExecute() {
textView.setVisibility(View.INVISIBLE);
progress.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(String s) {
progress.setVisibility(View.INVISIBLE);
JSONObject jsonRaw = null;
String age = null;
String gender = null;
String result = null;
if(!(s.contains("5002"))) {
try {
jsonRaw = new JSONObject(s);
age = jsonRaw.getJSONArray("images").getJSONObject(0).getJSONArray("faces").getJSONObject(0).getJSONObject("attributes").getString("age");
gender = jsonRaw.getJSONArray("images").getJSONObject(0).getJSONArray("faces").getJSONObject(0).getJSONObject("attributes").getJSONObject("gender").getString("type");
result = "Du är en " + ((gender.equals("M")) ? "Man" : "Kvinna") + " som är " + age + " år gammal";
} catch (JSONException e) {
e.printStackTrace();
}
}
else{
result = "Inga ansikten hittades";
}
textView.setText(result);
textView.setVisibility(View.VISIBLE);
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cliff.camera2">
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
</application>
</manifest>
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="DCIM/SkitApp" />
</paths>
The CAMERA permission is a dangerous permission, so is WRITE_EXTERNAL_STORAGE. Starting in API 23 you have to request these permissions at runtime. Meaning even though you list it in the manifest, for API >= 23 you have to request them
I am working on an app in which I want to get image from gallery or camera and then send it to server using multipart. I am able to send picture from gallery to server but when I tried to send image from camera it shows me failure.
// code for the same
// code fro open camera
private void cameraIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
}
// on activity result
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CAMERA) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
Log.d("TAG", "onActivityResult: "+Uri.fromFile(destination));
filePath = destination.toString();
if (filePath != null) {
try {
execMultipartPost();
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(getActivity(), "Image not capturd!", Toast.LENGTH_LONG).show();
}
}
// send to server code
private void execMultipartPost() throws Exception {
File file = new File(filePath);
String contentType = file.toURL().openConnection().getContentType();
Log.d("TAG", "file new path: " + file.getPath());
Log.d("TAG", "contentType: " + contentType);
RequestBody fileBody = RequestBody.create(MediaType.parse(contentType), file);
final String filename = "file_" + System.currentTimeMillis() / 1000L;
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("date", "21-09-2017")
.addFormDataPart("time", "11.56")
.addFormDataPart("description", "hello")
.addFormDataPart("image", filename + ".jpg", fileBody)
.build();
Log.d("TAG", "execMultipartPost: "+requestBody);
okhttp3.Request request = new okhttp3.Request.Builder()
.url("http://myexample/api/user/lets_send")
.post(requestBody)
.build();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, final IOException e) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getActivity(), "nah", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onResponse(Call call, final okhttp3.Response response) throws IOException {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Log.d("TAG", "response of image: " + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
});
}
Try This, it may help
Intent takePhotoIntent= new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Date date = new Date();
String timeStamp = new SimpleDateFormat(pictureNameDateFormat, Locale.US).format(date.getTime());
File fileDirectory = new File(Environment.getExternalStorageDirectory() + "/Pictures");
if (fileDirectory.exists()) {
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(
new File(Environment.getExternalStorageDirectory() + "/Pictures/picture_"+ timeStamp + ".png")));
takePhotoIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
takePhotoIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (takePhotoIntent.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivityForResult(takeVideoIntent, captureVideoActivityRequestCode);
}
}
private void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
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();
}
Log.e("path",Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
}
Please use below code to capture image by camera and for pick image from gallery and you can crop also.
First of all please add this dependency in your build.gradle
compile 'com.theartofdev.edmodo:android-image-cropper:2.3.+'
In your Activity please add this code :
uploadPic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onSelectImageClick(view);
}
});
/**
* Start pick image activity with chooser.
*/
public void onSelectImageClick(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(AccountSettingActivity.this, android.Manifest.permission.CAMERA) + ContextCompat.checkSelfPermission(AccountSettingActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(AccountSettingActivity.this, new String[]{android.Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, MY_REQUEST_CAMERA);
} else if (ContextCompat.checkSelfPermission(AccountSettingActivity.this, android.Manifest.permission.CAMERA) + ContextCompat.checkSelfPermission(AccountSettingActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
CropImage.startPickImageActivity(this);
}
}else {
CropImage.startPickImageActivity(this);
}
}
#Override
#SuppressLint("NewApi")
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// handle result of pick image chooser
if (requestCode == CropImage.PICK_IMAGE_CHOOSER_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri imageUri = CropImage.getPickImageResultUri(this, data);
startCropImageActivity(imageUri);
}
// handle result of CropImageActivity
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
fileUri = result.getUri();
userImage.setImageURI(result.getUri());
Toast.makeText(this, "Cropping successful, Sample: " + result.getSampleSize(), Toast.LENGTH_LONG).show();
} else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
Toast.makeText(this, "Cropping failed: " + result.getError(), Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED ) {
CropImage.startPickImageActivity(this);
} else {
Toast.makeText(this, "Cancelling, required permissions are not granted", Toast.LENGTH_LONG).show();
}
}
/**
* Start crop image activity for the given image.
*/
private void startCropImageActivity(Uri imageUri) {
CropImage.activity(imageUri)
.setGuidelines(CropImageView.Guidelines.ON)
.setMultiTouchEnabled(true)
.start(this);
}
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
in manifest please add these permissions and ask for run time permissions also ,this may solve your problem ,Your coding is correct those works for me perfectly after adding permission.
Please go trough the following code
try {
if (imageUri != null) {
photo = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(imageUri));
} else {
photo = (Bitmap) data.getExtras().get("data");
}
Uri tempUri = CommonData.getImageUri(getContext(), photo);
uri = tempUri.toString();
String path = CommonData.convertImageUriToFile(tempUri, getActivity());
// new PreprocessImagesTask().execute(path);
showLoader();
new ProcessingImage(this).execute(path);
} catch (Exception e) {
e.printStackTrace();
}
public static Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
public static String convertImageUriToFile(Uri imageUri, Activity activity) {
String imgPath = "";
String Path;
try {
Cursor cursor = null;
int imageID = 0;
try {
/* ********** Which columns values want to get ****** */
String[] proj = {
MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID,
MediaStore.Images.Thumbnails._ID,
MediaStore.Images.ImageColumns.ORIENTATION
};
cursor = activity.getContentResolver().query(
imageUri, // Get data for specific image URI
proj, // Which columns to return
null, // WHERE clause; which rows to return (all rows)
null, // WHERE clause selection arguments (none)
null // Order-by clause (ascending by name)
);
int file_ColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
int size = cursor.getCount();
/* ****** If size is 0, there are no images on the SD Card. **** */
if (size == 0) {
// imageDetails.setText("No Image");
} else {
int thumbID = 0;
if (cursor.moveToFirst()) {
Path = cursor.getString(file_ColumnIndex);
//String orientation = cursor.getString(orientation_ColumnIndex);
String CapturedImageDetails = " CapturedImageDetails : \n\n"
+ " ImageID :" + imageID + "\n"
+ " ThumbID :" + thumbID + "\n"
+ " Path :" + Path + "\n";
showLog("CapturedImageDetails", CapturedImageDetails);
imgPath = Path;
// Show Captured Image detail on view
// imageDetails.setText(CapturedImageDetails);
}
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return "" + imgPath;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return "";
}
}
Give a try!
private static final int REQUEST_IMAGE = 100;
private static final String TAG = "MainActivity";
TextView imgPath;
ImageView picture;
File destination;
String imagePath;
//onCreate
private void cameraIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(destination));
startActivityForResult(intent, REQUEST_IMAGE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if( requestCode == REQUEST_IMAGE && resultCode == Activity.RESULT_OK ){
try {
FileInputStream in = new FileInputStream(destination);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 10;
imagePath = destination.getAbsolutePath();//get your path
imgPath.setText(imagePath);
Bitmap bmp = BitmapFactory.decodeStream(in, null, options);
picture.setImageBitmap(bmp);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
else{
imgPath.setText("Request cancelled");
}
}
I am trying number of tutorials and sample codes for take an image from gallery or camera then crop the image and upload it to server. I was implemented the code for that in that code am facing few problems the are.
In pre Lollipop devices when I crop the image using photos app the image is not getting reflected in image view but it's showing the message as image saved..
In nexus phone both camera and gallery is not working.
5.0 versions in few devices when I crop the image am getting the image like shown below
below is my code snippet.`
public void getPhoto() {
final String[] items = new String[] { "Take from camera",
"Select from gallery" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.select_dialog_item, items);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Select Image");
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) { // pick from
// camera
if (item == 0) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(
"android.intent.extras.CAMERA_FACING",
android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
mImageCaptureUri = Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), "tmp_avatar_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
mImageCaptureUri);
try {
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
} else { // pick from file
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
// startActivityForResult(intent, SELECT_PICTURE);
startActivityForResult(intent, PICK_FROM_FILE);
}
}
});
final AlertDialog dialog = builder.create();
dialog.show();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK)
return;
switch (requestCode) {
case PICK_FROM_CAMERA:
doCrop();
break;
case PICK_FROM_FILE:
mImageCaptureUri = data.getData();
doCrop();
break;
case CROP_FROM_CAMERA:
Bundle extras = data.getExtras();
if (extras != null) {
photo = extras.getParcelable("data");
profile_image = encodeTobase64(photo);
saveType = "photo";
try {
JSONObject obj = new JSONObject();
obj.put("user_id", user_id);
obj.put("mode", saveType);
obj.put("photo", profile_image);
obj.put("is_profile", 1);
saveResponse(obj);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
File f = new File(mImageCaptureUri.getPath());
if (f.exists())
f.delete();
break;
}
}
private void doCrop() {
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getActivity().getPackageManager()
.queryIntentActivities(intent, 0);
int size = list.size();
if (size == 0) {
Toast.makeText(getActivity(), "Can not find image crop app",
Toast.LENGTH_SHORT).show();
return;
} else {
intent.setData(mImageCaptureUri);
intent.putExtra("crop", "true");
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("circleCrop", new String(""));
intent.putExtra("return-data", true);
if (size == 1) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent(new ComponentName(res.activityInfo.packageName,
res.activityInfo.name));
startActivityForResult(i, CROP_FROM_CAMERA);
} else {
for (ResolveInfo res : list) {
final CropOption co = new CropOption();
co.title = getActivity().getPackageManager()
.getApplicationLabel(
res.activityInfo.applicationInfo);
co.icon = getActivity().getPackageManager()
.getApplicationIcon(
res.activityInfo.applicationInfo);
co.appIntent = new Intent(intent);
co.appIntent
.setComponent(new ComponentName(
res.activityInfo.packageName,
res.activityInfo.name));
cropOptions.add(co);
}
CropOptionAdapter adapter = new CropOptionAdapter(
getActivity(), cropOptions);
AlertDialog.Builder builder = new AlertDialog.Builder(
getActivity());
builder.setTitle("Choose Crop App");
builder.setAdapter(adapter,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
startActivityForResult(
cropOptions.get(item).appIntent,
CROP_FROM_CAMERA);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
if (mImageCaptureUri != null) {
getActivity().getContentResolver().delete(
mImageCaptureUri, null, null);
mImageCaptureUri = null;
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
}
public String encodeTobase64(Bitmap image) {
Bitmap immagex = image;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
immagex.compress(Bitmap.CompressFormat.JPEG, 100, baos);
image_Array = baos.toByteArray();
String imageEncoded = Base64
.encodeToString(image_Array, Base64.DEFAULT);
return imageEncoded;
}
`
comment below before duplicating this question because i was checked a lot but didn't find any solution for this, please let me know if you need more information.
I have the same problem last week and I finally solve it, it's a little bit different in my case I get an image in Base64 from a server then crop it
here's the code
byte[] decodedString = Base64.decode(imageJson, Base64.DEFAULT);
Bitmap tmp = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
bitmapDecoded = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int h = metrics.heightPixels;
int w = metrics.widthPixels;
Bitmap resized = Bitmap.createScaledBitmap(tmp, tmp.getWidth(), (int) (tmp.getHeight()*1.6), true);
imageView.setImageBitmap(canvas.getCircleBitmap(resized, w,h));
imageJson is the image in Base64 it's a String I transform it in a Bitmap, after I get the size of the screen, the Bitmap resized is here for have a square image, cause I have a 16/9 image this is maybe not usefull for you, and finally I show the bitmap in an imageView and crop it with the canvas method getCircleBitmap
here is the method
public Bitmap getCircleBitmap(Bitmap bitmap,int width, int height) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect((int)(bitmap.getWidth()*0.054), (int) (height*0.005), (int) (bitmap.getWidth()*0.945), (bitmap.getHeight()));
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
You can change the value of the rect for fit it for your usage
I declare this method in a canvas class who extends View, really hope this help you too and sorry for my english
i also facing this issue..Now its working fine because i m using library
**compile 'com.soundcloud.android:android-crop:1.0.1#aar'**
public Uri mImageCaptureUri=null;
Pick image from gallery
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, PICK_FROM_FILE);
this is add to onActivityResult method
//call this line after crop it
if(requestCode == Crop.REQUEST_CROP){
handleCrop(resultCode, data);
}
case PICK_FROM_FILE:
mImageCaptureUri = data.getData();
beginCrop(mImageCaptureUri);
break;
private void beginCrop(Uri source) {
Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped"));
Crop.of(source, destination).asSquare().start(this);
}
private void handleCrop(int resultCode, Intent result) {
if (resultCode == RESULT_OK) {
// mImage.setImageURI(Crop.getOutput(result));
Picasso.with(SettingsActivity.this).load(Crop.getOutput(result)).transform(new RoundTransform()).into(mImage);
mImageCaptureUri=Crop.getOutput(result);
getImageUri(mImageCaptureUri); //this method uri stored to sdcard
} else if (resultCode == Crop.RESULT_ERROR) {
Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
}
}
If user requests to take a picture:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(BaseActivity.this.getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = ImageVideoUtil.createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
imagePath = Uri.fromFile(photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imagePath);
startActivityForResult(takePictureIntent, ApplicationConstants.REQUEST_CAMERA);
}
}
If user requests to pick from camera you can use:
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, ApplicationConstants.REQUEST_GALLERY);
dialog.dismiss();
And on your activity result you can get uri and use it:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
BaseFragment fragment = (BaseFragment) getSupportFragmentManager().findFragmentById(R.id.fl_main);
if (resultCode == RESULT_OK) {
Bitmap bitmap = null;
switch (requestCode) {
case ApplicationConstants.REQUEST_CAMERA:
if (imagePath != null && fragment instanceof PhotoView) {
bitmap = Tools.fromGallery(this, imagePath);
if (bitmap != null) {
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
((PhotoView) fragment).onPhotoSet(bitmap);
}
}
break;
case ApplicationConstants.REQUEST_GALLERY:
Uri uri = data.getData();
imagePath = uri;
bitmap = Tools.fromGallery(this, uri);
if (bitmap != null && fragment instanceof PhotoView) {
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
((PhotoView) fragment).onPhotoSet(bitmap);
}
break;
case ApplicationConstants.REQUEST_VIDEO:
if (fragment instanceof VideoView) {
((VideoView) fragment).onVideoSelected(videoPath);
}
break;
}
}
}
Here the ImageVideoUtil Class which'll help you to crop, scale, save and read image video operations.
public class ImageVideoUtil {
public static void startCameraIntent(Activity activity) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(activity.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
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
activity.startActivityForResult(takePictureIntent, ApplicationConstants.REQUEST_CAMERA);
}
}
}
public static File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "SnapSense" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, /* prefix */
ApplicationConstants.DEFAULT_IMGAE_SUFFIX, /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
return image;
}
public static File createVideoFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "SnapSense" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
File video = File.createTempFile(imageFileName, /* prefix */
ApplicationConstants.DEFAULT_VIDEO_SUFFIX, /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
return video;
}
public static Bitmap decodeBitmap(Bitmap bmp) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 50, out);
return BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
} catch (Exception ex) {
ex.printStackTrace();
}
return bmp;
}
}
Finally here are some other static methods to help you:
public static Bitmap fromGallery(Context context, final Uri selectedImageUri) {
try {
Bitmap bm = MediaStore.Images.Media.getBitmap(context.getContentResolver(), selectedImageUri);
ExifInterface exif = new ExifInterface(selectedImageUri.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
angle = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
angle = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
angle = 270;
break;
default:
angle = 0;
break;
}
Matrix mat = new Matrix();
if (angle == 0 && bm.getWidth() > bm.getHeight())
mat.postRotate(90);
else
mat.postRotate(angle);
return Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), mat, true);
} catch (IOException e) {
e.printStackTrace();
} catch (OutOfMemoryError oom) {
oom.printStackTrace();
}
return null;
}
public static String getRealPathFromURI(Activity activity, Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = activity.managedQuery(contentUri, proj, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
I hope my code helps you. Good Luck.
I was facing same issue in Nexus. I used Android Image Cropper which is very lightweight and flexible.
compile 'com.theartofdev.edmodo:android-image-cropper:2.2.+'
Each version has there own way to get path:
Try this method will work for every version, IT WORKED FOR ME:
public static String getRealPathFromURI(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/"
+ split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection,
selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
Is there any solution to use AQuery library of android for JSON parsing? Do give the code for it. Any solution that makes use of AQuery and no need to create JSONObject instance and to get object from there. Any direct solution for it, please do answer it with a sample of code.
-- Complete code for capturing image ,saving to SD card , pick from gallery,compress,rotate image,etc.. 200% working.
public class A extends AppCompatActivity implements View.OnClickListener, AsyncTaskCompleteListener {
private static final String IMAGE_DIRECTORY = "/idyme";
private static int MAX_IMAGE_DIMENSION = 200;
private final String TAG = "RegisterFragment";
private Button btnVerify, btnUploadImage;
private String ImgPath = null, filePath = null,
profileImageFilePath, profileImageData = null,imageVideoType = "", imageVideoPath = "";
private ImageView ivImage;
private AQuery aQuery;
private Uri uri = null;
private ImageOptions imageOptions;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vip_registration);
ivImage = (ImageView) findViewById(R.id.ivProfile);
aQuery = new AQuery(this);
imageOptions = new ImageOptions();
imageOptions.memCache = true;
imageOptions.fileCache = true;
imageOptions.fallback = R.drawable.userimage;
}
#Override
public void onClick(View v) {
// onRegisterButtonClick();
switch (v.getId()) {
case R.id.btnUploadImage:
showPictureDialog();
}
}
private void showPictureDialog() {
AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
pictureDialog.setTitle(getResources().getString(
R.string.dialog_chhose_photo));
String[] pictureDialogItems = {
getResources().getString(R.string.dialog_from_gallery),
getResources().getString(R.string.dialog_from_camera)};
pictureDialog.setItems(pictureDialogItems,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
choosePhotoFromGallary();
break;
case 1:
takePhotoFromCamera();
break;
}
}
});
pictureDialog.show();
}
private void choosePhotoFromGallary() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, Constants.CHOOSE_PHOTO);
}
private void takePhotoFromCamera() {
Calendar cal = Calendar.getInstance();
File file = new File(Environment.getExternalStorageDirectory(),
(cal.getTimeInMillis() + ".jpg"));
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
} else {
file.delete();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
// uri = Uri.fromFile(file);
uri = getOutputMediaFileUri();
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(cameraIntent, Constants.TAKE_PHOTO);
}
public Uri getOutputMediaFileUri() {
return Uri.fromFile(getOutputMediaFile());
}
private String getRealPathFromURI(Uri contentURI) {
String result;
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = this.getContentResolver().query(contentURI, proj, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file
// path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == this.RESULT_CANCELED) {
return;
}
if (requestCode == Constants.CHOOSE_PHOTO) {
if (data != null) {
Uri contentURI = data.getData();
profileImageData = getRealPathFromURI(contentURI);
// new AQuery(getApplicationContext()).id(ivMeme).image(
// profileImageData, imageOptions);
try {
String path = saveImage(scaleImage(this, contentURI));
imageVideoPath = path;
aQuery.id(R.id.ivProfile).image(
imageVideoPath, imageOptions);
} catch (IOException e) {
e.printStackTrace();
Utils.showToast("Failed", this);
}
}
} else if (requestCode == Constants.TAKE_PHOTO) {
// old
if (uri != null) {
profileImageFilePath = uri.getPath();
if (profileImageFilePath != null
&& profileImageFilePath.length() > 0) {
File myFile = new File(profileImageFilePath);
String path = saveImage(BitmapFactory
.decodeFile(profileImageFilePath));
imageVideoPath = path;
aQuery.id(R.id.ivProfile).image(
imageVideoPath, imageOptions);
} else {
Utils.showToast("Failed", this);
}
} else {
Utils.showToast("Failed", this);
}
}
}
public String saveImage(Bitmap myBitmap) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File wallpaperDirectory = new File(
Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
// have the object build the directory structure, if needed.
if (!wallpaperDirectory.exists()) {
wallpaperDirectory.mkdirs();
}
try {
File f = new File(wallpaperDirectory, Calendar.getInstance()
.getTimeInMillis() + ".jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
MediaScannerConnection.scanFile(this,
new String[]{f.getPath()},
new String[]{"image/jpeg"}, null);
fo.close();
AppLog.Log("TAG", "File Saved::-> " + f.getAbsolutePath());
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
private static File getOutputMediaFile() {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY, "Oops! Failed create " + IMAGE_DIRECTORY
+ " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
return mediaFile;
}
public static Bitmap scaleImage(Context context, Uri photoUri)
throws IOException {
InputStream is = context.getContentResolver().openInputStream(photoUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();
int rotatedWidth, rotatedHeight;
int orientation = getOrientation(context, photoUri);
if (orientation == 90 || orientation == 270) {
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
if (rotatedWidth > MAX_IMAGE_DIMENSION
|| rotatedHeight > MAX_IMAGE_DIMENSION) {
float widthRatio = ((float) rotatedWidth)
/ ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight)
/ ((float) MAX_IMAGE_DIMENSION);
float maxRatio = Math.max(widthRatio, heightRatio);
// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
srcBitmap = BitmapFactory.decodeStream(is);
}
is.close();
/*
* if the orientation is not 0 (or -1, which means we don't know), we
* have to do a rotation.
*/
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0,
srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true);
}
String type = context.getContentResolver().getType(photoUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (type.equals("image/png")) {
srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
} else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
byte[] bMapArray = baos.toByteArray();
baos.close();
return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);
}
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[]{MediaStore.Images.ImageColumns.ORIENTATION},
null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
}
--After getting images send it to server , like this :
map.put(Constants.Params.PROFILEPICTURE, imageVideoPath);
// Log.d("image view", profileImageFilePath);
new MultiPartRequester(this, map,
AndyConstants.ServiceCode.VIP_USER_REGISTRATION, this);
-- Permission required :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
-- dependencies :
compile files('libs/android-query-full.0.26.7.jar')
-- this is full code for json parsing with AQuery library of android