0

Я новичок в android.Android Widget - разрешено разрешение Read_SMS API 23

Что я намерен сделать, так это получить номер sms, который в настоящее время находится в папке «Входящие» устройства. Я хочу, чтобы этот номер отображался внутри текстового вида.

Я знаю из других сообщений, что механизм разрешения изменился в API 23. Но во всех этих сообщениях у нас есть активность. В моем случае у меня нет активности, я пытаюсь получить количество смс внутри метода onUpdate для AppWidgetProvider.

В моем файле манифеста я добавил разрешение для READ_SMS.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.globa8track.smsgtw">  
    **<uses-permission android:name="android.permission.READ_SMS"/>** 
    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <receiver android:name=".smsGtw"> 
      <intent-filter> 
       <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
      </intent-filter> 

      <meta-data 
       android:name="android.appwidget.provider" 
       android:resource="@xml/sms_gtw_info" /> 
     </receiver>  
    </application> 
</manifest> 

Тогда на мой виджет класса Java smsGtw.java

package com.globa8track.smsgtw; 

import android.Manifest; 
import android.app.DownloadManager; 
import android.appwidget.AppWidgetManager; 
import android.appwidget.AppWidgetProvider; 
import android.content.ContentResolver; 
import android.content.Context; 
import android.content.pm.PackageManager; 
import android.database.Cursor; 
import android.net.Uri; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
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(R.id.appwidget_text, widgetText); 

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

     @Override 
     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); 
      } 
     } 

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

     @Override 
     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); 
      cursor.moveToFirst(); 

      while(cursor.moveToNext()){ 

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

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

      return sms; 
     } 


    } 

Когда я запускаю этот код на Android студии эмулятора (Nexus 5 API 23) Я получаю следующее сообщение об ошибке :

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

От поста: Why does Android ignore READ_SMS permission?

я понял, что нужно спросить первое разрешение, а затем проверить для этого разрешения. Как сказал Томаш Навара. Но в его случае есть деятельность.

Должен ли я иметь деятельность? Я не хочу взаимодействия с пользователем, ни пользовательский интерфейс для проверки количества смс, хранящихся в папке «Входящие».

Другое дело, не могли бы вы помочь мне начать работу в мире виджетов Android? С чего начать? Не могли бы вы предоставить мне несколько указателей/ресурсов? Благодарим всех вас за терпение.

+1

«Должен ли я тоже заниматься деятельностью?» -- да. – CommonsWare

+0

Tk u @CommonsWare. Итак, я должен создать активность SMSRead, которая вызывается виджетами onUpdate() через намерение? И как мне получить результат, напечатанный в текстовом виде виджетов? – ThelmaJay

ответ

1

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

Нет. Ваш существующий код в порядке (предположительно) для получения сообщений и обновления виджета приложения. Если он работает на более старых устройствах, и если он работает на Android 6.0, если вы вручную предоставите разрешение на экране своего приложения в настройках, то это будет хорошо.

Если вам нужна деятельность, вы можете запросить разрешение пользователя READ_SMS.

Итак, в коде виджета приложения вам необходимо позвонить ContextCompat.checkSelfPermission(), чтобы узнать, есть ли у вас READ_SMS доступ или нет. Если у вас есть доступ, продолжайте и обновите виджет приложения. Если вы этого не сделаете, поднимите Notification, чтобы пользователь знал, что вам нужно, чтобы предоставить вам разрешение. В идеале, Notification будет привязан к вашей деятельности, где вы можете использовать ActivityCompat.requestPermissions() для запроса READ_SMS.

Вы также можете договориться о том, что это мероприятие является активностью настройки виджета вашего приложения, которое запускается автоматически, когда виджет приложения добавляется на главный экран пользователя.Это позволяет сразу же запросить разрешение. Однако вам все равно нужно позвонить checkSelfPermission() в AppWidgetProvider, так как пользователь может аннулировать разрешение с помощью приложения «Настройки».

+0

Спасибо @CommonsWare. Я добавил основной вид моего виджета и добавил 'checkSelfPermission' и' requestPermissions'. Теперь я могу получить количество полученных sms на моем виджете. Эта [ссылка] (https://guides.codepath.com/android/Understanding-App-Permissions) помогла мне понять, как запросить разрешение. – ThelmaJay