Дождитесь разрешения пользователя

Я создаю приложение, которое отбирает GPS при запуске. Как вы, вероятно, знаете, разрешения запрашиваются во время выполнения с Android M и выше.

Итак, в моем случае я начинаю с проверки наличия разрешений, например:

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

Но Android продолжает запускать код и запрашивать данные GPS (= сбой, потому что пользователь не принял запрос на разрешение).

Я нахожу много решений о ожидании ввода пользователем (например, используя DialogInterface.OnClickListener , link , но в этом случае он не может быть реализован, потому что я не создаю диалог).

Итог, вопрос: как я могу подождать ответа пользователя в диалоговом окне разрешения Android?

Вы можете обрабатывать метод отмены ответа пользователя

 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 

От вашей деятельности.

Android продолжает работать с кодом и запрашивает данные GPS (= сбой, поскольку пользователь не принял запрос на разрешение).

Как и многие другие вещи в Android, requestPermissions() является асинхронным. Пользователь пока не получил запрос на получение разрешений к моменту возвращения этого метода.

Как я могу подождать ответа пользователя в диалоговом окне разрешения Android?

Вы этого не делаете.

Если вы обнаружите, что у вас уже есть разрешение, вы выполняете свою работу. Если вы обнаружите, что вам нужно запросить разрешение, вы задерживаете выполнение этой работы, пока не получите разрешение, в onRequestPermissionsResult() .

Я работал так:

1- Создал Boolean помощник для проверки разрешений:

 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- Создал экран Splash как:

 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- Создал OnRequestPermissionsResult как OnRequestPermissionsResult ниже:

 @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- Определите экран Splash как Launcher в AndroidManifest.xml как:

 <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> Размер <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- В styles.xml определяется SplashTheme как:

 <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar"> <item name="android:windowBackground">@drawable/Splash</item> </style> 

6- @drawable/Splash.xmls :

 <?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> - <?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- В values/colors.xmls цвет lightgray был определен следующим образом:

 <?xml version="1.0" encoding="utf-8"?> <resources> <color name="lightgray">#D3D3D3</color> </resources> 
Intereting Posts