Android runtime permission is GRANTED but still denied
Asked Answered
M

5

8

I'm trying to write an app that sends SMS. When checking if I have the required permissions it returns true but still crashes with SecurityException.

When button is pressed

private void startAutoMsg() {
    Log.d("Starting Auto Msg");
    //FIXME: Start proper loop
    if (canSendSms()) {
        sendMessage();
        mAutoMsgButton.setBackgroundColor(Color.GREEN);
    }
}

I'm using the below function to determine if I have the proper permission

private boolean canSendSms() {
    if ((ContextCompat.checkSelfPermission(mContext, Manifest.permission.SEND_SMS)
            == PackageManager.PERMISSION_GRANTED)) {
        Log.d("Permission granted");
        return true;
    } else {
        Log.d("Permission denied");
        ActivityCompat.requestPermissions(
                mActivity, new String[]{Manifest.permission.SEND_SMS}, 101);
        return false;
    }
}

The above code returns true and therefore SMS is trying to be sent with this

private void sendMessage() {
    Log.d("sending message");
    PendingIntent sentPI = PendingIntent.getBroadcast(
            mContext, 0, new Intent(Constants.ACTION_SMS_SENT), 0);
    PendingIntent deliveredPI = PendingIntent.getBroadcast(
            mContext, 0, new Intent(Constants.ACTION_SMS_DELIVERED), 0);
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            mSmsManager.sendTextMessage("mNumber", null, mText, sentPI, deliveredPI);
        }
    });
    thread.run();
}

In my manifest:

<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" />

Log from crash

D/SmsApp: TelephonyFragment: canSendSms(533): Permission granted
D/SmsApp: TelephonyFragment: sendMessage(222): sending message
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.android.phone, PID: 16736
                  java.lang.SecurityException: Sending SMS message: uid 1001 does not have android.permission.SEND_SMS.
                      at android.app.ContextImpl.enforce(ContextImpl.java:1727)
                      at android.app.ContextImpl.enforceCallingPermission(ContextImpl.java:1749)
                      at android.content.ContextWrapper.enforceCallingPermission(ContextWrapper.java:750)
                      at android.content.ContextWrapper.enforceCallingPermission(ContextWrapper.java:750)
                      at com.android.internal.telephony.IccSmsInterfaceManager.sendText(IccSmsInterfaceManager.java:410)
                      at com.android.internal.telephony.UiccSmsController.sendTextForSubscriber(UiccSmsController.java:136)
                      at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:366)
                      at android.telephony.SmsManager.sendTextMessage(SmsManager.java:349)
                      at com.rawinc.smsapp.ui.telephony.TelephonyFragment$2.run(TelephonyFragment.java:230)
                      at java.lang.Thread.run(Thread.java:764)
                      at com.rawinc.smsapp.ui.telephony.TelephonyFragment.sendMessage(TelephonyFragment.java:233)
                      at com.rawinc.smsapp.ui.telephony.TelephonyFragment.startAutoMsg(TelephonyFragment.java:517)
                      at com.rawinc.smsapp.ui.telephony.TelephonyFragment.toggleAutoMsg(TelephonyFragment.java:507)
                      at com.rawinc.smsapp.ui.telephony.TelephonyFragment.lambda$-com_rawinc_smsapp_ui_telephony_TelephonyFragment_11555(TelephonyFragment.java:359)
                      at com.rawinc.smsapp.ui.telephony.-$Lambda$uKVldJdEkN_fZa3QWm3EZHDa2r8$2.$m$0(Unknown Source:4)
                      at com.rawinc.smsapp.ui.telephony.-$Lambda$uKVldJdEkN_fZa3QWm3EZHDa2r8$2.onClick(Unknown Source:0)
                      at android.view.View.performClick(View.java:6178)
                      at android.view.View$PerformClick.run(View.java:24416)
                      at android.os.Handler.handleCallback(Handler.java:769)
                      at android.os.Handler.dispatchMessage(Handler.java:98)
                      at android.os.Looper.loop(Looper.java:255)
                      at android.app.ActivityThread.main(ActivityThread.java:6555)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Megavolt answered 27/6, 2017 at 9:38 Comment(8)
which android version?Tannenwald
Did you mentioned it in manifest as well. Just cross check onceFavin
Target version is API 26 but im testing on 25 as of now. The permissions are in the manifest.Megavolt
Are you by chance using a Samsung? I'm coming across a similar problem on a Samsung device but for a different permission. Turns out PermissionChecker and ContextCompat selfCheckPermission return different results (Denied vs. Granted)Komarek
This was on a Sony device. But thanks for the tip, I will look into it.Megavolt
Did you find a solution to this?Futtock
No I did not unfortunately.Megavolt
I have the same problem with a POCO deviceChaschase
C
1

Please Do This :

Create This Class in your App:

import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;


public abstract class RuntimePermissionsActivity extends AppCompatActivity
{


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
    {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        int permissionCheck = PackageManager.PERMISSION_GRANTED;
        for (int permission : grantResults)
        {
            permissionCheck = permissionCheck + permission;
        }
        if ((grantResults.length > 0) && permissionCheck == PackageManager.PERMISSION_GRANTED)
        {
            onPermissionsGranted(requestCode);
        }
        else
        {
            onPermissionsDeny(requestCode);
        }
    }

    public void requestAppPermissions(final String[] requestedPermissions, final int requestCode)
    {
        int permissionCheck = PackageManager.PERMISSION_GRANTED;
        boolean shouldShowRequestPermissionRationale = false;
        for (String permission : requestedPermissions)
        {
            permissionCheck = permissionCheck + ContextCompat.checkSelfPermission(this, permission);
            shouldShowRequestPermissionRationale = shouldShowRequestPermissionRationale || ActivityCompat.shouldShowRequestPermissionRationale(this, permission);
        }
        if (permissionCheck != PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(this, requestedPermissions, requestCode);
        }
        else
        {
            onPermissionsGranted(requestCode);
        }
    }

