I give all files access by this method :
if (!hasPermissionToManageFiles(myContext)){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
try {
Intent intentFiles = new Intent();
intentFiles.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
Uri uriFiles = Uri.fromParts("package", myContext.getPackageName(), null);
intentFiles.setData(uriFiles);
myContext.startActivity(intentFiles);
}
catch (Exception e){
Intent intentFiles = new Intent();
intentFiles.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
myContext.startActivity(intentFiles);
}
}
}
This line in my manifest :
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
I tried to create method to verify this kind of permission but it's not working. I don't have any error, when my app has the permission to access the intent still appears.
here is my method :
public static boolean hasPermissionToManageFiles(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return ActivityCompat.checkSelfPermission(context, Manifest.permission.MANAGE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}
return true;
}
According to the docs you should use Environment.isExternalStorageManager method instead of the checkSelfPermission.
Related
I'm trying to disable Bluetooth on the button click but it not work
hear, What I Do
if (SDK_INT >= Build.VERSION_CODES.S) {
if (checkPermission(Manifest.permission.BLUETOOTH_CONNECT) && checkPermission(Manifest.permission.BLUETOOTH_SCAN)) {
BluetoothAdapter adapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
if (adapter != null) {
if (adapter.getState() == BluetoothAdapter.STATE_ON) {
Log.e("BT", "disable");
adapter.disable();
} else if (adapter.getState() == BluetoothAdapter.STATE_OFF) {
if (!adapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
Log.e("BT", "enable");
} else {
Log.e("BT", "Else");
}
} else {
Toast.makeText(UltimateHomeLauncherActivity.this, "Bluetooth is not supported on your hardware", Toast.LENGTH_SHORT).show();
}
} else {
List<String> deniedPermissions = new ArrayList<>();
deniedPermissions.add(Manifest.permission.BLUETOOTH_CONNECT);
deniedPermissions.add(Manifest.permission.BLUETOOTH_SCAN);
requestRuntimePermissions(1011, deniedPermissions.toArray(new String[0]));
}
}
I'm add Bluetooth permission in Manifest also.
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
android.permission.BLUETOOTH_CONNECT is a runtime permission and requires the consent of the user.
However, with next API level 33 enable()/disable() of the BluetoothAdapter will be deprecated and are not longer allowed. Therefore, it is probably best for such a function to navigate the user to the Bluetooth system dialog and ask him to turn the function on or off there.
but how to validate if the app currently has the 'All Files Access' permission or not. i use this method to ask permission.
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s",this.getPackageName())));
startActivityForResult(intent, 2296);
Please help me to fix this :(
declare this permission in your manifest.xml:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
for asking MANAGE_EXTERNAL_STORAGE:
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, 2296);
}
get your result in onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2296) {
if (SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
// perform action when allow permission success
} else {
Toast.makeText(this, "Allow permission for storage access!", Toast.LENGTH_SHORT).show();
}
}
}
}
so, basically you can check permission is granted or not in Android11 like this;
if (SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
// Permission Granted
}
}
create new dummy 0-bytes file in root of internal memory and then remove it. if both operations success then you have access. when you won't have access then your code will throw Exception (on create-file step), which you can try{ }catch(Exception e) (preventing app crash)
path for internal/external/shared can be obtained from Environment class, I would try at first getExternalStorageDirectory
I do it that way:
public static boolean hasAllFilesAccess(Context context) {
AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
try {
ApplicationInfo app = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
return appOpsManager.unsafeCheckOpNoThrow("android:manage_external_storage",app.uid, context.getPackageName()) == AppOpsManager.MODE_ALLOWED;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
catch (NoSuchMethodError e)
{
return true;
}
return false;
}
Seems there is a better way now though:
Environment.isExternalStorageManager()
I am using the following code to check if camera & storage permissions have been granted when user clicks on input-file field on my website in android webview:
public boolean file_permission(){
if(Build.VERSION.SDK_INT >=23 && (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 1);
return false;
}else{
return true;
}
}
class MyWebChromeClient extends WebChromeClient {
// Handling onshow file chooser
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
if(file_permission() && Build.VERSION.SDK_INT >= 21) {
file_path = filePathCallback;
Intent takePictureIntent = null;
takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = create_image();
takePictureIntent.putExtra("PhotoPath", cam_file_data);
} catch (IOException ex) {
Log.e(TAG, "Image file creation failed", ex);
}
if (photoFile != null) {
cam_file_data = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} else {
cam_file_data = null;
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType(file_type);
Intent[] intentArray;
intentArray = new Intent[]{takePictureIntent};
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Select Photo for yourPrint");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, file_req_code);
return true;
} else {
return false;
}
}
}
When the permission is checked via file_permission(), the accept permission dialog appears. But once the user accepts the permission, the input-file field needs to be clicked again by the user to show the file chooser. I want the input-field that originally triggered the onShowFileChooser to be clicked again automatically after user accepts the permissions, so that file chooser opens automatically.
I have tried using onRequestPermissionsResult with javascript to trigger click on input field after permissions acceptance using this code javascript:jQuery('.file-input-field').trigger('click'), However, I do not want to use this way as chrome blocks programmatic clicks on input fields with type file for security purposes.
How to accomplish this?
you must reset this variable like this in java/kotlin :
filePathCallback.onReceiveValue(null)
filePathCallback = null
if filePathCallback not null onShowFileChooser will not triggered
Basically what I'm trying to do is create a simple app that uses the default camera app to take a picture, then I want to display that image in a new activity within an ImageView, but everything I've tried has resulted in
java.io.FileNotFoundException: /storage/emulated/0/imageToProcess.jpg: open failed: ENOENT (No such file or directory)
I've included the correct permissions (maybe even too many) in the manifest:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and I'm also manually requesting permissions if need be in the main activity:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
}
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
}
so I don't think the issue is with read/write permissions.
In my main activity's xml file, I've created a button with an onClick listener that calls the following method:
public void openCamera(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "imageToProcess.jpg");
imgUri = Uri.fromFile(f);
intent.putExtra("imgUri", imgUri.toString());
startActivityForResult(intent, TAKE_PICTURE);
}
Here's the onActivityResult() method I defined to create a new intent and pass the uri to the new activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if(requestCode == TAKE_PICTURE && resultCode == Activity.RESULT_OK) {
Intent camResult = new Intent(this, ShowCameraResult.class);
camResult.putExtra("imgUri", imgUri.toString());
startActivity(camResult);
}
}
NOTE: imgUri and TAKE_PICTURE are defined at the top of the class as protected static final int TAKE_PICTURE = 1; and private Uri imgUri;
Lastly, here is my ShowCameraResult activity
public class ShowCameraResult extends AppCompatActivity {
private Bitmap mImageBitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_camera_result);
ImageView imageView = (ImageView)findViewById(R.id.imageView);
String filePath = getIntent().getStringExtra("imgUri");
Log.d("ShowCameraResult", "directory: " + filePath);
try {
mImageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(filePath));
imageView.setImageBitmap(mImageBitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
The Log.d method call above returns
ShowCameraResult: directory: file:///storage/emulated/0/imageToProcess.jpg
This leads me to believe that the image result from the camera isn't actually being saved into my imageToProcess.jpg file, but I could be very wrong as this is the first real android project I've worked on.
So my question is: Where did I go wrong?
Any help is greatly appreciated, thank you!
ITs returning a file, not a content resolver uri. Just decode the file with BitmapFactory.
I have problem with permissions. What should I do to stop my app from crashing?
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1 && resultCode == RESULT_OK && data != null){
Uri selectedImage = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
ImageView imageView = (ImageView)findViewById(R.id.imageView);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I just added this in my OnCreate method
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 225);
And it seems to work, is there any better solution?
If putting in your onCreate() works I would check whether you put it in the manifest in the correct place because that has caused me issues in the past.
Make sure <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> is after the first manifest closing tag and before the first <Application ...
For example:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.mypackagename">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application...
try this :
//check permission is granted or no
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, RESULT_LOAD_IMG);
}
else
{
//your code
}
If your target build version is API 23 or higher, just check that the permission is granted or not.
Go to Settings -> Apps and then tap on your app. In Permissions option enable the Storage permission. But it is not the permanent solution.
Well i do something like u want. I give u simply code how to do this :)
Here i checking permission(i call this method in fragment, make this in activity)
#TargetApi(23)
public void checkStoragePermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
if (settingsDrawerFragment != null) {
settingsDrawerFragment.onPermissionGranted();
}
return;
}
if (this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager
.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE_EXTERNAL_STORAGE);
return;
}
if (settingsDrawerFragment != null) {
settingsDrawerFragment.onPermissionGranted();
}
}
This check permission with auto message
Also i make onRequestPermissions
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[]
grantResults) {
switch (requestCode) {
case REQUEST_CODE_AUDIO_RECORD:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startBrowseActivity();
} else {
Utils.showToast(this, getString(R.string.audio_permission_denied));
}
break;
case REQUEST_CODE_EXTERNAL_STORAGE:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (settingsDrawerFragment != null) {
settingsDrawerFragment.onPermissionGranted();
}
} else {
if (settingsDrawerFragment != null) {
closeSettingsDrawer();
}
Utils.showToast(this, getString(R.string.storage_permission_denied));
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
Remember to make methods in activity. On fragment check it.
Finally i make something like this to check permissions in fragment
public void setHomeStreamSource(int position) {
if (position == STORAGE_CLOUD_CACHE) {
preferenceHelper.putInt(getString(R.string.preferences_usb_prefs), getString(R.string
.preferences_video_source), MainActivity.SOURCE_CLOUD);
closeDrawer();
Utils.showToast(activity, getString(R.string.source_selected));
} else if (position == STORAGE_USB) {
((MainActivity) activity).checkStoragePermission();
}
}
Hope this sample code help u well