Is it necessary that requesting each dangerous permission it needs while the app is running Android 6.0 or higher?I have requested the following dangerous permissions,but there are only four dialogs.
The premissions
public static final String[] PERMISSIONS = new String[]{
android.Manifest.permission.CALL_PHONE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.READ_PHONE_STATE,
android.Manifest.permission.WRITE_SETTINGS,
android.Manifest.permission.GET_ACCOUNTS,
android.Manifest.permission.CAMERA
};
The dialogs
1.Allow the app to make and manage phone calls?
2.Allow the app to access photos,media,and files on your device?
3.Allow the app to access this device's location?
4.Allow the app to access your contacts?
I cant get the permissions such as android.Manifest.permission.READ_PHONE_STATE,
android.Manifest.permission.WRITE_SETTINGS,
android.Manifest.permission.GET_ACCOUNTS,
android.Manifest.permission.CAMERA,neither code nor system setting.
Special Permissions
There are a couple of permissions that don't behave like normal and
dangerous permissions. WRITE_SETTINGS is
particularly sensitive, so most apps should not use them. If an app
needs one of these permissions, it must declare the permission in the
manifest, and send an intent requesting the user's authorization. The
system responds to the intent by showing a detailed management screen
to the user.
Demo
public class MainActivity extends AppCompatActivity {
Context context;
TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
textView = (TextView) findViewById(R.id.foodName);
textView.setText(getResources().getText(R.string.txt_name));
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean result = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
result = Settings.System.canWrite(context);
Log.d("TAG", "Can Write Settings: " + result);
if (result) {
Toast.makeText(context, "Write allowed :-)", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, "Write not allowed :-(", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
startActivity(intent);
}
}
}
});
}
}
Related
I am trying to use the "new" way of requesting external storage write permission.
But the request is automatically denied and no window pops up asking the user for permission.
Virtual Device: Pixel 2 API 30
SDK 30
I did add the permissions into the manifest file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lab6">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE "/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
WRITE_EXTERNAL_STORAGE is a dangerous permission from my knowledge, so it has to be requested at runtime.
into my gradle dependencies I added these:
implementation 'androidx.activity:activity:1.2.0'
implementation 'androidx.fragment:fragment:1.3.0'
The activity looks like this:
public class MainActivity extends AppCompatActivity {
private ActivityResultLauncher<String> requestPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
Log.d("mihai", "Permission is granted now.");
} else {
Log.d("mihai", "Permission refused ");
}
});
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button downloadBtn = findViewById(R.id.downloadButton);
Button loadBtn = findViewById(R.id.loadButton);
downloadBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("mihai", "requesting permission");
if (ContextCompat.checkSelfPermission(
getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
Log.d("mihai", "permission already granted");
} else {
Log.d("mihai", "launching");
requestPermissionLauncher.launch(
Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
}
});
}
}
And these are the logs I get. As you can see, the request is denied. No question pops up on the phone.
2022-04-28 19:55:15.351 7499-7499/com.example.lab6 D/mihai: requesting permission
2022-04-28 19:55:15.353 7499-7499/com.example.lab6 D/mihai: launching
2022-04-28 19:55:15.592 7499-7499/com.example.lab6 D/mihai: Permission refused
Because you have denied the permission multiple times.
From the documentation:
Starting in Android 11 (API level 30), if the user taps Deny for a specific permission more than once during your app's lifetime of installation on a device, the user doesn't see the system permissions dialog if your app requests that permission again. The user's action implies "don't ask again." On previous versions, users would see the system permissions dialog each time your app requested a permission, unless the user had previously selected a "don't ask again" checkbox or option.
You will need to redirect the user to the app's setting detail to grant the permission manually.
To open an app specific app's detail setting screen:
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
I created an app which picks up images from images folder in emulator and displays selected image in my layout of application. When I converted my app to instant app, the same code that picks up images from image folder throws exception. I used runtime permissions READ_EXTERNAL_STORAGE.
My code:
private static final int PICK_IMAGE_REQUEST = 234;
Intent intent = new Intent();
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, PICK_IMAGE_REQUEST);
Exception thrown:
java.lang.SecurityException: Not allowed to start activity Intent {
act=android.intent.action.GET_CONTENT typ=*/* }
Code for runtime permissions:
private static final int REQUEST_WRITE_STORAGE = 112;
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public boolean checkPermission()
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
{
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
Toast.makeText(MainActivity.this,"Permission Denied...",Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_WRITE_STORAGE);
return true;
}
return false;
} else {
return true;
}
} else {
return true;
}
}
Can anyone help me in solving this issue?
Instant Apps are blocked from accessing some features that regular Android apps can access. The exception:
java.lang.SecurityException: Not allowed to start activity Intent...
Means you have found one such feature. In this case it is Intent.ACTION_GET_CONTENT which is not currently allowed. Support for additional features such as this may be introduced over time.
In addition, Instant Apps do not have access to read or write from external storage so requesting access to READ_EXTERNAL_STORAGE will also not work or throw an exception. See here for a list of permissions that are supported by Instant Apps.
I'm using this code to request SMS permission before running the method SendSMS(string 1, string 2);
but my app crashes before permission request takes place.
What's missing?
final private int REQUEST_CODE = 101;
private void SendCreditSMS() {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.SEND_SMS}, REQUEST_CODE);
} else {
SendSMS("181", "رصيد");
}
}
Try this,
final private int REQUEST_CODE = 101;
private void SendCreditSMS() {
if (Build.VERSION.SDK_INT >= 23) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{android.Manifest.permission.SEND_SMS}, REQUEST_CODE);
} else
{
SendSMS("181", "رصيد");
}
}
else{
SendSMS("181", "رصيد");
}
}
The problem may be due to the reason that you declared the activity in which you request permission(s) as with no history. To solve the problem remove
android:noHistory="true"
line from the associated activity's code block in AndroidManifest file. To have an activity with no history you can use other calls such as finishAndRemoveTask().
Try going to the application manager in your android device and select the app you are currently executing. Then check whether permissions are given by the device to use send_sms service in your device.
Apparently the MIUI OS has already implemented its own Permissions system before Marshmallow does. I'm currently testing a video recording app for the Xiaomi Mi 4i, which uses a MIUI based on API 21 [Android 5.0.2], and it needs the Record Audio permission which is not granted by default by MIUI's Permissions Manager.
So far the way I've managed to alter the permissions is by accessing the Permissions Manager window for the app on clicking the OK button in the AlertDialog:
isMIUI = MIUIUtils.isMIUI();
if(isMIUI)
{
AlertDialog.Builder adb = new AlertDialog.Builder(this);
adb.setMessage("If you intend to use the video recording feature, please enable the 'Record Audio' permission in the settings menu. You will be redirected there if you press OK.")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
intent.putExtra("extra_pkgname", "com.picmix.mobile");
startActivity(intent);
}
})
.setNegativeButton("CANCEL", null)
.create();
adb.show();
}
But this isn't good enough for me. I need to check if the Record Audio permission is already checked in the MIUI Permissions Manager in order to run this only once.
How do I check for the permissions granted or to be notified in the MIUI Permissions Manager programmatically?
private boolean resourceCanBeAccessed() {
boolean response = true;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
== PackageManager.PERMISSION_DENIED ) {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUDIO}, 1);
response = false;
}
}
return response;
}
You just need to call this method before accessing the resource. This method will return true if the permission is granted. It the permission is not granted then it will grant the permission
This question already has answers here:
Android permission doesn't work even if I have declared it
(11 answers)
Closed 6 years ago.
Why i get this message
if the i set the permission in the manifest file:
Thank you for any help.
You need request permission at runtime in android >= 6.0
https://developer.android.com/training/permissions/requesting.html
You have to grant permission in android version >=6.0 (Marshmallow and above).
For Android 6.0+, you have to request the permission at runtime as well as adding it to the manifest. So something like this added to your Activity onCreate();
List<String> permissions = new ArrayList<>();
permissions.add(Manifest.permission.READ_CONTACTS);
//...add any others you need to this arraylist
// Convert the List to an Array
String[] permissionsArray = permissions.toArray(new String[0]);
ActivityCompat.requestPermissions(getActivity(), permissionsArray, REQUEST_CODE);
//The REQUEST_CODE is just a integer that your callback method will check, set it to some number
Then override this method in your activity to check whether the request was granted or not
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Permission Granted, do your thing
} else {
//Permission denied, you can't do what you want to because user didn't give you permission
}
return;
}
}
See here for more info https://developer.android.com/training/permissions/requesting.html
Change your target sdk version to 22 in your app's build.gradle if you donot want to request the permission to the user at run time.
Else if you want to keep the target sdk version to 23 then you would need to request the permission from the user at run time as mentioned above by #wanpanman
Call this permission.
//Check permissions
public boolean reqPermission() {
if (!Permissions.checkPermission(this, Manifest.permission.READ_CONTACTS)) {
if (shouldShowRationale(Manifest.permission.READ_CONTACTS)) {
Snackbar.make(yourLayout, "Need to enable contact permission to use this feature. bla bla bla",
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.settings, new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
})
.show();
return true;
} else {
Permissions.grantPermission(this, PERMISSION_REQUEST_CODE);
return true;
}
} else {
return false;
}
}
#TargetApi(Build.VERSION_CODES.M)
public boolean shouldShowRationale(String permission) {
return shouldShowRequestPermissionRationale(permission);
}