after build app, connection error on android marshmallow - android

my device on android marshmallow.
so I use get permission this method.
int currentApiVer = Build.VERSION.SDK_INT;
Log.d(TAG, "currentApiVer = " + currentApiVer);
if (currentApiVer >= Build.VERSION_CODES.M) {
Log.d(TAG, "currentApiVer ----------------------------");
verifyPermissions(this);
} //onCreate()
private static boolean verifyPermissions(AppCompatActivity activity) {
Log.d(TAG, "verifyPermissions --------------------------------------");
int writePerm = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int readPerm = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
int camera_perm = ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
if (writePerm != PackageManager.PERMISSION_GRANTED ||
readPerm != PackageManager.PERMISSION_GRANTED ||
camera_perm != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity, PERMISSIONS_REQ, REQUEST_CODE_PERMISSIONS
);
return false;
} else {
return true;
}
}
my app is CCTV app. I use WebRTC
my problem when I first build my app.
show permission dialog. when I check permit permission.
success CCTV connect.
but I try again start built app.
fail CCTV connect.
clearly I already check permit permission.
perhaps, I think marshmallow permission problem.
in this situation. how I fix this problem?
thanks.

Related

How to know if location permission is granted "Allow all the time"

In Android 10, when asking for some permission like Location, the system prompts the user 3 options:
Allow APP to access this device's location?
-Allow all the time
-Allow only while using the app
-Deny
Is there a way to know how exactly has been granted? I use this code to know if location is granted:
boolean hasPermission = (ContextCompat.checkSelfPermission(oContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED);
But I need to know if it has been granted "all the time" or just "while using the app".
What I really need is to have permission all the time as my app has a background location service. So I need to know if the permission has been granted to to that, or the possibility to ask for the permission but without the option of allowing it "only when using the app".
requestPermissions(Context, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 123);
You can use:
boolean backgroundLocationPermissionApproved =
ActivityCompat.checkSelfPermission(this,
permission.ACCESS_BACKGROUND_LOCATION)
There is no possibility to prompt the user without letting him choose the "only when using the app" option.
You can use this method, I have tested this method on android level 10 and above :
private void checkLocationPermissionState(Context context){
int fineLocation = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION);
int coarseLocation = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
int bgLocation = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_BACKGROUND_LOCATION);
boolean isAppLocationPermissionGranted = (bgLocation == PackageManager.PERMISSION_GRANTED) &&
(coarseLocation == PackageManager.PERMISSION_GRANTED);
boolean preciseLocationAllowed = (fineLocation == PackageManager.PERMISSION_GRANTED)
&& (coarseLocation == PackageManager.PERMISSION_GRANTED);
if (preciseLocationAllowed) {
Log.e("PERMISSION","Precise location is enabled in Android 12");
} else {
Log.e("PERMISSION","Precise location is disabled in Android 12");
}
if (isAppLocationPermissionGranted) {
Log.e("PERMISSION","Location is allowed all the time");
} else if(coarseLocation == PackageManager.PERMISSION_GRANTED){
Log.e("PERMISSION","Location is allowed while using the app");
}else{
Log.e("PERMISSION","Location is not allowed.");
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
int bgLocation = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_BACKGROUND_LOCATION);
boolean isAppLocationPermissionGranted = (bgLocation == PackageManager.PERMISSION_GRANTED) &&
(coarseLocation == PackageManager.PERMISSION_GRANTED);
if (isAppLocationPermissionGranted) {
Log.e("PERMISSION","Location is allowed all the time");
} else if(coarseLocation == PackageManager.PERMISSION_GRANTED){
Log.e("PERMISSION","Location is allowed while using the app");
}else{
Log.e("PERMISSION","Location is not allowed.");
}
} else {
boolean isAppLocationPermissionGranted = (fineLocation == PackageManager.PERMISSION_GRANTED) &&
(coarseLocation == PackageManager.PERMISSION_GRANTED);
if (isAppLocationPermissionGranted) {
Log.e("PERMISSION","Location permission is granted");
} else {
Log.e("PERMISSION","Location permission is not granted");
}
}
}
As of 18th July 2021 based on #gkpln3's answer it is not returning Boolean value but returning Integer value so added a small boolean converter in Kotlin
val backgroundLocationPermissionApproved: Boolean = ActivityCompat.checkSelfPermission(requireContext(),
Manifest.permission.ACCESS_BACKGROUND_LOCATION) > -1

