Je construis une application qui échantillonne le GPS au démarrage de… .. Comme vous le savez probablement, des autorisations sont demandées pendant l'exécution à partir d'Android M et supérieur.
Donc, dans mon cas, je commence par vérifier si des autorisations sont nécessaires, comme ceci:
private void permissionForAndroidM()
{
if (Build.VERSION.SDK_INT > 22) {
String[] allPermissionNeeded = {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO};
List<String> permissionNeeded = new ArrayList<>();
for (String permission : allPermissionNeeded)
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED)
permissionNeeded.add(permission);
if (permissionNeeded.size() > 0) {
requestPermissions(permissionNeeded.toArray(new String[0]), 0);
}
}
}
mais Android continue à exécuter le code et à demander des données GPS (= plantage, car l'utilisateur n'a pas accepté la demande d'autorisation).
Je trouve de nombreuses solutions pour attendre les entrées de l'utilisateur (comme utiliser DialogInterface.OnClickListener
, link , mais cela ne peut pas être mis en œuvre dans ce cas, car je ne crée pas le dialogue).
En bout de ligne, la question: comment puis-je attendre la réponse de l'utilisateur à partir de la boîte de dialogue d'autorisation Android?
Vous pouvez gérer la méthode de substitution de réponse de l'utilisateur
public void onRequestPermissionsResult(
int requestCode,
String[] permissions,
int[] grantResults
)
de votre activité.
Android continue à exécuter le code et à demander des données GPS (= plantage, car l'utilisateur n'a pas accepté la demande d'autorisation).
Comme beaucoup de choses dans Android, requestPermissions()
est asynchrone. L'utilisateur n'a même pas été invité à entrer les autorisations au moment du retour de cette méthode.
Comment puis-je attendre la réponse de l'utilisateur à partir de la boîte de dialogue d'autorisation Android?
Vous pas.
Si vous trouvez que vous avez déjà la permission, vous faites votre travail. Si vous constatez que vous devez demander une autorisation, vous retardez l'exécution de ce travail jusqu'à l'obtention de l'autorisation, dans onRequestPermissionsResult()
.
Je l'ai travaillé de la manière suivante:
1- Création d'un assistant Boolean
pour vérifier les autorisations accordées:
public class UtilPermissions {
public static boolean hasPermissions(Context context, String... allPermissionNeeded)
{
if (Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& context != null && allPermissionNeeded != null)
for (String permission : allPermissionNeeded)
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED)
return false;
return true;
}
}
2- Créer un écran Splash
en tant que:
public class Splash extends Activity {
private static final int PERMISSION_ALL = 0;
private Handler h;
private Runnable r;
/*
SharedPreferences mPrefs;
final String settingScreenShownPref = "settingScreenShown";
final String versionCheckedPref = "versionChecked";
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
h = new Handler();
r = new Runnable() {
@Override
public void run() {
Toast.makeText(Splash.this, "Runnable started", Toast.LENGTH_SHORT).show();
/* // (OPTIONAL) these lines to check if the `First run` ativity is required
int versionCode = BuildConfig.VERSION_CODE;
String versionName = BuildConfig.VERSION_NAME;
mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = mPrefs.edit();
Boolean settingScreenShown = mPrefs.getBoolean(settingScreenShownPref, false);
int savedVersionCode = mPrefs.getInt(versionCheckedPref, 1);
if (!settingScreenShown || savedVersionCode != versionCode) {
startActivity(new Intent(Splash.this, FirstRun.class));
editor.putBoolean(settingScreenShownPref, true);
editor.putInt(versionCheckedPref, versionCode);
editor.commit();
}
else
*/
startActivity(new Intent(Splash.this, MainActivity.class));
finish();
}
};
String[] PERMISSIONS = {
READ_PHONE_STATE,
MODIFY_AUDIO_SETTINGS,
ACCESS_FINE_LOCATION,
READ_SMS
};
if(!UtilPermissions.hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
else
h.postDelayed(r, 1500);
}
// Put the below OnRequestPermissionsResult code here
}
3- Créé la OnRequestPermissionsResult
comme ci-dessous:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
int index = 0;
Map<String, Integer> PermissionsMap = new HashMap<String, Integer>();
for (String permission : permissions){
PermissionsMap.put(permission, grantResults[index]);
index++;
}
if((PermissionsMap.get(ACCESS_FINE_LOCATION) != 0)
|| PermissionsMap.get(READ_SMS) != 0){
Toast.makeText(this, "Location and SMS permissions are a must", Toast.LENGTH_SHORT).show();
finish();
}
else
{
h.postDelayed(r, 1500);
}
}
4- Défini l'écran Splash
comme Launcher
dans le AndroidManifest.xml
comme:
<activity
Android:name=".MainActivity"
Android:label="@string/app_name"
Android:theme="@style/AppTheme.NoActionBar">
</activity>
<activity
Android:name=".Splash"
Android:configChanges="orientation|keyboardHidden|screenSize"
Android:theme="@style/SplashTheme">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
5- Dans le styles.xml
défini la SplashTheme
comme:
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="Android:windowBackground">@drawable/Splash</item>
</style>
6- Le @drawable/Splash.xmls
est:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item
Android:drawable="@color/lightgray"/>
<item>
<bitmap
Android:gravity="center"
Android:src="@mipmap/ic_launcher"/>
</item>
</layer-list>
7- Dans le values/colors.xmls
, la couleur lightgray
avait été définie comme suit:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="lightgray">#D3D3D3</color>
</resources>
Après avoir demandé une autorisation, avec une boucle while, vous pouvez vérifier si l'autorisation est accordée de manière continue. Si cette autorisation est accordée, vous pouvez modifier la valeur et quitter la boucle while.
Boolean isAnswered = true;
while(isAnswered){
if (ActivityCompat.checkSelfPermission(getApplication(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplication(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.d("isanswered", String.valueOf(isAnswered));
}
else{
isAnswered = false;
Log.d("isanswered", String.valueOf(isAnswered));
}
}