Everything I'm seeing says that you need to add a <provider>
section into the AndroidManifest, and you need to refer to an XML resource file that says the external file path you want for the image.
I'm doing neither of those but the code snippet I found is working, even on Nougat and newer.
I'm wondering why. I can't figure out what is causing this to actually work.
Here is my Android manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.inthecheesefactory.lab.intent_fileprovider">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
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>
</application>
</manifest>
And here is the full MainActivity. I would love to trim it down quite a bit for you guys but I want to make sure I don't accidentally cut something out that you guys need to see. I can't figure it out.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final int REQUEST_TAKE_PHOTO = 1;
Button btnTakePhoto;
ImageView ivPreview;
String mCurrentPhotoPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initInstances();
}
private void initInstances() {
btnTakePhoto = (Button) findViewById(R.id.btnTakePhoto);
ivPreview = (ImageView) findViewById(R.id.ivPreview);
btnTakePhoto.setOnClickListener(this);
}
/////////////////////
// OnClickListener //
/////////////////////
@Override
public void onClick(View view) {
if (view == btnTakePhoto) {
MainActivityPermissionsDispatcher.startCameraWithCheck(this);
}
}
////////////
// Camera //
////////////
@NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
void startCamera() {
try {
dispatchTakePictureIntent();
} catch (IOException e) {
}
}
@OnShowRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)
void showRationaleForCamera(final PermissionRequest request) {
new AlertDialog.Builder(this)
.setMessage("Access to External Storage is required")
.setPositiveButton("Allow", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
request.proceed();
}
})
.setNegativeButton("Deny", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
request.cancel();
}
})
.show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
// Show the thumbnail on ImageView
Uri imageUri = Uri.parse(mCurrentPhotoPath);
File file = new File(imageUri.getPath());
try {
InputStream ims = new FileInputStream(file);
ivPreview.setImageBitmap(BitmapFactory.decodeStream(ims));
} catch (FileNotFoundException e) {
return;
}
// ScanFile so it will be appeared on Gallery
MediaScannerConnection.scanFile(MainActivity.this,
new String[]{imageUri.getPath()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
}
});
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
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 = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), "Camera");
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent() throws IOException {
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
return;
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = Uri.fromFile(createImageFile());
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
}