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)
amoz871
  • 81
  • 1
  • 5

5 Answers5

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

    }
Community
  • 1
  • 1
morteza moradi
  • 165
  • 1
  • 13
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();
        }
    }
Anil
  • 1,605
  • 1
  • 14
  • 24
  • 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. – amoz871 Jun 27 '17 at 09:47
  • Instead of READ_EXTERNA‌​L_STORAGE replace with SEND_SMS – Anil Jun 27 '17 at 09:48
  • 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. – amoz871 Jun 27 '17 at 09:50
  • Use my code to check permission and see and it will ask permission for only one time – Anil Jun 27 '17 at 09:55
  • It prints Log.v("======>","Permission is granted"); in the log and then crashes – amoz871 Jun 27 '17 at 09:59
  • Us this function for send sms i have tested its working – Anil Jun 27 '17 at 10:13
  • 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(); } } – Anil Jun 27 '17 at 10:13
  • That is the function I'm using – amoz871 Jun 27 '17 at 10:16
  • 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 chat – Anil Jun 27 '17 at 10:18
  • I tested your function and it shows a toast "Sending SMS message: uid 1001 does not have android.permission.SEND_SMS. – amoz871 Jun 27 '17 at 11:10
  • Can u add your full class – Anil Jun 27 '17 at 11:54
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;
        }
    }
0

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

Joshua
  • 589
  • 1
  • 5
  • 19
  • Settings -> Apps -> SmsApp -> Permissions: No Permissions requested, [Screenshot](http://imgur.com/a/phdyR) – amoz871 Jun 29 '17 at 13:22
  • 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. – Joshua Jul 04 '17 at 11:21
  • I think I found what you meant. However my app is not even visible under SMS permission, [screenshots](http://imgur.com/a/HF9vd) – amoz871 Jul 05 '17 at 12:54
  • try restarting the device – Joshua Jul 07 '17 at 09:51
  • I've tried restarting it. I've tried uninstalling/reinstalling the app. I've reflashing my device and tried on several other devices. – amoz871 Jul 08 '17 at 11:45
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

Roledenez
  • 751
  • 4
  • 16
  • 43
  • Thank you for your comment. My Android devices runs Android 8.0. minSdkVersion version is set to 24 and targetSdkVersion 27. – amoz871 May 24 '18 at 09:17