Camera intent Android return null [duplicate] - java

This question already has answers here:
ACTION_IMAGE_CAPTURE returns imagefile as Extra instead of Data
(1 answer)
Why do I get null in data parmeter of onActivityResult
(1 answer)
Camera Intent Not Adding Extra
(1 answer)
Android "Taking Photos Simply" tutorial does not work for me [duplicate]
(1 answer)
Closed 2 months ago.
Start Intent Code :
Intent takePictureIntent = new Intent();
takePictureIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageUri);
takePictureIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
OnActivityResult Code :
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_IMAGE_CAPTURE && resultCode == UserVisitDetailActivity.RESULT_OK && data != null){
System.out.println("Masuk Camera");
Bitmap photo = (Bitmap) data.getExtras().get("data");
System.out.println(photo);
imageUri = getImageUri(getApplicationContext(), photo);
checkInHolder.setImageURI(imageUri);
}
}
Get Image URI Code :
public 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);
}
The code run smoothly but after several modification, it suddenly return null data.
Thank you for your help

I have an code that working on SDK 32 successfully.
first of you need to setup manifest.xml
<manifest
....>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<application
android:requestLegacyExternalStorage="true"
....>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
</application>
</manifest>
need to create provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
</paths>
setup java code.
// create global variable
private File photoFile = null;
//create methods...
private void chooseFromCamera(int requestCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
photoFile = createImageFile();
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, requestCode);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private File createImageFile() throws IOException {
long timeStamp = Calendar.getInstance().getTimeInMillis();
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return image;
}
start intent for capture image.
chooseFromCamera(REQUEST_IMAGE_CAPTURE);
get bitmap...
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK && data != null){
if (photoFile != null) {
bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
}
}
}

Related

Can not resolve com.android.camera.action.CROP in android 11 for first time app is installed

