I made an Android App, which have some permissions, everything is ok but problem is that when user don't click on Allow or Deny(on Permission Dialog at first time app launch) button with in few seconds(approx 3 to 5 seconds) then my app not functioning properly it's register page, login and some other functions not working, if user click within few seconds then its work properly without any issue, i also check this from Internet but nobody clear my issue please help. FCM token not generating from Firebase.
Error is:-
E/FirebaseInstanceId: Unable to get master token
java.lang.SecurityException: getDeviceId: Neither user 10493 nor current process has android.permission.READ_PHONE_STATE.
at android.os.Parcel.readException(Parcel.java:2004)
at android.os.Parcel.readException(Parcel.java:1950)
at com.android.internal.telephony.ITelephony$Stub$Proxy.getDeviceId(ITelephony.java:5030)
at android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java:1013)
at com.Abc.AppName.FirebaseInstanceIDService.id(FirebaseInstanceIDService.java:63)
at com.Abc.AppName.FirebaseInstanceIDService.onTokenRefresh(FirebaseInstanceIDService.java:35)
at com.google.firebase.iid.FirebaseInstanceIdService.zza(Unknown Source:187)
at com.google.firebase.iid.FirebaseInstanceIdService.handleIntent(Unknown Source:306)
at com.google.firebase.iid.zzc.run(Unknown Source:4)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Manifest:-
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
Splash:-
if (Build.VERSION.SDK_INT >= 23) {
String[] PERMISSIONS = {android.Manifest.permission.INTERNET,
android.Manifest.permission.ACCESS_NETWORK_STATE,
android.Manifest.permission.READ_PHONE_STATE,
Manifest.permission.CALL_PHONE
};
if (!hasPermissions(mContext, PERMISSIONS)) {
ActivityCompat.requestPermissions((Activity) mContext, PERMISSIONS, REQUEST);
} else {
callNextActivity();
}
} else {
callNextActivity();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
callNextActivity();
} else {
Toast.makeText(mContext, R.string.permission_denied, Toast.LENGTH_LONG).show();
}
}
}
}
private static boolean hasPermissions(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
FirebaseInstanceID:-
#Override
public void onTokenRefresh() {
token = FirebaseInstanceId.getInstance().getToken();
device_id = id(this);
sharedPreferences = getSharedPreferences(getString(R.string.prefs), 0);
sharedPreferences.edit().putString("fcm_token", token).apply();
device_id = sharedPreferences.getString(PREF_UNIQUE_ID, "");
Log.e("fcm_token", token + " " + device_id);
executeMethod();
}
public synchronized static String id(Context context) {
if (uniqueID == null) {
SharedPreferences sharedPrefs = context.getSharedPreferences(context.getString(R.string.prefs), Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
if (uniqueID == null) {
mngr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
}
uniqueID = mngr.getDeviceId();
Log.e("UNIQUEID", uniqueID);
sharedPrefs.edit().putString(PREF_UNIQUE_ID, uniqueID).apply();
}
}
return uniqueID;
}
You can use another activity to request permissions. If user allows, just start your main activity, else kill request activity or show popup to warn user.
The problem is you are trying to get id of the device in onTokenRefresh . This method will be called as soon as the app gets installed and opened first time . By this time your app wont have the permission .
So solution to this problem .
In onTokenRefresh just save the token in shared preferences and when you reach the activity ,request for permission and after permission is granted get the token from shared preferences and device id and do your stuff .
I try to create folder in android external storage. I try many example but it all isn't worked. I set run-time permissions for reading and writing to external storage. It is work on Android API 6, 7. but not work on Android Oreo.
File f = new File(Environment.getExternalStorageDirectory(), "MyDir");
if (!f.exists()) {
try {
boolean is_seccess = f.mkdirs();
if (is_seccess) {
Toast.makeText(this, "create", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "not create", Toast.LENGTH_SHORT).show();
}
}catch (Exception e){
e.printStackTrace();
}
}
I Checked if external storage is available for read and write, it return true.
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
I give below permissions, I also give run-time permission and allow it.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Just Android Oreo isn't work other device is working perfect. What is problem in my code?
The app requests READ_EXTERNAL_STORAGE and the user grants it. If the app targets API level 25 or lower, the system also grants WRITE_EXTERNAL_STORAGE at the same time, because it belongs to the same STORAGE permission group and is also registered in the manifest. If the app targets Android 8.0 (API level 26), the system grants only READ_EXTERNAL_STORAGE at that time; however, if the app later requests WRITE_EXTERNAL_STORAGE
Ask run time permission like below:
private boolean checkAndRequestPermissions() {
int permissionReadStorage = ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE);
int permissionCamera = ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA);
int permissionWriteStorage = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
List<String> listPermissionsNeeded = new ArrayList<>();
if (permissionCamera != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CAMERA);
}
if (permissionReadStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (permissionWriteStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions((Activity) this,
listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),
REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
I'm trying to get permission for drawing overlays in marshmallow.
In marshmallow we must give run-time permission for drawing overlays and I have implemented. What issue I'm getting is once I have given the permission from my app next time if I check with following code, if(Settings.canDrawOverlays(getApplicationContext()) it returns false.
But in settings (Draw over other apps) my app is Checked. Here I have provided my code of lib activity.
if(Settings.canDrawOverlays(getApplicationContext())&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
Toast.makeText(getApplicationContext(), "Windows Overlay allowed" , Toast.LENGTH_SHORT).show();
startService(new Intent(this, FABService.class));
finish();
}
else{
startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION), 1);
}
and my onActivityResult is,
#TargetApi(Build.VERSION_CODES.M)
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
/** check if received result code
is equal our requested code for draw permission */
if (requestCode == 1) {
// * if so check once again if we have permission /
if (Settings.canDrawOverlays(getApplicationContext()) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// continue here - permission was granted
Toast.makeText(getApplicationContext(), "Windows Overlay allowed", Toast.LENGTH_LONG).show();
startService(new Intent(this, FABService.class));
finish();
}
}
}
These code I have implemented in lib of that application. Any 1 can help me where I have went wrong.
Put permission in Manifest
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Use this for Overlay permission
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(myIntent);
}
It is a very strange situation. I am working with camera2 API and there is a regular method to open the camera.
manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
this method is requiring to make test, this one
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) !=
PackageManager.
return;
}
it is simple test to deduce if there was declared CAMERA permission in manifest or not.
<uses-permission android:name="android.permission.CAMERA" />
i have this permission in my manifest file and if i am uploading this app to Samsung S5 it is work properly without problem, but if i am uploading this app to chinese device, mistake is happen. Don't pass the test and eventually don't open the camera...
Maybe should i set permission dynamically?
And one more thing, i have tryed call method to open the camera inside test, this way
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) !=
PackageManager.
manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
return;
}
but get this mistake
FATAL EXCEPTION: main Process: com.example.android.camera2basic, PID: 29649 Theme: themes:{} java.lang.SecurityException: Lacking privileges to access camera service at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108) at android.hardware.camera2.legacy.CameraDeviceUserShim.connectBinderShim(CameraDeviceUserShim.java:336) at android.hardware.camera2.CameraManager.openCameraDeviceUserAsync(CameraManager.java:327) at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:457) at com.example.android.camera2basic.activities.CameraActivity.openCamera(CameraActivity.java:919)
What i am doing wrong?
On API level 23+ you need to request permissions at runtime (even if you have them declared in your Manifest).
You should do something like this:
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
CAMERA_REQUEST);
To process the result you need to override onRequestPermissionsResult() in your Activity:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == CAMERA_REQUEST) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission granted
// you can do your Camera related stuff
} else {
// permission denied
}
}
// ...
}
Check out the documentation on runtime permissions.
I am testing my app on Marshmallow 6.0 and it's getting force closed for the android.permission.READ_EXTERNAL_STORAGE, even if it is defined in the Manifest already. Somewhere I have read that if I request permission at runtime then it would not force close your application. I have read this android document also, which is for requesting runtime permission.
So, I came to know that we can request a permission like below which is mentioned in the android document.
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
The above code has a callback method onRequestPermissionsResult which gets the result.
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
}
}
My question is where to exactly request the permission to user? Should we use the requesting permission at start of the app or should we do it as when the permission is required?
This is worked for me !!!
In Your Splash Activity of your application do the following,
1) Declare an int variable for request code,
private static final int REQUEST_CODE_PERMISSION = 2;
2) Declare a string array with the number of permissions you need,
String[] mPermission = {Manifest.permission.READ_CONTACTS, Manifest.permission.READ_SMS,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
3) Next Check the condition for runtime permission on your onCreate method,
try {
if (ActivityCompat.checkSelfPermission(this, mPermission[0])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, mPermission[1])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, mPermission[2])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, mPermission[3])
!= MockPackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
mPermission, REQUEST_CODE_PERMISSION);
// If any permission aboe not allowed by user, this condition will execute every tim, else your else part will work
}
} catch (Exception e) {
e.printStackTrace();
}
4) Now Declare onRequestPermissionsResult method to check the request code,
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.e("Req Code", "" + requestCode);
if (requestCode == REQUEST_CODE_PERMISSION) {
if (grantResults.length == 4 &&
grantResults[0] == MockPackageManager.PERMISSION_GRANTED &&
grantResults[1] == MockPackageManager.PERMISSION_GRANTED &&
grantResults[2] == MockPackageManager.PERMISSION_GRANTED &&
grantResults[3] == MockPackageManager.PERMISSION_GRANTED) {
// Success Stuff here
}
}
}
Do like this
private static final int REQUEST_ACCESS_FINE_LOCATION = 111;
In your onCreate
boolean hasPermissionLocation = (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED);
if (!hasPermissionLocation) {
ActivityCompat.requestPermissions(ThisActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_ACCESS_FINE_LOCATION);
}
then check result
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case REQUEST_ACCESS_FINE_LOCATION: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(ThisActivity.this, "Permission granted.", Toast.LENGTH_SHORT).show();
//reload my activity with permission granted
finish();
startActivity(getIntent());
} else
{
Toast.makeText(ThisActivity.this, "The app was not allowed to get your location. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
}
}
In general, request needed permissions it as soon as you need them. This way you can inform the user why you need the permission and handle permission denies much easier.
Think of scenarios where the user revokes the permission while your app runs: If you request it at startup and never check it later this could lead to unexpected behaviour or exceptions.
In my opinion, there is no one correct answer to your question. I strongly suggest you to look at this official permissions patterns page.
Couple of things suggested by Google :
"Your permissions strategy depends on the clarity and importance of the permission type you are requesting. These patterns offer different ways of introducing permissions to the user."
"Critical permissions should be requested up-front. Secondary permissions may be requested in-context."
"Permissions that are less clear should provide education about what the permission involves, whether done up-front or in context."
This illustration might give you better understanding.
Maybe the most crucial thing here is that whether you ask the permission up-front or in the context, you should always keep in mind that these permissions can be revoked anytime by the user (e.g. your app is still running, in background).
You should make sure that your app doesn't crash just because you asked the permission on the very beginning of the app and assumed that user didn't change his/her preference about that permission.
For requesting runtime permission i use GitHub Library
Add library in Build.gradle file
dependencies {
compile 'gun0912.ted:tedpermission:1.0.3'
}
Create Activity and add PermissionListener
public class MainActivity extends AppCompatActivity{
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PermissionListener permissionlistener = new PermissionListener() {
#Override
public void onPermissionGranted() {
Toast.makeText(RationaleDenyActivity.this, "Permission Granted", Toast.LENGTH_SHORT).show();
//Camera Intent and access Location logic here
}
#Override
public void onPermissionDenied(ArrayList<String> deniedPermissions) {
Toast.makeText(RationaleDenyActivity.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
new TedPermission(this)
.setPermissionListener(permissionlistener)
.setRationaleTitle(R.string.rationale_title)
.setRationaleMessage(R.string.rationale_message) // "we need permission for access camera and find your location"
.setDeniedTitle("Permission denied")
.setDeniedMessage("If you reject permission,you can not use this service\n\nPlease turn on permissions at [Setting] > [Permission]")
.setGotoSettingButtonText("Settings")
.setPermissions(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.check();
}
}
string.xml
<resources>
<string name="rationale_title">Permission required</string>
<string name="rationale_message">we need permission for read <b>camera</b> and find your <b>location</b></string>
</resources>
Android Easy Runtime Permissions with Dexter:
1. Dexter Permissions Library
To get started with Dexter, add the dependency in your build.gradle
dependencies {
// Dexter runtime permissions
implementation 'com.karumi:dexter:4.2.0'
}
1.1 Requesting Single Permission
To request a single permission, you can use withPermission() method by passing the required permission. You also need a PermissionListener callback to receive the state of the permission.
> onPermissionGranted() will be called once the permission is granted.
> onPermissionDenied() will be called when the permission is denied. Here you can check whether the permission is permanently denied by using response.isPermanentlyDenied() condition.
The below code requests CAMERA permission.
Dexter.withActivity(this)
.withPermission(Manifest.permission.CAMERA)
.withListener(new PermissionListener() {
#Override
public void onPermissionGranted(PermissionGrantedResponse response) {
// permission is granted, open the camera
}
#Override
public void onPermissionDenied(PermissionDeniedResponse response) {
// check for permanent denial of permission
if (response.isPermanentlyDenied()) {
// navigate user to app settings
}
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
1.2 Requesting Multiple Permissions
To request multiple permissions at the same time, you can use withPermissions() method. Below code requests STORAGE and LOCATION permissions.
Dexter.withActivity(this)
.withPermissions(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new MultiplePermissionsListener() {
#Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
// check if all permissions are granted
if (report.areAllPermissionsGranted()) {
// do you work now
}
// check for permanent denial of any permission
if (report.isAnyPermissionPermanentlyDenied()) {
// permission is denied permenantly, navigate user to app settings
}
}
#Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
})
.onSameThread()
.check();
A good explanation and HowTo can be found here:
https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en
I wrote this code to check and request the permissions at runtime in a BaseActivity.class which is parent of every other Activity.class I implemented:
public static final int PERMISSION_REQUEST = 42;
public static final int MULTIPLE_PERMISSION_REQUEST = 43;
//Marshmallow Permission Model
public boolean requestPermission(String permission /* Manifest.permission...*/) {
if (ContextCompat.checkSelfPermission(this,
permission) != PackageManager.PERMISSION_GRANTED) {
if (Utils.hasMarshmallow())
ActivityCompat.requestPermissions(this,
new String[]{permission}, PERMISSION_REQUEST
);
else {
requestPermissions(new String[]{permission},
PERMISSION_REQUEST);
}
return false;
} else {
return true;
}
}
public boolean requestPermission(String... permissions) {
final List<String> permissionsList = new ArrayList<String>();
for (String perm : permissions) {
addPermission(permissionsList, perm);
}
if (permissionsList.size() > 0) {
if (Utils.hasMarshmallow())
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
MULTIPLE_PERMISSION_REQUEST);
else
ActivityCompat.requestPermissions(this, permissionsList.toArray(new String[permissionsList.size()]),
MULTIPLE_PERMISSION_REQUEST);
return false;
} else
return true;
}
private boolean addPermission(List<String> permissionsList, String permission) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Check for Rationale Option
if (Utils.hasMarshmallow())
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST:
case MULTIPLE_PERMISSION_REQUEST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
Simply example call:
activity.requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE);
Return result will let you know if the permission is already granted or not.
calling this function we can allow user to open dialog for asking permission to allow camera and record Audio.
if ( ActivityCompat.shouldShowRequestPermissionRationale (this, Manifest.permission.CAMERA) ||
ActivityCompat.shouldShowRequestPermissionRationale (this,
Manifest.permission.RECORD_AUDIO) ) {
Toast.makeText (this,
R.string.permissions_needed,
Toast.LENGTH_LONG).show ();
} else {
ActivityCompat.requestPermissions (
this,
new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO},
CAMERA_MIC_PERMISSION_REQUEST_CODE);
}
https://material.io/guidelines/patterns/permissions.html
This link will give you different type of scenario where permissions can be asked. Choose accordingly to your needs.
I like short code. I use RxPermission for permissions.
RxPermission is best library, which makes permission code unexpected just 1 line.
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
.request(Manifest.permission.CAMERA,
Manifest.permission.READ_PHONE_STATE) // ask single or multiple permission once
.subscribe(granted -> {
if (granted) {
// All requested permissions are granted
} else {
// At least one permission is denied
}
});
add in your build.gradle
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
}
Isn't this easy?
if ( ActivityCompat.shouldShowRequestPermissionRationale (this, Manifest.permission.CAMERA) ||
ActivityCompat.shouldShowRequestPermissionRationale (this,
Manifest.permission.RECORD_AUDIO) ) {
Toast.makeText (this,
R.string.permissions_needed,
Toast.LENGTH_LONG).show ();
} else {
ActivityCompat.requestPermissions (
this,
new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO},
CAMERA_MIC_PERMISSION_REQUEST_CODE);
}