Kotlin : TelephonyManager.getImei() Call requires permission which may be rejected by user

I'am developping an android app with Kotlin, i use the api 28.
I want to get the deviceId number.At the begining i use TelephonyManager.deviceId, after some research,i found that it's deprecated.
I found as solution, replace deviceId by getImei()
The following an excerpt from my code:
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
if (telephonyManager != null) {
val androidID = Settings.Secure.getString(this.contentResolver, Settings.Secure.ANDROID_ID)
if (androidID != null) {
Utility().DEVICE_ID = androidID
Utility().setDataBykeyValue(applicationContext, AppController.SHAIRD_PREF_DEVICE_ID, androidID)
} else {
val devId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) telephonyManager.getImei()
else telephonyManager.getDeviceId()
Utility().DEVICE_ID = devId
Utility().setDataBykeyValue(applicationContext, AppController.SHAIRD_PREF_DEVICE_ID, devId)
}
Utility().CARRIER = telephonyManager.simOperatorName
}
Also i add this permission to my AndroidManifest.xml :
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
the "telephonyManager.getImei()" is underline with a red line, and the following msg appear :
Call requires permission which may be rejected by user: code should
explicitly check to see if permission is available (with
checkPermission) or explicitly handle a potential
I want to know what's the problem and how can i correct it
For Java:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, 1);
} else {
// else for if they have already given permission
}
}
You can check this tutorial also: https://www.androidhive.info/2016/11/android-working-marshmallow-m-runtime-permissions/
For Kotlin:
val permission = ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_PHONE_STATE)
if (permission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 1)
}
You can check this tutorial also: https://www.techotopia.com/index.php/Kotlin_-_Making_Runtime_Permission_Requests_in_Android
public static String getImei(TelephonyManager tm) {
String imei;
try{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
imei = tm.getDeviceId(0);
}else{
imei = tm.getDeviceId();
}
}catch(SecurityException e){
imei = "";
}
return imei;
}

Android: asking for Run Time permissions runs first permission request but skips others

If I ask for several permissions at one time on Android, run time permissions works great and asks the user for all the permissions I am requesting. That is if I do them all in one call.
If I instead choose to separate run time permission requests into groups, so that I first request access to contacts, then afterwards request access to SMS, my program will ignore the request to SMS and will ultimately treat the SMS request as rejected. Why is this? does the program proceed through code while waiting for the user to respond? How can I keep my permission requests separate and still be able to request permissions right after each other?
The reason why I don't want to do all permissions at once is because I only want ask for permissions when I need them. That is why I have separated permissions into groups.
Any help is greatly appreciated!
EDIT:
Sample code: checkPermissions is called
public boolean checkPermissions(int permissionsToCheck)
{
// Use constants above to specify permissions check to do
if (Build.VERSION.SDK_INT < 23) {
//Do not need to check the permission
return true;
} else {
switch (permissionsToCheck) {
case PERMISSIONS_FOR_MESSAGING:
return ( checkAndRequestContactPermissions() && checkAndRequestSMSPermissions() );
case PERMISSIONS_FOR_BLUETOOTH:
return checkAndRequestBluetoothPermissions();
default:
return false;
}
}
}
Calls checkAndRequestContactPermissions() and checkAndRequestSMSPermissions()
private boolean checkAndRequestContactPermissions() {
int permissionReadContacts = ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_CONTACTS);
int permissionWriteContacts = ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_CONTACTS);
List<String> listPermissionsNeeded = new ArrayList<>();
if (permissionReadContacts != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_CONTACTS);
}
if (permissionWriteContacts != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_CONTACTS);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(mActivity, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), MY_PERMISSIONS_REQUEST_CONTACTS);
return false;
}
return true;
}
private boolean checkAndRequestSMSPermissions() {
int permissionReadSMS = ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_SMS);
int permissionSendSMS = ContextCompat.checkSelfPermission(mContext, Manifest.permission.SEND_SMS);
List<String> listPermissionsNeeded = new ArrayList<>();
if (permissionReadSMS != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.SEND_SMS);
}
if (permissionSendSMS != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_SMS);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(mActivity, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), MY_PERMISSIONS_REQUEST_SMS);
return false;
}
return true;
}
I try to check if I have permissions to Contacts and SMS but it only requests permission to Contacts instead of both.