I am starting implicit intent for crop with string "com.android.camera.action.CROP" on android 11.
when application is first installed can not resolve its activity by this code.
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
//to check whether there is an cropping app present or not
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(
intent, MATCH_DEFAULT_ONLY);
it is not resolving for the first time and runs for second time it gets the activities that can handle the intent.
This code is a code that captures or imports an image from the camera app or gallery app and proceeds with cropping.
MainActivity.java
public class MainActivity extends AppCompatActivity {
public final String APP_TAG = "crop";
public String intermediateName = "1.jpg";
public String resultName = "2.jpg";
Uri intermediateProvider;
Uri resultProvider;
ActivityResultLauncher<Intent> cameraActivityResultLauncher;
ActivityResultLauncher<Intent> galleryActivityResultLauncher;
ActivityResultLauncher<Intent> cropActivityResultLauncher;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonCamera = findViewById(R.id.buttonCamera);
buttonCamera.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onLaunchCamera();
}
});
Button buttonGallery = findViewById(R.id.buttonGallery);
buttonGallery.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onPickPhoto();
}
});
cameraActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Bitmap takenImage = loadFromUri(intermediateProvider);
ImageView ivPreview = findViewById(R.id.originView);
ivPreview.setImageBitmap(getResizedBitmap(takenImage, 400));
onCropImage();
}
});
galleryActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
saveBitmapFileToIntermediate(result.getData().getData());
Bitmap selectedImage = loadFromUri(intermediateProvider);
ImageView ivPreview = findViewById(R.id.originView);
ivPreview.setImageBitmap(getResizedBitmap(selectedImage, 400));
onCropImage();
}
});
cropActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Bitmap cropImage = loadFromUri(resultProvider);
ImageView ivPreview = findViewById(R.id.resultView);
ivPreview.setImageBitmap(getResizedBitmap(cropImage, 400));
}
});
}
public void onLaunchCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photoFile = getPhotoFileUri(intermediateName);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
intermediateProvider = FileProvider.getUriForFile(MainActivity.this, "com.photostream.crop.fileprovider", photoFile);
else
intermediateProvider = Uri.fromFile(photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, intermediateProvider);
if (intent.resolveActivity(getPackageManager()) != null) {
cameraActivityResultLauncher.launch(intent);
}
}
// Trigger gallery selection for a photo
public void onPickPhoto() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
if (intent.resolveActivity(getPackageManager()) != null) {
galleryActivityResultLauncher.launch(intent);
}
}
private void onCropImage() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
grantUriPermission("com.android.camera", intermediateProvider, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(intermediateProvider, "image/*");
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, 0);
int size = 0;
if(list != null) {
grantUriPermission(list.get(0).activityInfo.packageName, intermediateProvider, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
size = list.size();
}
if (size == 0) {
Toast.makeText(this, "Error, wasn't taken image!", Toast.LENGTH_SHORT).show();
} else {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.putExtra("crop", "true");
intent.putExtra("scale", true);
File photoFile = getPhotoFileUri(resultName);
// wrap File object into a content provider
// required for API >= 24
// See https://guides.codepath.com/android/Sharing-Content-with-Intents#sharing-files-with-api-24-or-higher
resultProvider = FileProvider.getUriForFile(MainActivity.this, "com.photostream.crop.fileprovider", photoFile);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, resultProvider);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
Intent cropIntent = new Intent(intent);
ResolveInfo res = list.get(0);
cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
grantUriPermission(res.activityInfo.packageName, resultProvider, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
cropIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
cropActivityResultLauncher.launch(cropIntent);
}
} else {
File photoFile = getPhotoFileUri(resultName);
resultProvider = Uri.fromFile(photoFile);
Intent intentCrop = new Intent("com.android.camera.action.CROP");
intentCrop.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intentCrop.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intentCrop.setDataAndType(intermediateProvider, "image/*");
intentCrop.putExtra("crop", "true");
intentCrop.putExtra("scale", true);
intentCrop.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intentCrop.putExtra("noFaceDetection", true);
intentCrop.putExtra("return-data", false);
intentCrop.putExtra(MediaStore.EXTRA_OUTPUT, resultProvider);
cropActivityResultLauncher.launch(intentCrop);
}
}
// Returns the File for a photo stored on disk given the fileName
public File getPhotoFileUri(String fileName) {
File mediaStorageDir = new File(getExternalFilesDir(""), APP_TAG);
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()){
Log.d(APP_TAG, "failed to create directory");
}
File file = new File(mediaStorageDir.getPath() + File.separator + fileName);
return file;
}
public Bitmap loadFromUri(Uri photoUri) {
Bitmap image = null;
try {
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1){
// on newer versions of Android, use the new decodeBitmap method
ImageDecoder.Source source = ImageDecoder.createSource(this.getContentResolver(), photoUri);
image = ImageDecoder.decodeBitmap(source);
} else {
// support older versions of Android by using getBitmap
image = MediaStore.Images.Media.getBitmap(this.getContentResolver(), photoUri);
}
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
private void saveBitmapFileToIntermediate(Uri sourceUri) {
try {
Bitmap bitmap = loadFromUri(sourceUri);
File imageFile = getPhotoFileUri(intermediateName);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
intermediateProvider = FileProvider.getUriForFile(MainActivity.this, "com.photostream.crop.fileprovider", imageFile);
else
intermediateProvider = Uri.fromFile(imageFile);
OutputStream out = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
float bitmapRatio = (float)width / (float) height;
if (bitmapRatio > 1) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.photostream.crop">
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
<intent>
<action android:name="com.android.camera.action.CROP" />
</intent>
<intent>
<action android:name="android.intent.action.PICK" />
<data android:mimeType="vnd.android.cursor.dir/image" />
</intent>
</queries>
<application
android:allowBackup="true"
android:largeHeap="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Test">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.photostream.crop.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/fileprovider" />
</provider>
</application>
</manifest>
It's working well on Android 11.
You can also refer follow project on Github.
https://github.com/bigant02/image-crop
I assume you target Android 11 (API 30), which requires you to specify all intents to external apps in a queries node inside your AndroidManifest.xml like follows:
<queries>
...
<intent>
<action android:name="com.android.camera.action.CROP" />
</intent>
...
</queries>
Read more here and here. Also there's a medium post on the matter here.
NOTE:
The intent com.android.camera.action.CROP is based on the camera app from AOSP which might be missing on some devices, please refer to Commonsware's old blogpost about it: https://commonsware.com/blog/2013/01/23/no-android-does-not-have-crop-intent.html
In my case, I'm using the following <queries> config in AndroidManifest.xml and it works.
<manifest>
// ...
<queries>
<intent>
<action android:name="com.android.camera.action.CROP" />
<data android:scheme="content"
android:mimeType="image/*"/>
</intent>
</queries>
</manifest>
And the resolveActivity:
val intent = Intent("com.android.camera.action.CROP").apply {
type = "image/*"
data = photoUri
}
if (intent.resolveActivity(context.packageManager) != null) {
// grant uri permission here
}
After some test, I found the key is that the android:mimeType in queries must align with the type which is set in the Intent.

How to convert a string to a URI without throwing exceptions

I had to convert a Uri to a string so that I could serialize that Uri.
Intent openFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
openFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
openFileIntent.setType("audio/mpeg");
startActivityForResult(openFileIntent, PICK_MP3_FILE);
...then on activity result...
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_MP3_FILE)
{
if (resultCode == RESULT_OK)
{
try
{
if (data != null)
{
Uri mp3AudioFile;
if ((mp3AudioFile = data.getData()) != null)
{
myObject.setMp3Path(mp3AudioFile.getPath());
myObject.Save();
}
}
} catch (Exception e)
{
e.printStackTrace();
}
}
}
}
I closed the app and opened again. When I try to open that Uri with:
Uri uri = Uri.parse(myObject.getMp3Path();
I get an error:
java.lang.SecurityException: Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2Faudio.mp3 from pid=601, uid=10107 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
My Manifest has the following permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
We need to provide persistent Uri permission.
JAVA
Intent openFileIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
openFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
openFileIntent.setType("audio/mpeg");
startActivityForResult(openFileIntent, PICK_MP3_FILE);
Also, a note worth mentioning is persistent permission is available only to Intent.ACTION_OPEN_DOCUMENT and NOT Intent.ACTION_GET_CONTENT whereas the latter one is like a one-time thing.
To do that I used getPath().
You should use toString() instead.
String scheme = uri.toString();
Uri uri = Uri.parse(scheme);
The permission denial issue needs to be dealt with the first time you receive a URI.
private val pickImage = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
// you will get result here in result.data
val uri = result.data?.data!!
requireActivity().contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
// Do something else with the URI. E.g, save the URI as a string in the database
}
}

