Vue.js実戦——Android Hybird App開発の権限設定_11


一、目標
Html 5コードがAndroidエンジニアリングに移植された後、Android App開発の基本フレームワークの権限設定部分のコード設計と開発を完了する.
二、手順
1、AndroidManifest.xmlでは、本プロジェクトで使用する権限のように、使用する権限を定義します.
    
    
    
    
    
    
    
    

2、配置後、コードの中で権限があるかどうかをチェックする必要があります.コアコードは以下の通りです.
                int resultPermission = ContextCompat.checkSelfPermission(activity, permission);

この戻り値はPackageManagerです.PERMISSION_GRANTEDでは、権限が付与されていることを示します.そうしないと、次のステップで権限を申請する必要があります.
3、申請権限コアコード:
ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)

注意:shouldShowRequestPermissionRationaleは非同期の方法で、1つの申請許可の弾窓を呼び出すことを担当しています.このような権限の弾窓を同時に複数申請すると、最初の弾窓だけがポップアップされ、後ろの弾窓は直接スキップされます.
4、授権結果を取得するには、要求権限の要求コードに基づいて、MainActivityのonRequestPermissionsResultコールバックメソッドで処理する必要がある.
5、上記のステップ3に基づいて、複数回のポップアップウィンドウがスキップされたため、ステップ3の申請権限方法を呼び出し、すべての権限申請が完了するまで次の権限項目を申請し続ける必要がある.
6、上記のロジックに基づいて、コアコードロジックをまとめる(完全コードはgithubを参照):
MainActivityのアクセス権に関するコード:
package com.justinsoft.activity;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.justinsoft.R;
import com.justinsoft.constant.Constant;
import com.justinsoft.permission.PermissionMgr;
import com.justinsoft.util.LogUtil;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class MainActivity extends AppCompatActivity {
    //     
    private static final String TAG = LogUtil.getClassTag(MainActivity.class);

    private BtWebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 1.      
        loadPermission(this);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        Log.i(TAG, "update permission now.");
        PermissionMgr permissionMgr = PermissionMgr.getInstance();
        permissionMgr.updatePermission(this, requestCode, permissions, grantResults);
        if (permissionMgr.hasRequestAllPermission()) {
            refreshHomepage();
        }
    }

    /**
     *            
     *
     * @param activity
     */
    private void loadPermission(Activity activity) {
        Map> allPermission = new HashMap>();

        Set locationPermission = new HashSet();
        locationPermission.add(Manifest.permission.ACCESS_FINE_LOCATION);
        locationPermission.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        allPermission.put(Constant.LOCATION_PERMISSION_CODE, locationPermission);

        Set audioPermission = new HashSet();
        audioPermission.add(Manifest.permission.RECORD_AUDIO);
        allPermission.put(Constant.RECORD_PERMISSION_CODE, audioPermission);

        Set cameraPermission = new HashSet();
        cameraPermission.add(Manifest.permission.CAMERA);
        allPermission.put(Constant.CAMERA_PERMISSION_CODE, cameraPermission);

        Set storagePermission = new HashSet();
        storagePermission.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        storagePermission.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        allPermission.put(Constant.STORAGE_PERMISSION_CODE, storagePermission);

        PermissionMgr.getInstance().requestPermission(activity, allPermission);
    }
}

抽出された権限管理クラスPermissionMgr:
package com.justinsoft.permission;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.justinsoft.util.LogUtil;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;

public final class PermissionMgr
{
    //     
    private static final String TAG = LogUtil.getClassTag(PermissionMgr.class);
    
    //     
    private static PermissionMgr permissionMgr;
    
    private static final Lock LOCK = new ReentrantLock();
    
    private Set requestedPermissionCode;
    
    private Set grantPermissionCode;
    
    private Map> allPermission;
    
    private PermissionMgr()
    {
        requestedPermissionCode = new HashSet();
        grantPermissionCode = new HashSet();
    }
    
    public static PermissionMgr getInstance()
    {
        if (null == permissionMgr)
        {
            LOCK.tryLock();
            try
            {
                if (null == permissionMgr)
                {
                    permissionMgr = new PermissionMgr();
                }
                return permissionMgr;
            }
            catch (Exception e)
            {
                Log.e(TAG, "failed to get permission", e);
            }
            finally
            {
                LOCK.unlock();
            }
        }
        return permissionMgr;
    }
    
