Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android runtime permission is GRANTED but still denied

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)
like image 493
amoz871 Avatar asked Jun 27 '17 09:06

amoz871


People also ask

How do you check if a permission is already granted Android?

checkSelfPermission(activity, Manifest. permission. X) checks if any permission is already granted, if you check out other answers they do the same, and rest of the code asks for the permissions not granted.

How can I tell if an Android user is denied permission?

Android provides a utility method, shouldShowRequestPermissionRationale() , that returns true if the user has previously denied the request, and returns false if a user has denied a permission and selected the Don't ask again option in the permission request dialog, or if a device policy prohibits the permission.


1 Answers

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();

    }
like image 116
morteza moradi Avatar answered Nov 14 '22 18:11

morteza moradi