Подтвердить что ты не робот

Подождите, пока пользовательское разрешение

Я создаю приложение, которое отбирает 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, , но в этом случае он не может быть реализован, потому что я не создаю диалог).

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

Нет.

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

Ответ 3

Я работал следующим образом:

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, как показано ниже:

@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>

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>

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

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

Ответ 4

После запроса разрешения с помощью цикла while вы можете проверить, предоставляется ли разрешение непрерывно, а если вы предоставили, вы можете изменить значение и выйти из цикла 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));
        }
    }