Why is my camera working? I thought Nugat should have solved this security problem?

All that I see says that you need to add the <provider> section to AndroidManifest, and you need to access the XML resource file, which indicates the external path to the file you want for the image.

I do none of them, but the code fragment that I found works even on Nougat and newer.

I wonder why. I can't figure out what really makes it 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 like to trim it a bit for you, but I want to make sure that I don't accidentally cut something that you guys need to see. I can not understand.

 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 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); } } } } 
+5
source share

Source: https://habr.com/ru/post/1272296/


All Articles