    /**
     *     
     *
     * @param activity
     * @param allPermission
     */
    public void requestPermission(Activity activity, Map> allPermission)
    {
        this.allPermission = allPermission;
        requestLeftPermission(activity, allPermission);
    }
    
    /**
     *          ,       
     *
     * @param activity
     * @param requestCode
     * @param permissions
     * @param grantResults
     * @return
     */
    public void updatePermission(Activity activity, int requestCode, String permissions[], int[] grantResults)
    {
        Log.i(TAG, "request permission code:" + requestCode);
        Log.i(TAG, "all permission code:" + allPermission.keySet());
        Log.i(TAG, "all permission:" + permissions);
        if (!allPermission.keySet().contains(requestCode))
        {
            Log.i(TAG, "invalid permission");
            return;
        }
        requestedPermissionCode.add(requestCode);
        
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
        {
            // permission was granted, yay! Do the
            // contacts-related task you need to do.
            Log.i(TAG, "grant permission now:" + requestCode);
            grantPermissionCode.add(requestCode);
        }
        else
        {
            // permission denied, boo! Disable the
            // functionality that depends on this permission.
            Log.i(TAG, "no permission now:" + requestCode);
        }
        
        Map> ungrantPermission = new HashMap>();
        ungrantPermission.putAll(allPermission);
        ungrantPermission.keySet().removeAll(requestedPermissionCode);
        Log.i(TAG, "Left permission:" + ungrantPermission.keySet());
        requestLeftPermission(activity, ungrantPermission);
    }
    
    /**
     *             
     *
     * @return
     */
    public boolean hasRequestAllPermission()
    {
        Map> ungrantPermission = new HashMap>();
        ungrantPermission.putAll(allPermission);
        ungrantPermission.keySet().removeAll(requestedPermissionCode);
        return ungrantPermission.isEmpty();
    }
    
    /**
     *       
     * 
     * @param activity
     * @param allPermission
     */
    private void requestLeftPermission(Activity activity, Map> allPermission)
    {
        for (Map.Entry> entry : allPermission.entrySet())
        {
            int grantPermission = -1;
            boolean isLocationPermission = false;
            int requestCode = entry.getKey();
            Set batchPermission = entry.getValue();
            for (String permission : batchPermission)
            {
                int resultPermission = ContextCompat.checkSelfPermission(activity, permission);
                if (resultPermission == PackageManager.PERMISSION_GRANTED)
                {
                    this.requestedPermissionCode.add(requestCode);
                    grantPermission = PackageManager.PERMISSION_GRANTED;
                }
                
                if (permission.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
                    || permission.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION))
                {
                    isLocationPermission = true;
                }
            }
            
            if (grantPermission != PackageManager.PERMISSION_GRANTED)
            {
                boolean result = shouldPermission(activity, batchPermission);
                if (isLocationPermission)
                {
                    List allProvider = getLocationProvider(activity);
                    if (null == allProvider || allProvider.isEmpty())
                    {
                        result = false;
                    }
                }
                if (!result)
                {
                    Log.i(TAG, "It needs to request permission now.");
                    ActivityCompat.requestPermissions(activity, batchPermission.toArray(new String[] {}), requestCode);
                }
                return;
            }
        }
    }
    
    private boolean shouldPermission(Activity activity, Set batchPermission)
    {
        for (String permission : batchPermission)
        {
            if (!this.requestedPermissionCode.contains(permission))
            {
                if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission))
                {
                    Log.i(TAG, "grant permission:" + permission);
                    return true;
                }
            }
        }
        return false;
    }
    
    private List getLocationProvider(Activity activity)
    {
        LocationManager locationManager = (LocationManager)activity.getSystemService(Activity.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        List allProviderName = locationManager.getProviders(criteria, true);
        Log.i(TAG, "provider:" + allProviderName);
        return allProviderName;
    }
}

三、まとめ
権限申請はAndroid開発の基本的な訴えの一つで、開発の過程で、まず頭を全部弾いて窓を申請したが、結局一度弾いただけで弾けなくなったことに気づき、後でActivityでのコールバック方法onRequestPermissionsResultで次の権限を申請し続け、ついに次から次へと弾窓の目標を達成した.
四、参考資料
[1]https://www.cnblogs.com/Free-Thinker/p/6014765.html
 
下一篇:Vue.js実戦——Html 5 AppをAndroid Appに移植_10下一篇:Vue.js実戦——Android Hybird Appを開発するWebviewインフラストラクチャ_12