The code I have written should check the permissions in the OnStart method and regardless of the outcome of whether the user gives access, the same two pieces of code should execute:
Starting my service
Auto-login the user if they have provided credentials before
If I retype my credentials and turn the app on and off then on again - then for around 2-5 minutes it will automatically log me in. If I have the app off for longer than that, the autologin will not work.
OnStart:
#Override
protected void onStart() {
super.onStart();
List<String> permissions = new ArrayList<>();
permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
permissions.add(Manifest.permission.ACTIVITY_RECOGNITION);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
permissions.add(Manifest.permission.SCHEDULE_EXACT_ALARM);
checkPermission(permissions.toArray(new String[0]), INITIAL_REQUESTS_CODE);
}
checkPermission Function:
public void checkPermission(String[] permissions, int requestCode) {
// Checking if permission is not granted
boolean ungrantedPermissions = false;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_DENIED) {
ungrantedPermissions = true;
break;
}
}
if (ungrantedPermissions)
ActivityCompat.requestPermissions(this, permissions, requestCode);
else{
startStepCounterService();
attemptLoginWithSavedCredentials();
}
}
onRequestPermissionResult:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode,
permissions,
grantResults);
startStepCounterService();
attemptLoginWithSavedCredentials();
}
startStepCounterService Function:
private void startStepCounterService() {
if(!isMyServiceRunning(StepCounterService.class))
{
Intent newIntent = new Intent(this, StepCounterService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(newIntent);
} else {
startService(newIntent);
}
}
}
attemptLoginWithSavedCredentials Function:
private void attemptLoginWithSavedCredentials() {
String savedUsername = SaveSharedPreference.getUserName(this);
String savedPassword = SaveSharedPreference.getUserPassword(this);
if(!savedUsername.isEmpty() && !savedPassword.isEmpty())
{
LoadingExtensions.showLoadingIcon(loadingIndicator, rootView);
loginManager.login(savedUsername, savedPassword);
}
}
Related
I have two activities: a Main, as well a RuntimePermissionManager, which is started first whenever my app is opened.
The app works as expected when the user allows the runtime permission, but when they deny it, instead of the AlertDialog showing up with the permission rationale, the permission dialog is closed completely, and I just get an infinite splash screen (since I have set it to always be on screen during the lifetime of its parent activity).
I have copied the permission logic straight from the RuntimePermissionsBasic example bundled with Android Studio, and just replaced the Snackbar with an AlertDialog, so I don’t see why my app isn’t working.
Here’s the complete RuntimePermissionManager activity for reference.
Thanks.
public class RuntimePermissionManager extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
private static final String TAG = "RuntimePermissionManager";
private static final String PERMISSION = Manifest.permission.WRITE_EXTERNAL_STORAGE;
private static final int PERMISSION_ID = 0;
#Override
protected void onCreate(final Bundle savedInstanceState) {
final SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
super.onCreate(savedInstanceState);
// This ensures no hiccups while the splash screen is active.
splashScreen.setKeepOnScreenCondition(() -> true);
checkRuntimePermissionStatus();
ThreadManager.unpackCriticalAssets(getApplicationContext());
}
#Override
public void onRequestPermissionsResult(final int requestCode, #NonNull final String[] permissions, #NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_ID) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Runtime permission has been granted.");
startMainActivity();
} else {
Log.e(TAG, "Runtime permission has been denied.");
}
}
}
private void checkRuntimePermissionStatus() {
if (ActivityCompat.checkSelfPermission(this, PERMISSION) == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Runtime permission has been granted.");
startMainActivity();
} else {
requestRuntimePermission();
}
}
private void requestRuntimePermission() {
System.out.println(ActivityCompat.shouldShowRequestPermissionRationale(this, PERMISSION));
if (ActivityCompat.shouldShowRequestPermissionRationale(this, PERMISSION)) {
System.out.println("HERE1");
showPermissionRationaleDialog(R.string.permission_rationale_title, R.string.permission_rationale_message);
} else {
Log.e(TAG, "Runtime permission has been denied.");
ActivityCompat.requestPermissions(this, new String[]{PERMISSION}, PERMISSION_ID);
}
}
private void showPermissionRationaleDialog(final int title, final int message) {
System.out.println("HERE2");
AlertDialog.Builder builder = new AlertDialog.Builder(RuntimePermissionManager.this);
builder.setTitle(title).setMessage(message).setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(RuntimePermissionManager.this, new String[]{PERMISSION}, PERMISSION_ID);
}
});
builder.create().show();
}
private void startMainActivity() {
Intent intent = new Intent(this, Main.class);
startActivity(intent);
}
}
I am trying to request some permission for my app inside the launcher activity. This activity only checks for permissions and prompts the user asking for missing permission. What I want to do is after 1.5 seconds, if the user was prompted and accepted/denied the permissions required, the main activity is started, displaying the dashboard of the application. Now, the problem is that onRequestPermissionResult is not called no matter what I do and I don't understand where the problem comes from. I mention that the permissions are requested successfully, the user being prompted and being able to accept them or deny them, but the callback is not triggered somehow.
Here is my activity code:
public class LauncherActivity extends AppCompatActivity {
public static final String TAG = LauncherActivity.class.getSimpleName();
private boolean permissionsGiven;
private static final String[] REQUIRED_PERMISSIONS =
new String[] {
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
};
private static final int REQUEST_CODE_REQUIRED_PERMISSIONS = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
if (!hasPermissions(this, REQUIRED_PERMISSIONS)) {
permissionsGiven = false;
Log.d(TAG, "onCreate: app does not have all the required permissions. Requesting permissions...");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(
this,
REQUIRED_PERMISSIONS,
REQUEST_CODE_REQUIRED_PERMISSIONS
);
}
} else {
permissionsGiven = true;
}
Runnable enterApplication = new Runnable() {
#Override
public void run() {
while (!permissionsGiven);
SharedPreferences loginPreferences = getApplicationContext().getSharedPreferences("LOGIN_DETAILS", MODE_PRIVATE);
boolean signedIn = loginPreferences.getBoolean("signedIn", false);
if (!signedIn) {
Log.d(TAG, "onCreate: user is not signed in. Sending him to login activity...");
sendUserToLoginActivity();
} else {
sendUserToMainActivity();
}
}
};
Handler launcherHandler = new Handler();
launcherHandler.postDelayed(enterApplication, 1500);
}
private static boolean hasPermissions(Context context, String... permissions) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
#CallSuper
#Override
public void onRequestPermissionsResult(
int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode != REQUEST_CODE_REQUIRED_PERMISSIONS) {
return;
}
permissionsGiven = true;
for (int grantResult : grantResults) {
if (grantResult == PackageManager.PERMISSION_DENIED) {
Toast.makeText(this, "Missing permissions", Toast.LENGTH_LONG).show();
finish();
return;
}
}
recreate();
}
private void sendUserToLoginActivity() {
Log.d(TAG, "sendUserToLoginActivity: starting login activity...");
Intent loginIntent = new Intent(LauncherActivity.this, SignInActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(loginIntent);
finish();
}
private void sendUserToMainActivity() {
Log.d(TAG, "sendUserToMainActivity: starting main activity...");
Intent mainIntent = new Intent(LauncherActivity.this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mainIntent);
finish();
}
}
Can anyone help me understand what am I doing wrong and how can I trigger onRequestPermissionsResult so I can start the next activity inside the app?
recreate();
I never saw that method.
Dont call it for a test and place a Toast instead.
I wonder how you know that it is not triggered.
Further i would not use a thread that is waiting for a variable to change its value.
Further you dont need threads at all. Just call the code in onCreate or onRequestPermissionsResult. You can place all that code in a function.
My Android application crashes the first time launching and it asks me about the user call permission. When I launch my app again then it works normally. I have tried the following code.
public void loadContactList() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
} else {.....}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
loadContactList();
} else {
Toast.makeText(this, "Until you grant the permission, we canot display the list", Toast.LENGTH_SHORT).show();
}
}
}
Your code is right but you set the codes on wrong places lets try this it will definitely help you....
In Your Main Activity...
private int STORAGE_PERMISSION_CODE = 1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
filter();
Toast.makeText(this, ""+arrayList, Toast.LENGTH_SHORT).show();
} else {
Permission.requestStoragePermission(MainActivity.this,
STORAGE_PERMISSION_CODE);
}
}//on create closed
Permission method.....
//---------------------------------RuntimePermission-----------------------------//
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[]
permissions, #NonNull int[] grantResults) {
if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] ==
PackageManager.PERMISSION_GRANTED) {
filter();
} else {
Toast.makeText(this, "Permission DENIED", Toast.LENGTH_SHORT).show();
Permission.requestStoragePermission(MainActivity.this,STORAGE_PERMISSION_CODE);
}
}
}
after that make java class for getting permission....
public class Permission {
public static void requestStoragePermission(final Activity activity, final int
STORAGE_PERMISSION_CODE) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(activity)
.setTitle("Permission needed")
.setMessage("This permission is needed because of this and that")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(activity,
new String[]
{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.create().show();
} else {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
STORAGE_PERMISSION_CODE);
}
}
}
The main thing you have to remember is to put your working method at the right place like my is filter();
It will work for you because it work for me when i stuck in the same situation
Add the following code
String[] appPermissions =
{Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS};
int PERMISSIONS_REQUEST_CODE = 234;
Call this Method from your on create
checkAndRequestPermissions();
Add the following method to your Main Activity
public boolean checkAndRequestPermissions() {
List<String> listPermissionsNeeded = new ArrayList<>();
for (String perm : appPermissions) {
if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(perm);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), PERMISSIONS_REQUEST_CODE);
return false;
}
return true;
}
I just solved an exception. I did two things. Firstly, I removed the initialization of Contacts by
Contacts = new ArrayList<ContactModel> from the loadContactList() and added it into the onCreate() and Secondly I just changed the return datatype of loadContactList() from void to list. Then I returned the contacts in loadContacts() so that loadListView() can fetch this list and display it into the list view.
I am creating an app in which i am unable to handle the permission of location in fragment.The method
public void onRequestPermissionsResult(int requestCode String permissions[], int[] grantResults){}
is not working in fragment. So please help me how to handle both permission DENY and ALLOW This is my code...
public class BlankFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_blank, container, false);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
return v;
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission was granted.
if (ActivityCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
}
} else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(getActivity(), "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
}
}
Please help me how to handle the both permissions in fragment.
Thanks..
AFAIK, you should use this PermissionsDispatcher to request runtime permission. You just need to define callback functions in your Fragment as below:
#NeedsPermission(Manifest.permission. ACCESS_FINE_LOCATION)
void showCamera() {
getSupportFragmentManager().beginTransaction()
.replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
.addToBackStack("camera")
.commitAllowingStateLoss();
}
#OnShowRationale(Manifest.permission. ACCESS_FINE_LOCATION)
void showRationaleForCamera(final PermissionRequest request) {
new AlertDialog.Builder(this)
.setMessage(R.string.permission_camera_rationale)
.setPositiveButton(R.string.button_allow, (dialog, button) -> request.proceed())
.setNegativeButton(R.string.button_deny, (dialog, button) -> request.cancel())
.show();
}
#OnPermissionDenied(Manifest.permission. ACCESS_FINE_LOCATION)
void showDeniedForCamera() {
Toast.makeText(this, R.string.permission_camera_denied, Toast.LENGTH_SHORT).show();
}
#OnNeverAskAgain(Manifest.permission. ACCESS_FINE_LOCATION)
void showNeverAskForCamera() {
Toast.makeText(this, R.string.permission_camera_neverask, Toast.LENGTH_SHORT).show();
}
Then using the auto-gen method to request permission:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button_camera).setOnClickListener(v -> {
// NOTE: delegate the permission handling to generated method
MainActivityPermissionsDispatcher.showCameraWithCheck(this);
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// NOTE: delegate the permission handling to generated method
MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
You should read the library carefully for more detail.
Try this after removing ActivityCompat from code.
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)) {
//Prompt the user once explanation has been shown
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
i want to ask the user to accept the following permissions at the same time(one by one), the permissions are like:
checkLocationPermission, checkReadSMS, checkCallingPermission, checkReadState, checkContactWriteState.
So, how i can ask all these permissions in my first screen itself.
Please help me out in this regard.
Thanks in advance.
You have to first check that user phone build version is 23.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
askPermissions(true);
} else {
startActivity(new Intent(PermissionsActivity.this, SplashActivity.class));
finish();
}
If version is 23 then you need to ask permissions.
private void askPermissions(boolean isForOpen) {
isRationale = false;
List permissionsRequired = new ArrayList();
final List<String> permissionsList = new ArrayList<String>();
if (!checkPermission(permissionsList, Manifest.permission.WRITE_EXTERNAL_STORAGE))
permissionsRequired.add("Write External Storage");
if (!checkPermission(permissionsList, Manifest.permission.CALL_PHONE))
permissionsRequired.add("Call phone");
if (!checkPermission(permissionsList, Manifest.permission.READ_PHONE_STATE))
permissionsRequired.add("Read phone state");
if (!checkPermission(permissionsList, Manifest.permission.READ_CONTACTS))
permissionsRequired.add("Read Contacts");
if (!checkPermission(permissionsList, Manifest.permission.RECEIVE_SMS))
permissionsRequired.add("Receive SMS");
if (!checkPermission(permissionsList, Manifest.permission.GET_ACCOUNTS))
permissionsRequired.add("Get Accounts");
if (!checkPermission(permissionsList, Manifest.permission.ACCESS_COARSE_LOCATION))
permissionsRequired.add("Location");
if (!checkPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
permissionsRequired.add("Location");
if (permissionsList.size() > 0 && !isRationale) {
if (permissionsRequired.size() > 0) {
}
if (isForOpen) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(this, permissionsList.toArray(new String[permissionsList.size()]),
11);
}
}
} else if (isRationale) {
if (isForOpen) {
new android.support.v7.app.AlertDialog.Builder(this, R.style.AppCompatAlertDialogStyle)
.setTitle("Permission Alert")
.setMessage("You need to grant permissions manually. Go to permission and grant all permissions.")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 123);
}
})
.show();
}
} else {
startActivity(new Intent(PermissionsActivity.this, SplashActivity.class));
finish();
}
}
private boolean checkPermission(List permissionsList, String permission) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Check for Rationale Option
if (!isFirst) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
isRationale = true;
return false;
}
}
}
}
return true;
}
on the onRequestPermissionsResult you need to check which permissions granted
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 11:
Map<String, Integer> perms = new HashMap<String, Integer>();
// Initial
perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.CALL_PHONE, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_PHONE_STATE, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.RECEIVE_SMS, PackageManager.PERMISSION_GRANTED);
// Fill with results
for (int i = 0; i < permissions.length; i++) {
perms.put(permissions[i], grantResults[i]);
}
// Check for ACCESS_FINE_LOCATION
if (perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
perms.get(Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED &&
perms.get(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED &&
perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED &&
perms.get(Manifest.permission.RECEIVE_SMS) == PackageManager.PERMISSION_GRANTED) {
// All Permissions Granted
startActivity(new Intent(PermissionsActivity.this, SplashActivity.class));
finish();
} else {
// Permission Denied
Toast.makeText(this, "Some Permission is Denied.", Toast.LENGTH_SHORT)
.show();
isFirst = false;
askPermissions(true);
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
If user has set the permission to never ask again then the application setting screen will open. User will allow/Deny permission there. You need to check again on the activityResult.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
askPermissions(true);
}
if (!hasPermissions()){
// your app doesn't have permissions, ask for them.
requestNecessaryPermissions();
}
else {
// your app already have permissions allowed.
// do what you want.
}
private boolean hasPermissions() {
int res = 0;
// list all permissions which you want to check are granted or not.
String[] permissions = new String[] {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
for (String perms : permissions){
res = checkCallingOrSelfPermission(perms);
if (!(res == PackageManager.PERMISSION_GRANTED)){
// it return false because your app dosen't have permissions.
return false;
}
}
// it return true, your app has permissions.
return true;
}
private void requestNecessaryPermissions() {
// make array of permissions which you want to ask from user.
String[] permissions = new String[] {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// have arry for permissions to requestPermissions method.
// and also send unique Request code.
requestPermissions(permissions, REQUEST_CODE_STORAGE_PERMS);
}
}
/* when user grant or deny permission then your app will check in
onRequestPermissionsReqult about user's response. */
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grandResults) {
// this boolean will tell us that user granted permission or not.
boolean allowed = true;
switch (requestCode) {
case REQUEST_CODE_STORAGE_PERMS:
for (int res : grandResults) {
// if user granted all required permissions then 'allowed' will return true.
allowed = allowed && (res == PackageManager.PERMISSION_GRANTED);
}
break;
default:
// if user denied then 'allowed' return false.
allowed = false;
break;
}
if (allowed) {
// if user granted permissions then do your work.
dispatchTakePictureIntent();
}
else {
// else give any custom waring message.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
Toast.makeText(MainActivity.this, "Camera Permissions denied", Toast.LENGTH_SHORT).show();
}
else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(MainActivity.this, "Storage Permissions denied", Toast.LENGTH_SHORT).show();
}
}
}
}
follow this tutorial, in this tutorial multiples permissions are asked
Android 6.0 Runtime Permissions
the Kotlin version
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.fragment.app.Fragment
class MyFragment : Fragment() {
companion object {
val TAG: String = MyFragment::class.java.simpleName
var PERMISSIONS = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
}
private val permReqLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
val granted = permissions.entries.all {
it.value == true
}
if (granted) {
displayCameraFragment()
}
}
private fun takePhoto() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
displayCameraFragment()
}
activity?.let {
if (hasPermissions(activity as Context, PERMISSIONS)) {
displayCameraFragment()
} else {
permReqLauncher.launch(
PERMISSIONS
)
}
}
}
// util method
private fun hasPermissions(context: Context, permissions: Array<String>): Boolean = permissions.all {
ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
private fun displayCameraFragment() {
// open camera fragment
}
}