ThelmaJay ThelmaJay - 4 months ago 45
Android Question

Android Widget - Read_SMS permission denied API 23

I am new to android.

What I intent to do is to get the nr of sms that are currently inside the device sms inbox.
I want this number to appear inside a text view.

I know from other posts that the permission mechanism changed in API 23.
But in all those posts we have an activity.
In my case I don't have an activity, I am trying to get the number of sms inside the onUpdate method of a AppWidgetProvider.

On my Manifest file I added the permission for READ_SMS.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=""
**<uses-permission android:name="android.permission.READ_SMS"/>**
<receiver android:name=".smsGtw">
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />

android:resource="@xml/sms_gtw_info" />

Then On my Widget Java Class

package com.globa8track.smsgtw;

import android.Manifest;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.widget.RemoteViews;

import java.util.ArrayList;

public class smsGtw extends AppWidgetProvider {

void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {

ArrayList<String> inboxSms;
int nrSmsInInbox = 0;

inboxSms = fetchInbox(context);
nrSmsInInbox = inboxSms.size();

CharSequence widgetText = "Gtw Total Sms Received: " + nrSmsInInbox;

// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.sms_gtw);
views.setTextViewText(, widgetText);

// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);

public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created

public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled

public static ArrayList<String> fetchInbox(Context context){

ArrayList<String> sms=new ArrayList<String>();

Uri uriSms=Uri.parse("content://sms/inbox");

ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(uriSms, new String[]{"_id", "address", "date", "body"}, null, null, null);


String address=cursor.getString(1);
String body=cursor.getString(3);

sms.add("Address=>"+address+"\n Sms=>"+body);

return sms;


When I run this code on Android Studio emulator (Nexus 5 API 23) I get the
following error:

Process: com.globa8track.smsgtw, PID: 5397 java.lang.RuntimeException: Unable to start receiver com.globa8track.smsgtw.smsGtw: java.lang.SecurityException: Permission Denial: reading uri content://sms/inbox from pid=5397, uid=10057 requires android.permission.READ_SMS, or grantUriPermission()

From the post : Why does Android ignore READ_SMS permission?

I understood that it is needed to ask first permission, then check for that permission. As @Tomáš Navara said. But in his case there is an activity.

Do I have to have an activity too? I don't want user interaction, neither a user interface for checking the amount of sms stored in the inbox.

Another thing, could you help me get started in the android widget world?
Where should I start?
Could you provide me some pointers/resources?
Thank you all for your patience.


So I have to create an activity SMSRead that is called by the widgets onUpdate() through an intent?

No. Your existing code is fine (presumably) for getting the messages and updating the app widget. If it works on older devices, and if it works on Android 6.0 if you manually grant the permission via your app's screen in Settings, then that stuff is fine.

Where you need an activity is to be able to request the READ_SMS permission from the user.

So, in your app widget code, you will need to call ContextCompat.checkSelfPermission() to see if you have READ_SMS access or not. If you do have access, go ahead and update your app widget. If you do not, raise a Notification to let the user know that you need them to grant you permission. Ideally, that Notification would be tied to an activity of yours, where you can then use ActivityCompat.requestPermissions() to request READ_SMS.

You could also arrange to have that activity be your app widget configuration activity, which is started automatically when your app widget is added to the user's home screen. This allows you to request the permission right away. However, you will still need to call checkSelfPermission() in the AppWidgetProvider, as the user could revoke the permission via the Settings app.