Błąd związany z uprawnieniami do odczytu wiadomości SMS

0

Witam,
Małe pytanie.
Zbudowałem sobie na dostępnym przykładzie kodu aplikację, która ma czytać sms-y z telefonu (tak aplikacja jest pod telefon z androidem).
Przykład procedury czytającej pochodzi z tej strony https://delphi-android.blogspot.com/2013/10/how-to-fetch-sms-messages-from-android.html.

I pomimo, że mam w android-manifest.xml poszczególne uprawnienia:

<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.SEND_MMS" />

to mi ciągle tłucze komunikatem:

Project sms_test.apk raised exception class EJNIException with message 'java.lang.SecurityException: Permission Denial: reading com.android.providers.telephony.SmsProvider uri content://sms/inbox from pid=15982, uid=10381 requires android.permission.READ_SMS, or grantUriPermission()'.
  function TfSms.FetchSms:string;
 var cursor: JCursor;
     uri: Jnet_Uri;
     address,person,msgdatesent,protocol,msgread,msgstatus,msgtype, msgreplypathpresent,subject,body, servicecenter,locked:string;
     msgunixtimestampms:int64;
     addressidx,personidx,msgdateidx,msgdatesentidx,protocolidx,msgreadidx,
     msgstatusidx,msgtypeidx,msgreplypathpresentidx,subjectidx,bodyidx,
     servicecenteridx,lockedidx:integer;
 begin
   uri:=StrToJURI('content://sms/inbox');
   cursor := TAndroidHelper.Activity.getContentResolver.query(uri, nil, nil,nil,nil);   // <--- miejsce wyjątku...
   addressidx:=cursor.getColumnIndex(StringToJstring('address'));
   personidx:=cursor.getColumnIndex(StringToJstring('person'));
   msgdateidx:=cursor.getColumnIndex(StringToJstring('date'));
   msgdatesentidx:=cursor.getColumnIndex(StringToJstring('date_sent'));
   protocolidx:=cursor.getColumnIndex(StringToJstring('protocol'));
   msgreadidx:=cursor.getColumnIndex(StringToJstring('read'));
   msgstatusidx:=cursor.getColumnIndex(StringToJstring('status'));
   msgtypeidx:=cursor.getColumnIndex(StringToJstring('type'));
   msgreplypathpresentidx:=cursor.getColumnIndex(StringToJstring('reply_path_present'));
   subjectidx:=cursor.getColumnIndex(StringToJstring('subject'));
   bodyidx:=cursor.getColumnIndex(StringToJstring('body'));
   servicecenteridx:=cursor.getColumnIndex(StringToJstring('service_center'));
   lockedidx:=cursor.getColumnIndex(StringToJstring('locked'));
   while (cursor.moveToNext) do begin
     address:=JStringToString(cursor.getString(addressidx));
     person:=JStringToString(cursor.getString(personidx));
     msgunixtimestampms:=cursor.getLong(msgdateidx);
     msgdatesent:=JStringToString(cursor.getString(msgdatesentidx));
     protocol:=JStringToString(cursor.getString(protocolidx));
     msgread:=JStringToString(cursor.getString(msgreadidx));
     msgstatus:=JStringToString(cursor.getString(msgstatusidx));
     msgtype:=JStringToString(cursor.getString(msgtypeidx));
     msgreplypathpresent:=JStringToString(cursor.getString(msgreplypathpresentidx));
     subject:=JStringToString(cursor.getString(subjectidx));
     body:=JStringToString(cursor.getString(bodyidx));
     servicecenter:=JStringToString(cursor.getString(servicecenteridx));
     locked:=JStringToString(cursor.getString(lockedidx));
     Result:=IntToStr(trunc(msgunixtimestampms/1000))+' '+address+' '+body;
   end;
 end;

i nie wiem co robię źle ?

Może jakieś sugestie ?

0

Jaka wersja Delphi i jaka wersja Androida?

0

W sieci piszą, że mimo uprawnień w apce, to i tak trzeba ustawić uprawnienia w systemie Android:
Ustawienia > Aplikacje > Uprawnienia > SMS

0

@Andrzej Boczko:
Przykład na który się powołujesz jest z 2013 roku i peanie działał na Androidzie z tamtych czasów, może to była wersja 6 . O tego czasu pojawiło się kilka nowych wersji Androida. Każda nowa wersja ma coraz bardziej restrykcyjne zabezpieczenia. Jutro sprawdzę Twój kod na wersji 11.
Jaka jest Twoja wersja Androida ?

0
grzegorz_so napisał(a):

@Andrzej Boczko:
Przykład na który się powołujesz jest z 2013 roku i peanie działał na Androidzie z tamtych czasów, może to była wersja 6 . O tego czasu pojawiło się kilka nowych wersji Androida. Każda nowa wersja ma coraz bardziej restrykcyjne zabezpieczenia. Jutro sprawdzę Twój kod na wersji 11.
Jaka jest Twoja wersja Androida ?

dla Aleksandrii 11.3 jest dostępny Android SDK w wersji 25.2.5 jeżeli mnie pamięć nie myli...

0

dla Aleksandrii 11.3 jest dostępny Android SDK w wersji 25.2.5 jeżeli mnie pamięć nie myli...

SDK i wersja Delphi są mało ważne. Wystarczy że są kompatybilne z wersją Androida. Problem jest w zabezpieczeniach Andrioida,

0

spróbuj tego rozwiązania...

PermissionsService.RequestPermissions([JStringToString(TJManifest_permission.JavaClass.READ_SMS)],
    procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>)
    begin
      if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then
         ShowMessage('Read permission  granted ')
      else
      begin
        ShowMessage('Read permission not granted');
      end;
    end);

w podobny sposób nadałem mojej aplikacji uprawnienia do odczytu historii połączeń

PermissionsService.RequestPermissions([JStringToString(TJManifest_permission.JavaClass.READ_CALL_LOG)],
    .......
    end);
0

Od bardzo już dawna nie wystarczy podać uprawnień w manifeście, trzeba jeszcze spytać użytkownika o pozwolenie i wtedy dopiero uprawnienie zostanie przyznane (lub nie). Nie dotyczy to wszystkich uprawnień, ale tego akurat tak.
Alternatywnie, po zainstalowaniu aplikacji możesz wejść w informacje o aplikacji i włączyć to sam, wtedy obejdzie się bez pytania ale nie muszę chyba tłumaczyć że to nie może być docelowe rozwiązanie.

SDK i wersja Delphi są mało ważne. Wystarczy że są kompatybilne z wersją Androida. Problem jest w zabezpieczeniach Andrioida,

Przeciwnie, jak skomplilujesz ze starym target sdk to będzie działać bez promptu (tak jak na starych Androidach), tyle że przy instalacji i uruchamianiu aplikacji dostaniesz info że aplikacja jest przestarzała no i oczywiście Google nie wpuści takiej aplikacji do sklepu

1 użytkowników online, w tym zalogowanych: 0, gości: 1