    public abstract void onPermissionsGranted(int requestCode);
    public abstract void onPermissionsDeny(int requestCode);

}

Next in your MainActivity (or any Activity) You Shoulde extends From This Class like This :

public class Main_Activity extends RuntimePermissionsActivity

And Overrite This Method in your Activity :

@Override
public void onPermissionsGranted(int requestCode) {

}

@Override
public void onPermissionsDeny(int requestCode) {

}

In Final : Use this Code To Check Permmision :

MainActivity.super.requestAppPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestcodeWriteStorage);

Also you can Check many Permission and you shoulde define in String Array ;

requestcodeWriteStorage is a int you should define it ;

Manage your Callback with 2 method that i read .

for example :

@Override
public void onPermissionsGranted(int requestCode) {
    if (requestCode == requestcodeWriteStorage){
        Toast.makeText(this,"Done",Toast.LENGTH_LONG).show();

    }
Cordite answered 27/6, 2017 at 9:54 Comment(0)
S
0

You need to handle onRequestPermissionResult

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
            Log.v("======>","Permission: "+permissions[0]+ "was "+grantResults[0]);
            //your task
        }
    }

and check for version

if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(android.Manifest.permission.SEND_SMS)
                    == PackageManager.PERMISSION_GRANTED) {
                Log.v("======>","Permission is granted");
                return true;
            } else {

                Log.v("======>","Permission is revoked");
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS}, 1);
                return false;
            }
        }
        else { //permission is automatically granted on sdk<23 upon installation
            Log.v("======>","Permission is granted");
            return true;
        }

and to send message use

private void sendMessage() {
        try {
            SmsManager smsManager = SmsManager.getDefault();
            smsManager.sendTextMessage(number, null, "TXt", null, null);
            Toast.makeText(getApplicationContext(), "Message Sent",
                    Toast.LENGTH_LONG).show();
        } catch (Exception ex) {
            Toast.makeText(getApplicationContext(),ex.getMessage().toString(),
                    Toast.LENGTH_LONG).show();
            ex.printStackTrace();
        }
    }
Schreck answered 27/6, 2017 at 9:44 Comment(11)
Thank you for your reply. The problem is that the line checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED will return true even thou I do NOT have the permission.Megavolt
Instead of READ_EXTERNA‌​L_STORAGE replace with SEND_SMSSchreck
I understood what you meant and used SEND_SMS anyway :) As seen in my original post I'm already doing this check in canSendSms() but the check gives me a false positive and that is my problem.Megavolt
Use my code to check permission and see and it will ask permission for only one timeSchreck
It prints Log.v("======>","Permission is granted"); in the log and then crashesMegavolt
Us this function for send sms i have tested its workingSchreck
private void sendMessage() { try { SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage(number, null, "TXt", null, null); Toast.makeText(getApplicationContext(), "Message Sent", Toast.LENGTH_LONG).show(); } catch (Exception ex) { Toast.makeText(getApplicationContext(),ex.getMessage().toString(), Toast.LENGTH_LONG).show(); ex.printStackTrace(); } }Schreck
That is the function I'm usingMegavolt
This is not same function which you are using I have tested in my device its working i think its problem with your device. first replace with this function and check ur device also i case problem occurs we can got to chatSchreck
I tested your function and it shows a toast "Sending SMS message: uid 1001 does not have android.permission.SEND_SMS.Megavolt
Can u add your full classSchreck
L
0

Check permission when need location

if ((ContextCompat.checkSelfPermission(LoginActivity.this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED)) {
            requestPermissions(new String[]{Manifest.permission.SEND_SMS},
                    101);
        }

This lines adds ur activity

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case PERMISSIONS_CODE:
                if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                break;
        }
    }
Lepidolite answered 27/6, 2017 at 9:49 Comment(7)
The problem is not handeling the permission. The problem is that the API is telling me I have it when I dont.Megavolt
ur permission not getted go and check settings---> choose ur app---> permissionLepidolite
given above condition and onRequestPermissionsResult add ur actitvity after check itLepidolite
Are u check it ur app permissionsLepidolite
6.0 after more permission doesn't get from manifest so added programattically.Lepidolite
Settings -> Apps -> SmsApp -> Permissions: No Permissions requested As seen above. The app does not request permission since it thinks it already has.Megavolt
share ur permission inside screenshotLepidolite
F
0

On 5.0 and higher u would have to also grant your app the permission to read sms in settings.

Foundry answered 28/6, 2017 at 12:40 Comment(5)
Settings -> Apps -> SmsApp -> Permissions: No Permissions requested, ScreenshotMegavolt
I don't know what the permissions might look like on different phones but you can use this step to get there. Look for permissions in settings, you'll see a list of different permissions. On clicking any of them you'll see a list of apps current requesting for that permission. Just look for the read sms permission, you should see your app listed and click on it you'd see the allow switch, just switch it on.Foundry
I think I found what you meant. However my app is not even visible under SMS permission, screenshotsMegavolt
try restarting the deviceFoundry
I've tried restarting it. I've tried uninstalling/reinstalling the app. I've reflashing my device and tried on several other devices.Megavolt
I
0

Make sure you have used android Android 6.0 and higher SDK for your app, I had the same issue and I found that I used android 4.1 kitkat sdk, once I change the min sdk level to 21, problem solved

Inestimable answered 23/5, 2018 at 9:9 Comment(1)
Thank you for your comment. My Android devices runs Android 8.0. minSdkVersion version is set to 24 and targetSdkVersion 27.Megavolt

© 2022 - 2024 — McMap. All rights reserved.