Wait for user permission

陌路散爱 提交于 2019-11-29 01:14:55
Valentin Yuryev

You can handle user response overriding method

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

from your activity.

Android continuing running the code and asking for GPS data ( = crash, because the user didn't accept the permission request).

Like many things in Android, requestPermissions() is asynchronous. The user has not even been prompted for the permissions by the time this method returns.

How can I wait for user answer from the Android permission dialog ?

You don't.

If you find that you already have the permission, you do your work. If you find that you have to request permission, you delay doing that work until you get the permission, in onRequestPermissionsResult().

I worked it the below way:

1- Created a Boolean helper to check permissions granted:

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- Created a Splash screen as:

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- Created the OnRequestPermissionsResult as below:

@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- Defined the Splash screen as Launcher in the AndroidManifest.xml as:

<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- In the styles.xml defined the SplashTheme as:

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

6- The @drawable/Splash.xmls is:

<?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- In the values/colors.xmls the lightgray color had been defined as below:

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

After asking a permission, with a while loop, you can check if the permission is granted continuously , if granted you can change the value and exit while loop.

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));
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!