0

我是android新手。Android Widget - Read_SMS權限被拒絕API 23

我故意做的是讓當前在設備的短信收件箱裏面的短信NR。 我希望此編號出現在文本視圖內。

我從其他職位的權限機制在API 23 改變知道,但是在所有這些文章中,我們還有一個活動。 在我的情況下,我沒有一個活動,我試圖獲得一個AppWidgetProvider的onUpdate方法內的短數。

在我的清單文件我增加了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 Studio中模擬器此代碼( 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?

我理解,這需要先詢問權限,然後檢查該權限。正如@TomášNavara所說的。但在他的情況下,有一個活動。

我也必須有活動嗎?我不希望用戶交互,也不需要用戶界面來檢查存儲在收件箱中的短信數量。

另一件事,你可以幫我在Android窗口小部件開始的世界? 我應該從哪裏開始? 你能提供一些指針/資源嗎? 謝謝大家的耐心等待。

+1

「我還必須有活動嗎?」 - 是的。 – CommonsWare

+0

@ @CommonsWare。所以我必須通過意圖創建一個由小部件onUpdate()調用的活動SMSRead?我如何獲得打印在小部件文本視圖上的結果? – 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

你也能安排這種活動是你的應用程序窗口小部件配置活動,當您的應用程序widget被添加到用戶的主屏幕,其會自動啓動。這使您可以立即請求權限。但是,您仍然需要撥打AppWidgetProvider中的checkSelfPermission(),因爲用戶可以通過設置應用撤消權限。

+0

謝謝@CommonsWare。我添加了一個主要活動到我的小部件並添加了'checkSelfPermission'和'requestPermissions'。我現在可以在我的小部件上獲得收到的短信數量。這[鏈接](https://guides.codepath.com/android/Understanding-App-Permissions)幫助我瞭解瞭如何申請許可。 – ThelmaJay