Android应用权限未正确询问

时间:2018-04-14 05:48:07

标签: android

public class EEmployeeApplication extends Application {
public void onCreate() {
    super.onCreate();
    try {
        mContext = getApplicationContext();
        dbHandler = new DataBaseModule(this);

        dbHandler.getReadableDatabase();
        dbHandler.close();

        dbHandler = getDbHandler();

        curUser = dbHandler.getActiveUserInfo();

        eEMPSharedPreference = new eEmployeeSharedPreference();
        DataSyncStartAlarm newAlarm = new DataSyncStartAlarm();
        newAlarm.startDataSyncAlarm(mContext, null);

    } catch (Exception e) {
        Log.d("eEmp/Application ", e.toString());
    }
}
@Override
public void onTerminate() {
    try {
    } catch (Exception e) {
        Log.d("eEmp/Application ", e.toString());
    }
    super.onTerminate();
}

public static boolean isNetAvailable() {
    try {
        ConnectivityManager connectivity = (ConnectivityManager)
                mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        {
            NetworkInfo netInfo = connectivity.getActiveNetworkInfo();
            if (netInfo != null) {
                NetworkInfo[] info = connectivity.getAllNetworkInfo();
                if ((info == null) || (!netInfo.isConnectedOrConnecting())) {
                    return false;
                } else {
                    return true;
                }
            }
        }
        return false;
    } catch (Exception e) {
        Log.d("eEmp/Application", e.toString());
        return false;
    }
}

public DataBaseModule getDbHandler() {
    return dbHandler;
}

public void checkUserAvailability(Activity activity) {

    try {
        if (curUser == null)  // No Employee registered in local DB
        {
            activity.finish();
            Intent loginScreen = new Intent(mContext, Login_Activity.class);
            loginScreen.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            loginScreen.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(loginScreen);
        } else {
            activity.finish();
            List<EmpZonesResponseDTO> empZonesResponseDTOS ;
            empZonesResponseDTOS = eEMPSharedPreference.getZones(mContext);
            if (empZonesResponseDTOS == null){
                Intent dashboardAct = new Intent(mContext, Login_Activity.class);
                dashboardAct.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                dashboardAct.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(dashboardAct);
            }else {
                Intent dashboardAct = new Intent(mContext, NavigationActivity.class);
                dashboardAct.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                dashboardAct.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(dashboardAct);
            }

        }
    } catch (Exception except) {
        Log.d("eEmp/LoginActivity", except.toString());
    }
}

public static Context getContext() {
    return mContext;
}

public void SyncMasterData(NavigationActivity NavActivity) {
    try{

        if (isNetAvailable()) {

            Log.d("eEmp/LoginCheck", "Internet is available");
            SyncMasterDataDownloadTask SyncTask = new SyncMasterDataDownloadTask();
            SyncTask.setContextandActivity(this,NavActivity);
            SyncTask.execute();
        } else   
        {
            Log.d("eEmp/SyncMasterData", "Internet is not available");

            NavActivity.DismissMasterDataDownload();
            Snackbar
                    .make(NavActivity.navigationView,
                            "No Internet connection, Unable to Sync Account", Snackbar.LENGTH_LONG)
                    .show();
        }

    }catch (Exception e){
        e.printStackTrace();
    }
}

public String getActivityFragmentTag(EmpConstants.WorkType aSelectedWorkType) {
    String selectedTag;
    switch (aSelectedWorkType) {
        case Dashboard:
            selectedTag = EmpConstants.DashBoard_Info_Tag;
            break;
        case Profile:
            selectedTag = EmpConstants.Personal_Info_Tag;
            break;
        case Entry:
            selectedTag = EmpConstants.Entry_Info_Tag;
            break;
        case Plan:
            selectedTag = EmpConstants.Plan_Info_Tag;
            break;
        case Report:
            selectedTag = EmpConstants.Report_Info_Tag;
            break;
        case QR:
            selectedTag = EmpConstants.QR_Info_Tag;
            break;
        case Miscellaneous:
            selectedTag = EmpConstants.Miscellaneous_Info_Tag;
            break;
        case Nothing:
            selectedTag = "";
            break;
        default:
            selectedTag = "";
            break;
    }
    return selectedTag;
}

// Location Method
public GpsLocationListener getGpsLocationListener() {
    try {
        if (gpsLocationListener == null) {
            gpsLocationListener = new GpsLocationListener();
            gpsLocationListener.getGPSCordinates();
            //Log.d("eEmp/getGPSLocationList","Location Listener Created");
        }
    } catch (Exception gpsLocationExp) {
        Log.d("eEmp/getGPSLocationList", "Error raised due to " + gpsLocationExp.toString());
    }
    return gpsLocationListener;
}


public String getEmpImageDirPath() {
    try {
        return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString()
                + EmpConstants.appDir;
    } catch (Exception e) {
        Log.d("eEmp/ImgDir", e.toString());
        return "";
    }

}

public String getEmpThumbImageDirPath() {
    try {
        return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString()
                + EmpConstants.thumbnailDir;
    } catch (Exception e) {
        Log.d("eEmp/ThumbImgDir", e.toString());
        return "";
    }
}
public Bitmap loadFromFile(String filename) {
    try {
        File f = new File(filename);
        if (!f.exists()) {
            return null;
        }

        final int width = EmpConstants.DisplayWidth;//mDisplay.widthPixels;
        final int height = EmpConstants.DisplayHeight;//mDisplay.heightPixels;
        Bitmap tmp = decodeSampledBitmapFromResource(filename, width, height);
        return tmp;
    } catch (Exception e) {
        return null;
    }
}
public static Bitmap decodeSampledBitmapFromResource(String imgFile,
                                                     int reqWidth, int reqHeight) {

    try {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imgFile, options);

        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);


        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(imgFile, options);
    } catch (Exception sampleBitmapConvExp) {
        Log.d("eEmp/sampleBMPConv", "Error raised due to " + sampleBitmapConvExp.toString());
        return null;
    }
}
public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}


