J'essaie d'écrire du code pour envoyer un SMS à partir d'une application Android, mais lorsque j'essaie d'envoyer le SMS, il me renvoie l'erreur:
09-17 18:37:29.974 12847-12847/**.**.****E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: **.**.****, PID: 12847
Java.lang.SecurityException: Sending SMS message: uid 10092 does not have Android.permission.SEND_SMS.
at Android.os.Parcel.readException(Parcel.Java:1599)
at Android.os.Parcel.readException(Parcel.Java:1552)
at com.Android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.Java:768)
at Android.telephony.SmsManager.sendTextMessageInternal(SmsManager.Java:310)
at Android.telephony.SmsManager.sendTextMessage(SmsManager.Java:293)
at **.**.****.MainActivity$3.onClick(MainActivity.Java:70)
at Android.view.View.performClick(View.Java:5198)
at Android.view.View$PerformClick.run(View.Java:21147)
at Android.os.Handler.handleCallback(Handler.Java:739)
at Android.os.Handler.dispatchMessage(Handler.Java:95)
at Android.os.Looper.loop(Looper.Java:148)
at Android.app.ActivityThread.main(ActivityThread.Java:5417)
at Java.lang.reflect.Method.invoke(Native Method)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:726)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:616)
J'ai vérifié mais j'ai les autorisations dans le manifeste, comme suit:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission Android:name="Android.permission.SEND_SMS"/>
<uses-feature Android:name="Android.hardware.telephony"
Android:required="true"/>
<application
Android:exported="true"
Android:allowBackup="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:theme="@style/AppTheme">
<activity
Android:name=".MainActivity"
Android:label="@string/app_name"
Android:screenOrientation="portrait">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
J'ai cherché sur Internet mais toutes les erreurs concernaient la syntaxe <uses-permission/>
, pourriez-vous m'aider s'il vous plaît?
(Ce qui suit est extrait de un de mes articles de blog à ce sujet )
La principale raison pour laquelle vous n’avez pas obtenu votre permission aujourd’hui est que Votre projet a un targetSdkVersion
égal ou supérieur à 23, et que l’autorisation que vous demandez est "dangereuse". Dans Android 6.0, cela inclut:
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ADD_VOICEMAIL
BODY_SENSORS
CALL_PHONE
CAMERA
GET_ACCOUNTS
PROCESS_OUTGOING_CALLS
READ_CALENDAR
READ_CALL_LOG
READ_CELL_BROADCASTS
READ_CONTACTS
READ_EXTERNAL_STORAGE
READ_PHONE_STATE
READ_SMS
RECEIVE_MMS
RECEIVE_SMS
RECEIVE_WAP_Push
RECORD_AUDIO
SEND_SMS
USE_SIP
WRITE_CALENDAR
WRITE_CALL_LOG
WRITE_CONTACTS
WRITE_EXTERNAL_STORAGE
Pour ces autorisations, non seulement votre application targetSdkVersion
23+ Doit disposer du ou des éléments <uses-permission>
, mais vous devez également demander ces autorisations à l'exécution à l'utilisateur sur les appareils Android 6.0 + , en utilisant des méthodes telles que checkSelfPermission()
et requestPermissions()
.
Pour résoudre temporairement ce problème, déposez votre targetSdkVersion
sous 23.
Cependant, vous aurez éventuellement une raison de vouloir que votre targetSdkVersion
soit de 23 ans ou plus. À ce moment-là, vous devrez.pour ajuster votre application afin qu’elle utilise le nouveau système de permission d’exécution . La documentation Android contient une page dédiée à ce sujet .
Au-dessus du niveau 23 de l'API, vous recevrez par programme de manière pragmatique, comme:
private static final int PERMISSION_REQUEST_CODE = 1;
if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.SEND_SMS)
== PackageManager.PERMISSION_DENIED) {
Log.d("permission", "permission denied to SEND_SMS - requesting it");
String[] permissions = {Manifest.permission.SEND_SMS};
requestPermissions(permissions, PERMISSION_REQUEST_CODE);
}
}
demander l'autorisation de manière pragmatique (après l'API 23)
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Ask for permision
ActivityCompat.requestPermissions(this,new String[] { Manifest.permission.SEND_SMS}, 1);
}
else {
// Permission has already been granted
}
"Si l'application dispose de l'autorisation, la méthode checkSelfPermission () renvoie PERMISSION_GRANTED et l'application peut poursuivre l'opération.
Si l'application ne dispose pas de l'autorisation, la méthode retourne PERMISSION_DENIED, et l'application doit explicitement demander à l'utilisateur l'autorisation. Vous devez demander à l'utilisateur cette autorisation, comme indiqué dans le code ci-dessus. L'appel de requestPermissions () ouvre une boîte de dialogue Android standard, que vous ne pouvez pas personnaliser. "
Si vous utilisez sdk 23 ou supérieur, vous devez vérifier les autorisations d'exécution.
lorsque vous déclarez permisson
dans Manifest
et que ce n'est pas le travail que vous effectuez, vous exécutez la tâche dans Marshmallow
et pour Marshmallow
vous avez défini Permisson à RunTime
.
comme ça
ActivityCompat.requestPermissions();
Veuillez suivre le lien ci-dessous, https://developer.Android.com/guide/topics/permissions/overview.html
Quelques exemples y sont également disponibles pour commencer à utiliser les autorisations.
Pour rendre Android plus sûr maintenant, les développeurs doivent mentionner l’autorisation dans manifest et ils doivent également demander à l’utilisateur au moment de l’exécution du travail. Ce sont des autorisations classées dans la section des autorisations dangereuses mentionnées ci-dessous.
CALENDRIER
READ_CALENDAR
WRITE_CALENDAR
CAM&EACUTE;RA
CAMERA
CONTACTS
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
EMPLACEMENT
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE
RECORD_AUDIO
T&EACUTE;L&EACUTE;PHONE
READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS (must request at runtime)
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
ANSWER_PHONE_CALLS
CAPTEURS
BODY_SENSORS
SMS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_Push
RECEIVE_MMS
ESPACE DE RANGEMENT
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
J'ai ajouté ceci à mon MainActivity, cela résout mon problème
int MY_PERMISSIONS_REQUEST_READ_CONTACTS=0;
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
Si vous utilisez la version Android "23" ou "23+", l'application vous montrera les erreurs lorsque vous essayez d'accéder à tout ce qui nécessite l'autorisation de l'utilisateur. Vous devez demander des autorisations au moment de l'exécution même si vous avez déclaré ces autorisations dans le manifeste Android.
Vérifiez ceci: https://developer.Android.com/training/permissions/requesting.html
Mais si vous avez créé toute votre application et que vous ne voulez pas changer à chaque endroit, une petite astuce suffira.
Allez dans le fichier "Build.gradle" et remplacez la version cible par Sdk par 23, comme 22, 21.
Avec la réponse de CommonsWare,
Il existe un paramètre de sécurité (j'ai coché la case CM13) pour définir la limite de message SMS. Si vous définissez cette option sur "Aucun", le système d'exploitation affichera une boîte de dialogue pour chaque SMS, même après avoir obtenu l'autorisation SMS_SEND du runtime. La meilleure chose à faire est de régler ceci au maximum.
Si le maximum n'est pas suffisant, il existe des moyens d'augmenter le débit maximum sur un périphérique enraciné.
Je devais donc créer une application pour envoyer et recevoir des messages, mais l'action d'envoi se bloquait à chaque fois que je cliquais sur envoyer, même si l'autorisation était accordée. J'avais demandé des autorisations d'exécution et je les avais autorisées, mais j'ai quand même rencontré un blocage que le processus ne dispose pas de l'autorisation demandée pour envoyer SMS. J'ai vérifié les autorisations accordées de:
adb Shell dumpsys package <package-name>
L'ordre de ma demande de permission était
J'ai inversé l'ordre de demande et cela fonctionne bien. Cela a été testé avec une nouvelle application complète (désinstaller-> installer -> tester). La réponse peut sembler étrange mais donnez-lui un coup de feu.
(Si cela fonctionne de la manière indiquée dans un certain ordre, alors Android pourrait avoir un bug !!)
Vous pouvez utiliser ce code pour accéder à vos messages
Ouvrez une boîte de dialogue en utilisant le code ci-dessous:
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
1);
Obtenez le résultat de l'activité comme ci-dessous:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
ou éditez le fichier build.gradle
et le numéro de variable targetSdkVersion
inférieur à 23
Et plus besoin du code ci-dessus
REMARQUE
Bien sûr, ce n'est pas le cas, et c'est juste un aspect éducatif
J'espère que la solution pour écrire sur un stockage externe sera également utile
public boolean checkPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Timber.tag(LOG_TAG).e("Permission error. You have permission");
return true;
} else {
Timber.tag(LOG_TAG).e("Permission error. You have asked for permission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else {
// for a stuff below api level 23
Timber.tag(LOG_TAG).e("Permission error. You already have the permission");
return true;
}
}