com.yanzhenjie.permission.DefaultRequest.java Source code

Java tutorial

Introduction

Here is the source code for com.yanzhenjie.permission.DefaultRequest.java

Source

/*
 * Copyright  Yan Zhenjie. All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.yanzhenjie.permission;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.content.ContextCompat;
import android.util.Log;

import com.yanzhenjie.permission.target.Target;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>Request permission and callback.</p>
 * Created by Yan Zhenjie on 2016/9/9.
 */
class DefaultRequest
        implements Request<RationaleRequest>, RationaleRequest, Rationale, PermissionActivity.PermissionListener {

    private static final String TAG = "AndPermission";

    private Target target;

    private int mRequestCode;
    private String[] mPermissions;
    private Object mCallback;
    private RationaleListener mRationaleListener;

    private String[] mDeniedPermissions;

    DefaultRequest(Target target) {
        if (target == null)
            throw new IllegalArgumentException("The target can not be null.");
        this.target = target;
    }

    @NonNull
    @Override
    public RationaleRequest permission(String... permissions) {
        this.mPermissions = permissions;
        return this;
    }

    @NonNull
    @Override
    public RationaleRequest requestCode(int requestCode) {
        this.mRequestCode = requestCode;
        return this;
    }

    @Override
    public RationaleRequest callback(Object callback) {
        this.mCallback = callback;
        return this;
    }

    @NonNull
    @Override
    public RationaleRequest rationale(RationaleListener listener) {
        this.mRationaleListener = listener;
        return this;
    }

    @Deprecated
    @Override
    public void send() {
        start();
    }

    @Override
    public void start() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            callbackSucceed();
        } else {
            mDeniedPermissions = getDeniedPermissions(target.getContext(), mPermissions);
            // Denied mPermissions size > 0.
            if (mDeniedPermissions.length > 0) {
                // Remind users of the purpose of mPermissions.
                boolean showRationale = target.shouldShowRationalePermissions(mDeniedPermissions);
                if (showRationale && mRationaleListener != null)
                    mRationaleListener.showRequestPermissionRationale(mRequestCode, this);
                else
                    resume();
            } else { // All permission granted.
                callbackSucceed();
            }
        }
    }

    private static String[] getDeniedPermissions(Context context, @NonNull String... permissions) {
        List<String> deniedList = new ArrayList<>(1);
        for (String permission : permissions)
            if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED)
                deniedList.add(permission);
        return deniedList.toArray(new String[deniedList.size()]);
    }

    @Override
    public void cancel() {
        int[] results = new int[mPermissions.length];
        for (int i = 0; i < mPermissions.length; i++)
            results[i] = ContextCompat.checkSelfPermission(target.getContext(), mPermissions[i]);
        onRequestPermissionsResult(mPermissions, results);
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void resume() {
        PermissionActivity.setPermissionListener(this);
        Intent intent = new Intent(target.getContext(), PermissionActivity.class);
        intent.putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, mDeniedPermissions);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        target.startActivity(intent);
    }

    @Override
    public void onRequestPermissionsResult(@NonNull String[] permissions, @NonNull int[] grantResults) {
        List<String> deniedList = new ArrayList<>();
        for (int i = 0; i < permissions.length; i++)
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED)
                deniedList.add(permissions[i]);

        if (deniedList.isEmpty())
            callbackSucceed();
        else
            callbackFailed(deniedList);
    }

    private void callbackSucceed() {
        if (mCallback != null) {
            if (mCallback instanceof PermissionListener)
                ((PermissionListener) mCallback).onSucceed(mRequestCode, Arrays.asList(mPermissions));
            else {
                callbackAnnotation(mCallback, mRequestCode, PermissionYes.class, Arrays.asList(mPermissions));
            }
        }
    }

    private void callbackFailed(List<String> deniedList) {
        if (mCallback != null) {
            if (mCallback instanceof PermissionListener)
                ((PermissionListener) mCallback).onFailed(mRequestCode, deniedList);
            else {
                callbackAnnotation(mCallback, mRequestCode, PermissionNo.class, deniedList);
            }
        }
    }

    private static void callbackAnnotation(Object callback, int requestCode,
            Class<? extends Annotation> annotationClass, List<String> permissions) {
        Method[] methods = findMethodForRequestCode(callback.getClass(), annotationClass, requestCode);
        if (methods.length == 0)
            Log.e(TAG, "Do you forget @PermissionYes or @PermissionNo for callback method ?");
        else
            try {
                for (Method method : methods) {
                    if (!method.isAccessible())
                        method.setAccessible(true);
                    method.invoke(callback, permissions);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

    private static Method[] findMethodForRequestCode(@NonNull Class<?> source,
            @NonNull Class<? extends Annotation> annotation, int requestCode) {
        List<Method> methods = new ArrayList<>(1);
        for (Method method : source.getDeclaredMethods())
            if (method.getAnnotation(annotation) != null)
                if (isSameRequestCode(method, annotation, requestCode))
                    methods.add(method);
        return methods.toArray(new Method[methods.size()]);
    }

    private static boolean isSameRequestCode(@NonNull Method method,
            @NonNull Class<? extends Annotation> annotation, int requestCode) {
        if (PermissionYes.class.equals(annotation))
            return method.getAnnotation(PermissionYes.class).value() == requestCode;
        else if (PermissionNo.class.equals(annotation))
            return method.getAnnotation(PermissionNo.class).value() == requestCode;
        return false;
    }
}