public void checkImageDirectories() {
    try {
        File eEmpPhotosDir = new File(getEmpImageDirPath());
        if (!eEmpPhotosDir.exists()) {
            eEmpPhotosDir.mkdir();
        }

        File eEmpThumbPhotosDir = new File(getEmpThumbImageDirPath());

        if (!eEmpThumbPhotosDir.exists())
            eEmpThumbPhotosDir.mkdir();
    } catch (Exception e) {
        Log.d("eEmp/CheckDir", e.toString());
    }
}

public void showFullImage(Context context, String curImgFile) {
    try {

        if (curImgFile.length() != 0) {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);

            final Dialog nagDialog = new Dialog(context, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
            nagDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            nagDialog.setCancelable(false);
            nagDialog.setContentView(R.layout.preview_image);
            Button btnClose = (Button) nagDialog.findViewById(R.id.btnIvClose);
            ImageView ivPreview = (ImageView) nagDialog.findViewById(R.id.iv_preview_image);
            TextView tvLoading = (TextView) nagDialog.findViewById(R.id.tvImgLoading);
            ivPreview.setTag(tvLoading);
            ImageRequest imgOrgReq = new ImageRequest();
            imgOrgReq.imgView = ivPreview;
            imgOrgReq.ImgType = EmpConstants.ImageLoadingType.OriginalImage;
            imgOrgReq.context = (EEmployeeApplication) mContext;
            BitmapWorkerTask statusImg = new BitmapWorkerTask(imgOrgReq);
            statusImg.execute(curImgFile);

            btnClose.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View arg0) {

                    nagDialog.dismiss();
                }
            });
            nagDialog.show();
        }
    } catch (Exception e) {
        Log.d("eEmp/ShowFullImg", e.getLocalizedMessage());
    }
}