Android exception permission denied even after granting permission?

What am I doing wrong?
I have tried googlign the problem, but people mostly say it is an issue with android Q, but I don't think my problem is that.
AndroidManifest.xml:
<manifest ...>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
Java:
void takePhoto(){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA},2);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null)
{
File photoFile = createPhotoFile();
if(photoFile != null){
pathToFile = photoFile.getAbsolutePath();
Uri photoURI = getUriForFile(this, this.getPackageName() + ".fileprovider", photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, REQUEST_CAMERA);
}
}
}
private File createPhotoFile() {
String name = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = null;
try{
image = File.createTempFile(name, ".jpg", storageDir);
} catch(IOException e){
Log.d("myLog", "Except: " + e.toString());
}
return image;
}

Need help in saving images using cropIwa

I added a destination file to save my images in app's created folder.
static final File imageRoot = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), appDirectoryName);
In cropIwa's documentation, it needs destinationUri
Here is what I have done:
cropIwaView.crop(new CropIwaSaveConfig.Builder(Uri.fromFile(imageRoot.getAbsoluteFile()))
.setCompressFormat(Bitmap.CompressFormat.PNG)
.setQuality(100) //Hint for lossy compression formats
.build());
ADDED #Khaled Lela
cropIwaView.crop(new CropIwaSaveConfig.Builder(getUriFromFile(this, new File(R.xml.file_paths + ".png")))
.setCompressFormat(Bitmap.CompressFormat.PNG)
.setQuality(100) //Hint for lossy compression formats
.build());
ADDED #Khaled Lela a saveCompleteListener of cropiwa.
cropIwaView.setCropSaveCompleteListener(new CropIwaView.CropSaveCompleteListener() {
#Override
public void onCroppedRegionSaved(Uri bitmapUri) {
addPicToGallery(CropProfilePicture.this, bitmapUri);
Toast.makeText(CropProfilePicture.this, "Done", Toast.LENGTH_SHORT).show();
finish();
}
});
Create temp file where the image should save
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile(context);
} catch (IOException ex) {
// Error occurred while creating the File
Timber.e("Can't create photoFile:%s",ex.getMessage());
}
private static File createImageFile(Context ctx) throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.US).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = ctx.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
return File.createTempFile(
imageFileName, /* prefix */
".png", /* suffix */
storageDir /* directory */
);
}
Generate Uri and use FileProvide when version LOLLIPOP or above
final Uri imageUri ;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP)
imageUri = Uri.fromFile(photoFile); // file://
else
imageUri = getUriFromFile(context,photoFile); // FileProvider
Saving image logic
cropIwaView.setCropSaveCompleteListener(bitmapUri -> {
addPicToGallery(context, bitmapUri); // sendBroadcast to gallery to scan new added images...
});
cropIwaView.crop(new CropIwaSaveConfig.Builder(imageUri)
.setCompressFormat(Bitmap.CompressFormat.PNG)
.setQuality(100) //Hint for lossy compression formats
.build());
Use FileProvider with android version LOLLIPOP and above
private static Uri getUriFromFile(Context context, File newFile) {
return FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", newFile);
}
Under app res add file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="my_images" path="Android/data/com.your_package_id/files/Pictures" />
</paths>
manifest.xml
<application
...// other attributes
>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.your_package_id.fileprovider"
android:readPermission="com.your_package_id.fileprovider.READ"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
</application>
add permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Update
Update image on gallery.
private static void addPicToGallery(Context context, Uri contentUri) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);
}

FileProvider failed to find configured root that contains... error

I have seen this question asked previously, but before you mark this question as redundant let me just say that I've been trying to figure this out for three hours and I'm just confused. My goal is to take a photo, set it to an imageview, and upload it to Firebase Storage. In order to get the full size photo, I believe I have to save it to a local file, because the FileProvider takes a reference to a file and that's where the full size photo goes. Is that correct so far? I cannot for the life of me get the FileProvider to accomplish this.
After many attempts, this is what I have:
// It all starts here
public void onClick(View v) {
Log.d("DebugMySocks", "Change photo button clicked");
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
photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getApplicationContext(),
getPackageName(),
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
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 = getExternalFilesDir(Environment.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();
return image;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mProfileImage.setImageBitmap(imageBitmap);
}
}
// in manifest file
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepaths" />
</provider>
// in /xml/filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="com.example.kevin.moresocksplease/files/Pictures" />
</paths>
and the error message is:
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example.kevin.moresocksplease/files/Pictures/JPEG_20171214_111337.jpg706457555.jpg
Replace:
<external-path name="my_images" path="com.example.kevin.moresocksplease/files/Pictures" />
with:
<external-files-path name="my_images" />

Categories

Resources