Is there a way to get all permission granted to an application [duplicate]

I want to get all granted permissions. I know I can get all requested permissions by packageinfo.requestedPermissions but I want to know list of granted permissions and granted permissions can be lesser then requested in case of android M. So I just wanted to know that is there way that I can get list of all granted permissions?
I know from list of requested permission I can check for that permission weather granted or not but I want to know list of all granted permission. Don't want to check for every requested permission.
A simple function that returns all the permissions that have been requested and granted for a given package could look like this:
List<String> getGrantedPermissions(final String appPackage) {
List<String> granted = new ArrayList<String>();
try {
PackageInfo pi = getPackageManager().getPackageInfo(appPackage, PackageManager.GET_PERMISSIONS);
for (int i = 0; i < pi.requestedPermissions.length; i++) {
if ((pi.requestedPermissionsFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
granted.add(pi.requestedPermissions[i]);
}
}
} catch (Exception e) {
}
return granted;
}
Note that this requires API level 16 or above, but that should hopefully not be an issue these days.
You can check permission one by one and add to list:
// Should we show an explanation?
List<String> listPermissionsNeeded = new ArrayList<>();
// No explanation needed, we can request the permission.
if((ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED))
{
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if((ContextCompat.checkSelfPermission(context,
Manifest.permission.GET_ACCOUNTS)
!= PackageManager.PERMISSION_GRANTED))
{
listPermissionsNeeded.add(Manifest.permission.GET_ACCOUNTS);
}
if((ContextCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED))
{
listPermissionsNeeded.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if((ContextCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED))
{
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if((ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED))
{
listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(context,
listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),
MY_PERMISSIONS_REQUEST_MULTIPLE_PERMISSION);
}

ContextCompat.checkSelfPermission(Context, Manifest.permission.CAMERA) alway return granted

I use Android API lvl 23 in my application. When I check Camera permission, the ContextCompat.checkSelfPermission always return 0 (== PackageManager.PERMISSION_GRANTED)
I managed to change it from ContextCompat to ActivityCompat.
Here is my code:
public static boolean verify(Activity activity, final String[] PERMISSIONS, final int PERMISSIONS_REQUEST_ID) {
if (underAPI23())
return true;
String[] denyPermission = new String[PERMISSIONS.length];
int denyPermissionLength = 0;
boolean shouldShowRequest = false;
for (int i = 0; i < PERMISSIONS.length; i++) {
int check = ContextCompat.checkSelfPermission(activity, PERMISSIONS[i]);
LogUtils.e(TAG, PERMISSIONS[i] + ": " + (check != PackageManager.PERMISSION_GRANTED));
// ===== ===== =====
// This always return true. :'(
// ===== ===== =====
if (check != PackageManager.PERMISSION_GRANTED) {
denyPermission[denyPermissionLength++] = PERMISSIONS[i];
if (shouldShowRequest == false) {
boolean should = ActivityCompat.shouldShowRequestPermissionRationale(activity, PERMISSIONS[i]);
if (should)
shouldShowRequest = true;
}
}
}
if (denyPermissionLength > 0) {
if (shouldShowRequest) {
ActivityCompat.requestPermissions(activity, denyPermission, PERMISSIONS_REQUEST_ID);
} else {
ActivityCompat.requestPermissions(activity, denyPermission, PERMISSIONS_REQUEST_ID);
}
return false;
} else {
return true;
}
}
My dependencies in Gradle build
dependencies {
//...
compile 'com.android.support:support-v4:23.2.0'
compile 'com.android.support:appcompat-v7:23.2.0'
//...
}
Updated: Permission call
if (PermissionGrant.verify(getActivity(), new String[]{Manifest.permission.CAMERA}, GRANT_TAKE_PHOTO)) {
// Do my jobs
}
Your permission should be Manifest.permission.<Android permission>
What is your Android target version? shouldShowRequestPermissionRationale always return false that mean ContextCompat.checkSelfPermission(activity, permission) always return false at Android API lvl under 23 too.
Document here. Please focus on:
Note: If the user turned down the permission request in the past and chose the Don't ask again option in the permission request system dialog, this method returns false. The method also returns false if a device policy prohibits the app from having that permission.

Categories

Resources