// delete selected image from external storage
public void deleteSelImgFromStorage(String imgPath, Context context) {
    try {
        File imgFile = new File(imgPath);
        if (imgPath.contains(EmpConstants.appName)) {
            if (imgFile.exists()) {
                imgFile.delete();
            }
            MediaScannerConnection.scanFile(context, new String[]{imgPath}, null,
                    new MediaScannerConnection.OnScanCompletedListener() {
                        public void onScanCompleted(String path, Uri uri) {

                        }
                    });
        }
    } catch (Exception e) {
        Log.i("Delete image", e.toString());
    }
}
// For Marshmallow
// To Check permissions for Marshmallow
public List<String> askPermissions(ArrayList<EmpConstants.PermissionsList> ReqPermnsList) {
    List<String> permissionsNeeded = new ArrayList<String>();
    for (EmpConstants.PermissionsList perm : ReqPermnsList) {
        switch (perm) {
            case PhonePerm:
                if (addPermission(Manifest.permission.READ_PHONE_STATE))
                    permissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
                break;
            case External_StoragePerm:
                if (addPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE))
                    permissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
                if (addPermission(Manifest.permission.READ_EXTERNAL_STORAGE))
                    permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
                break;
            case LocationPerm:
                if (addPermission(Manifest.permission.ACCESS_COARSE_LOCATION))
                    permissionsNeeded.add(Manifest.permission.ACCESS_COARSE_LOCATION);
                if (addPermission(Manifest.permission.ACCESS_FINE_LOCATION))
                    permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
                break;
            case CameraPerm:
                if (addPermission(Manifest.permission.CAMERA))
                    permissionsNeeded.add(Manifest.permission.CAMERA);
                break;
        }
    }
    return permissionsNeeded;
}

public boolean addPermission(String permission) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
            return true;
        }
    }
    return false;
}
public boolean isAnyPermissionRequired(ArrayList<EmpConstants.PermissionsList> ReqPermnsList) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        try {
            if (ReqPermnsList.size() == 0) {
                return false;
            } else {

                for (EmpConstants.PermissionsList perm : ReqPermnsList) {
                    switch (perm) {
                        case PhonePerm:
                            if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED) {
                                return true;
                            }
                            break;
                        case External_StoragePerm:
                            if ((checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED)
                                    || (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED)) {
                                return true;
                            }
                            break;
                        case LocationPerm:
                            if ((checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_DENIED)
                                    || (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED)) {
                                return true;
                            }
                            break;
                        case CameraPerm:
                            if ((checkSelfPermission(Manifest.permission.CAMERA)== PackageManager.PERMISSION_DENIED)){
                                return true;
                            }
                            break;
                        default:
                            return false;
                    }
                }
                return false;
            }
        } catch (Exception checkPermExpt) {
            Log.d("eEmp/CheckPerms", "Exception due to " + checkPermExpt.toString());
        }
    }
    return false;
}

public void getNetworkProvideLocation() {
    try {

        if (longitude_Value == 0 || latitude_Value == 0) {
            LocationManager locationManager = (LocationManager) EEmployeeApplication.getContext().getSystemService(Context.LOCATION_SERVICE);
            boolean isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            if (isNetworkEnable) {
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }
                Location lastLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (lastLocation != null) {
                    longitude_Value = lastLocation.getLongitude();
                    latitude_Value = lastLocation.getLatitude();
                    Log.d("eEmp/getNwValues", "Network Coordinates Updated" );
                }
            } else {
                return;
            }
        }

    } catch (Exception networkLocExp) {
        Log.d("eEmp/getNwValues", "Exception due to " + networkLocExp.toString());
    }
public int isValidUser() {
    try {
        if (isNetAvailable()) {
            HTTPCommunication loginHTTPRequest;
            EEmployeeHTTPResponse result;
            if (curUser != null) {
                Log.d("eEmp/ValLogin", "Validating User in Background");
                loginHTTPRequest = new HTTPCommunication();
                EmployeeInfoDTO loginInfo = new EmployeeInfoDTO();
                loginHTTPRequest.setRequestType(EmpConstants.HTTPRequestType.NewUser);

                loginInfo.EMPID = curUser.getEMPID();
                loginInfo.Password = curUser.getPassword();
                result = loginHTTPRequest.SendHTTPRequest(loginInfo);

                if (result != null) {
                    if (result.HTTPStatusCode == 200) {
                        if (result.Data != null) {
                            return result.Data.ResponseCode;
                        }
                    }
                }
            }
        }
        return 0; // Invalid User
    } catch (Exception e) {
        Log.d("eEmp/ValLoginError", e.toString());
        return 0;
    }
}

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}
}

LaunchingActivity.java

public class LaunchingActivity extends Activity implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, OnTaskStateChange {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try {
        setContentView(R.layout.activity_launching);
        context = (EEmployeeApplication) EEmployeeApplication.getContext();

        if (EEmployeeApplication.isNetAvailable()){

            // Read IMEI Number
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

                ArrayList<EmpConstants.PermissionsList> reqPermissionsList = new ArrayList<>();
                if ((context.eEMPSharedPreference != null) && (context.eEMPSharedPreference.getIMEI().isEmpty())) {
                    reqPermissionsList.add(EmpConstants.PermissionsList.PhonePerm);
                }
                reqPermissionsList.add(EmpConstants.PermissionsList.External_StoragePerm);
                reqPermissionsList.add(EmpConstants.PermissionsList.LocationPerm);
                reqPermissionsList.add(EmpConstants.PermissionsList.CameraPerm);

                // Check All Permissions
                if (context.isAnyPermissionRequired(reqPermissionsList)) {
                    requestPermission(context.askPermissions(reqPermissionsList));
                } else {
                    readIMEINumber();
                }

            } else {
                readIMEINumber();
            }


            int x = BuildConfig.VERSION_CODE;
            AppVersionTask mTask = new AppVersionTask();
            mTask.setListener(this);


            APPVERREQ aRequest = new APPVERREQ();
            aRequest.requestType = EmpConstants.HTTPRequestType.App_Ver;

            APP_VERSION loginInfo = new APP_VERSION();
            loginInfo.APP_VER = BuildConfig.VERSION_NAME;
            aRequest.RequestObj = loginInfo;
            mTask.execute(aRequest);
        }

        try {
            Log.d("eEmp/Test", "MasterdataTaskStarted");
            MasterDataLoadTask masterDataLoadTask = new MasterDataLoadTask();
            masterDataLoadTask.setContextandActivity(context, this);
            masterDataLoadTask.execute();


        } catch (Exception MasterDataExcept) {
            Log.d("eEmp/MstrDataTask", "Exception Occurred due to " + MasterDataExcept.toString());
            context.checkUserAvailability(this);
        }


        Log.d("eEmp/LaunchCreate", "Launching Created");
    } catch (Exception e) {
        Log.d("eEmp/LaunchActvty", e.toString());
    }
}

@Override
protected void onStart() {
    super.onStart();
    if ((mGoogleApiClient != null) && (!mGoogleApiClient.isConnected())) {
        mGoogleApiClient.connect();
    }
    Log.d("eEMP/LaunchOnStart", "Launch OnStart");

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    return super.onOptionsItemSelected(item);
}

// For Marshmallow
// To Check permissions for Marshmallow
public void requestPermission(List<String> permissionsNeeded) {
    if (permissionsNeeded.size() > 0) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(permissionsNeeded.toArray(new String[permissionsNeeded.size()]),
                    EmpConstants.REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
        }
    }
}


@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    readIMEINumber();
}


// The callback for the management of the user settings regarding location
private ResultCallback<LocationSettingsResult> mResultCallbackFromSettings = new ResultCallback<LocationSettingsResult>() {
    @Override
    public void onResult(LocationSettingsResult result) {
        final Status status = result.getStatus();

        switch (status.getStatusCode()) {
            case LocationSettingsStatusCodes.SUCCESS:

                // GPS is already in On State
                initiateLocationRequest();

                break;
            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                try {

                    status.startResolutionForResult(
                            LaunchingActivity.this,
                            REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException e) {
                    // Ignore the error.
                }
                break;

            default:
                context.checkUserAvailability(LaunchingActivity.this);

                Log.e("eEmp/Location", "Settings change unavailable. We have no way to fix the settings so we won't show the dialog.");
                break;
        }
    }
};


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    try {

        switch (requestCode) {
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:

                        if (mGoogleApiClient.isConnected()) {
                            initiateLocationRequest();
                        }
                        break;
                    case Activity.RESULT_CANCELED:

                        context.checkUserAvailability(this);
                        break;
                    default:
                        break;
                }
                break;
        }
    } catch (Exception expt) {
        Log.d("eEmp/AcvtResult", "Exception occurred due to " + expt.toString());
    }
}
public void readIMEINumber() {
    try {
        if ((context.eEMPSharedPreference != null) && (context.eEMPSharedPreference.getIMEI().isEmpty())) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

                if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
                    TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                    context.eEMPSharedPreference.setIMEI(telephonyManager.getDeviceId());
                }
            } else {
                TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                context.eEMPSharedPreference.setIMEI(telephonyManager.getDeviceId());
            }
}
if (!checkGPSStatus()) {
            LocationRequest mLocationRequest = LocationRequest.create();
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            if (checkPlayServices()) {

                LocationSettingsRequest.Builder locationSettingsRequestBuilder = new LocationSettingsRequest.Builder()
                        .addLocationRequest(mLocationRequest);

                locationSettingsRequestBuilder.setAlwaysShow(true);

                PendingResult<LocationSettingsResult> result =
                        LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, locationSettingsRequestBuilder.build());
                result.setResultCallback(mResultCallbackFromSettings);

            } else {

                context.checkUserAvailability(this);
            }
        } else {

            initiateLocationRequest();
        }

    } catch (Exception IMEIExp) {
        Log.d("eEmp/IMEIGet", "Unable to get IMEI number due to " + IMEIExp.toString());
    }
}
private boolean checkGPSStatus() {
    try {
        locationManager = (LocationManager) EEmployeeApplication.getContext().getSystemService(Context.LOCATION_SERVICE);

        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            return true;
        } else {
            return false;
        }
    } catch (Exception chkGPSExpt) {
        Log.d("eEmp/chkGPS", " Exception Raised due to  " + chkGPSExpt.toString());
        return false;
    }
}


@Override
protected void onDestroy() {
    Log.d("eEmp/Launching", "onDestroy Called");
    super.onDestroy();
}

@Override
public void onTaskStateChange(EmpConstants.TaskState State, String Msg, EEmployeeHTTPResponse result) {
    switch (State){
        case RequestStarted:
            break;
        case ResponseRecvd:
            break;
        case ResponseProcessing:
            break;
        case ResponseProcessed:
            if (result != null) {
                if (result.HTTPStatusCode == 200) {
                    if (result.Data != null) {
                            APP_VERSION_RESPONSE aResponse = (APP_VERSION_RESPONSE) result.Data.ActionResult;
                            if (aResponse!= null){
                                if (aResponse.APP_VER.equals(BuildConfig.VERSION_NAME)){
                                    try{
                                        System.out.print("Yes");
                                    }catch (Exception e){
                                        Log.d("/eEmp","/Excp due to"+e.toString());
                                    }

                                }
                            }
                    }
                }
            }
    }
}
}

在我的Android应用程序中,我要求启动应用程序的权限。 实际上我想要的是在启动应用程序之后,应该询问权限并接受用户输入,无论是接受还是拒绝,然后才应该移动到登录页面。

但是在启动之后,它被要求获得权限并且它不等待用户输入意味着权限对话框正在打开,并且在5到10秒后登录页面打开,即使用户没有响应权限对话框。

为什么会这样?

任何帮助都将不胜感激。

declared permissions in manifest file

1 个答案:

答案 0 :(得分:0)

您假设android框架应该处理权限处理过程并且应该继续加载UI组件,直到用户与权限交互为止是错误的。您需要自己处理与用户的权限交互。 以下是您的流程:

  1. 请用户许可。
  2. 等待用户与对话框进行交互。
  3. 阅读交互响应并评估是否授予了权限。
  4. 如果授予了权限,请加载UI组件。
  5. 换句话说,您需要确保执行任何需要权限的操作,直到权限实际存在。