├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── drawable-hdpi
│ │ │ │ └── card.png
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── values
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── drawable
│ │ │ │ └── shape_btn.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ ├── values-zh
│ │ │ │ └── strings.xml
│ │ │ └── layout
│ │ │ │ └── activity_main.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── me
│ │ │ └── weyye
│ │ │ └── demo
│ │ │ └── MainActivity.java
│ ├── test
│ │ └── java
│ │ │ └── me
│ │ │ └── weyye
│ │ │ └── demo
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── me
│ │ └── weyye
│ │ └── demo
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── library
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── drawable-xxhdpi
│ │ │ │ ├── permission_card1.png
│ │ │ │ ├── permission_ic_sms.png
│ │ │ │ ├── permission_ic_camera.png
│ │ │ │ ├── permission_ic_phone.png
│ │ │ │ ├── permission_ic_sensors.png
│ │ │ │ ├── permission_ic_storage.png
│ │ │ │ ├── permission_ic_calendar.png
│ │ │ │ ├── permission_ic_contacts.png
│ │ │ │ ├── permission_ic_location.png
│ │ │ │ └── permission_ic_micro_phone.png
│ │ │ ├── drawable
│ │ │ │ ├── spacer_30.xml
│ │ │ │ ├── shape_btn_next.xml
│ │ │ │ ├── shape_btn_blue.xml
│ │ │ │ ├── shape_btn_green_light.xml
│ │ │ │ ├── shape_bg_white.xml
│ │ │ │ └── shape_btn_border_white.xml
│ │ │ ├── values
│ │ │ │ ├── arrays.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── attrs.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── anim
│ │ │ │ ├── fade_in.xml
│ │ │ │ ├── fade_out.xml
│ │ │ │ ├── scale_in.xml
│ │ │ │ ├── scale_out.xml
│ │ │ │ ├── modal_out.xml
│ │ │ │ └── modal_in.xml
│ │ │ ├── layout
│ │ │ │ ├── permission_info_item.xml
│ │ │ │ └── dialog_request_permission.xml
│ │ │ └── values-zh
│ │ │ │ └── strings.xml
│ │ ├── java
│ │ │ └── me
│ │ │ │ └── weyye
│ │ │ │ └── hipermission
│ │ │ │ ├── PermissionCallback.java
│ │ │ │ ├── ConstantValue.java
│ │ │ │ ├── PermissionItem.java
│ │ │ │ ├── WrapHeightGridView.java
│ │ │ │ ├── PermissionAdapter.java
│ │ │ │ ├── PermissionView.java
│ │ │ │ ├── HiPermission.java
│ │ │ │ └── PermissionActivity.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── me
│ │ │ └── weyye
│ │ │ └── hipermission
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── me
│ │ └── weyye
│ │ └── hipermission
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── screenshot
├── app-debug.apk
├── 3ceb82af5f.gif
├── 45cd8b0505.gif
├── 6771a424d1.gif
├── screenshot1.gif
├── screenshot2.jpg
└── 20170524135457.jpg
├── .idea
├── copyright
│ └── profiles_settings.xml
├── vcs.xml
├── runConfigurations.xml
├── gradle.xml
├── compiler.xml
├── modules.xml
└── misc.xml
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
├── gradlew.bat
├── gradlew
├── README-CN.md
└── README.md
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':library'
2 |
--------------------------------------------------------------------------------
/screenshot/app-debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/screenshot/app-debug.apk
--------------------------------------------------------------------------------
/screenshot/3ceb82af5f.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/screenshot/3ceb82af5f.gif
--------------------------------------------------------------------------------
/screenshot/45cd8b0505.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/screenshot/45cd8b0505.gif
--------------------------------------------------------------------------------
/screenshot/6771a424d1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/screenshot/6771a424d1.gif
--------------------------------------------------------------------------------
/screenshot/screenshot1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/screenshot/screenshot1.gif
--------------------------------------------------------------------------------
/screenshot/screenshot2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/screenshot/screenshot2.jpg
--------------------------------------------------------------------------------
/screenshot/20170524135457.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/screenshot/20170524135457.jpg
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/app/src/main/res/drawable-hdpi/card.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_card1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_card1.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_ic_sms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_ic_sms.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_ic_camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_ic_camera.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_ic_phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_ic_phone.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_ic_sensors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_ic_sensors.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_ic_storage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_ic_storage.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_ic_calendar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_ic_calendar.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_ic_contacts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_ic_contacts.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_ic_location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_ic_location.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/permission_ic_micro_phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yewei02538/HiPermission/HEAD/library/src/main/res/drawable-xxhdpi/permission_ic_micro_phone.png
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/spacer_30.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/shape_btn_next.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #fffffc
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/shape_btn_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - @string/permission_storage
5 | - @string/permission_location
6 | - @string/permission_camera
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/shape_btn_green_light.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/anim/fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/library/src/main/res/anim/fade_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/library/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #41c236
4 | #ffffff
5 | #44A49C
6 | #ee447AA4
7 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/shape_bg_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/shape_btn_border_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/java/me/weyye/hipermission/PermissionCallback.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by Administrator on 2017/5/10 0010.
7 | */
8 |
9 | public interface PermissionCallback extends Serializable {
10 | void onClose();
11 |
12 | void onFinish();
13 |
14 | void onDeny(String permission, int position);
15 |
16 | void onGuarantee(String permission, int position);
17 | }
18 |
--------------------------------------------------------------------------------
/library/src/main/res/anim/scale_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
11 |
14 |
--------------------------------------------------------------------------------
/app/src/test/java/me/weyye/demo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package me.weyye.demo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/library/src/test/java/me/weyye/hipermission/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/library/src/main/res/anim/scale_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
12 |
15 |
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/library/src/main/java/me/weyye/hipermission/ConstantValue.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | /**
4 | * Created by Administrator on 2017/5/10 0010.
5 | */
6 |
7 | public interface ConstantValue {
8 | String DATA_PERMISSION_TYPE = "data_permission_type";
9 | String DATA_TITLE = "data_title";
10 | String DATA_MSG = "data_msg";
11 | String DATA_FILTER_COLOR = "data_color_filter";
12 | String DATA_STYLE_ID = "data_style_id";
13 | String DATA_ANIM_STYLE = "data_anim_style";
14 | String DATA_PERMISSIONS = "data_permissions";
15 | String DATA_CALLBACK = "data_callback";
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/library/src/main/res/anim/modal_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
13 |
17 |
--------------------------------------------------------------------------------
/library/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\android-sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/library/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\android-sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/library/src/main/java/me/weyye/hipermission/PermissionItem.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by Administrator on 2017/5/10 0010.
7 | */
8 |
9 | public class PermissionItem implements Serializable {
10 | public String PermissionName;
11 | public String Permission;
12 | public int PermissionIconRes;
13 |
14 | public PermissionItem(String permission, String permissionName, int permissionIconRes) {
15 | Permission = permission;
16 | PermissionName = permissionName;
17 | PermissionIconRes = permissionIconRes;
18 | }
19 |
20 | public PermissionItem(String permission) {
21 | Permission = permission;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/permission_info_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
20 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 申请多个权限(Default Style With Fade)
4 | 申请多个权限(Blue Style With Scale)
5 | 申请多个权限(Green Style With Modal)
6 | 申请单个权限
7 | 用户关闭权限申请
8 | 所有权限申请完成
9 | 照相机
10 | 拨打手机
11 | 亲爱的上帝
12 | 为了保护世界的和平,开启这些权限吧!\n你我一起拯救世界!
13 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/library/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 存储空间
3 | 位置信息
4 | 拍照权限
5 | 开启%s
6 | 为了您能正常使用%s,需要以下权限
7 | 请允许获取%s
8 | 我们需要获取%1$s, 否则您将无法正常使用%2$s
9 | "由于%1$s无法获取%2$s, 不能正常运行, 请开启权限后再使用。\n\n设置路径: 应用管理->%3$s->权限"
10 | 取消
11 | 确定
12 | 拒绝
13 | 下一步
14 | 去设置
15 |
16 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/me/weyye/demo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package me.weyye.demo;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("me.weyye.hipermission", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/library/src/androidTest/java/me/weyye/hipermission/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("me.weyye.library.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | HiPermission
3 | Mutl Permission(Default Style With Fade)
4 | Mutl Permission(Blue Style With Scale)
5 | Mutl Permission(Green Style With Modal)
6 | Single Permission
7 | They cancelled our request
8 | All permissions requested completed
9 | Camera
10 | Call Phone
11 | Dear God
12 | To protect the peace of the world, open these permissions! You and I together save the world!
13 |
14 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Storage
3 | Location
4 | Camera
5 | Start %s
6 | For your normal use %s, you need the following permissions
7 | Please allow access to %s
8 | We need access to %1$s,otherwise, you will not be able to use %2$s
9 | "Because %1$s cannot use %2$s,Can not run normally,Please open permissions before using.\n\nSetup path: Apps->%3$s->Permissions"
10 | Cancel
11 | Enter
12 | Deny
13 | Next
14 | Go to Setting
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
19 |
20 |
23 |
24 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.compileVersion
5 | buildToolsVersion rootProject.ext.buildToolsVersion
6 | defaultConfig {
7 | applicationId "me.weyye.demo"
8 | minSdkVersion rootProject.ext.minSdk
9 | targetSdkVersion rootProject.ext.targetSdk
10 | versionCode rootProject.ext.version_code
11 | versionName rootProject.ext.version_name
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(include: ['*.jar'], dir: 'libs')
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | compile "com.android.support:appcompat-v7:${rootProject.ext.supportVersion}"
28 | testCompile 'junit:junit:4.12'
29 | compile project(':library')
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/library/src/main/res/anim/modal_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
10 |
18 |
19 |
28 |
29 |
38 |
--------------------------------------------------------------------------------
/library/src/main/java/me/weyye/hipermission/WrapHeightGridView.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.GridView;
6 |
7 | /**
8 | * 自适应高度的GridView
9 | */
10 | public class WrapHeightGridView extends GridView {
11 |
12 | //防止计算多次导致界面显示错误
13 | public boolean isOnMeasure;
14 |
15 | public WrapHeightGridView(Context context) {
16 | super(context);
17 | }
18 |
19 | public WrapHeightGridView(Context context, AttributeSet attrs) {
20 | super(context, attrs);
21 | }
22 |
23 | public WrapHeightGridView(Context context, AttributeSet attrs, int defStyle) {
24 | super(context, attrs, defStyle);
25 | }
26 |
27 | @Override
28 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
29 | isOnMeasure = true;
30 | int heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
31 | MeasureSpec.AT_MOST);
32 | super.onMeasure(widthMeasureSpec, heightSpec);
33 | }
34 |
35 | @Override
36 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
37 | isOnMeasure = false;
38 | super.onLayout(changed, l, t, r, b);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
22 |
23 |
28 |
33 |
34 |
--------------------------------------------------------------------------------
/library/src/main/java/me/weyye/hipermission/PermissionAdapter.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | import android.graphics.Color;
4 | import android.graphics.ColorMatrixColorFilter;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.BaseAdapter;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * Created by Administrator on 2017/5/10 0010.
15 | */
16 |
17 | public class PermissionAdapter extends BaseAdapter {
18 | private List mData;
19 | private int mTextColor;
20 | private int mFilterColor;
21 |
22 | public PermissionAdapter(List data) {
23 | mData = data;
24 | }
25 |
26 | @Override
27 | public int getCount() {
28 | return mData.size();
29 | }
30 |
31 | @Override
32 | public Object getItem(int position) {
33 | return mData.get(position);
34 | }
35 |
36 | @Override
37 | public long getItemId(int position) {
38 | return 0;
39 | }
40 |
41 | @Override
42 | public View getView(int position, View convertView, ViewGroup parent) {
43 | PermissionItem item = mData.get(position);
44 | View view = View.inflate(parent.getContext(), R.layout.permission_info_item, null);
45 | int blue = Color.blue(mFilterColor);
46 | int green = Color.green(mFilterColor);
47 | int red = Color.red(mFilterColor);
48 | ImageView icon = (ImageView) view.findViewById(R.id.icon);
49 | float[] cm = new float[]{
50 | 1, 0, 0, 0, red,// 红色值
51 | 0, 1, 0, 0, green,// 绿色值
52 | 0, 0, 1, 0, blue,// 蓝色值
53 | 0, 0, 0, 1, 1 // 透明度
54 | };
55 | ColorMatrixColorFilter filter = new ColorMatrixColorFilter(cm);
56 | icon.setColorFilter(filter);
57 | TextView name = (TextView) view.findViewById(R.id.name);
58 | if (mTextColor != 0)
59 | name.setTextColor(mTextColor);
60 | icon.setImageResource(item.PermissionIconRes);
61 | name.setText(item.PermissionName);
62 | return view;
63 | }
64 |
65 | public void setTextColor(int itemTextColor) {
66 | mTextColor = itemTextColor;
67 | notifyDataSetChanged();
68 | }
69 |
70 | public void setFilterColor(int filterColor) {
71 | mFilterColor = filterColor;
72 | notifyDataSetChanged();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/dialog_request_permission.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
21 |
22 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
72 |
--------------------------------------------------------------------------------
/library/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
30 |
31 |
32 |
39 |
40 |
48 |
49 |
54 |
55 |
59 |
60 |
64 |
65 |
69 |
70 |
74 |
75 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.github.dcendents.android-maven'
3 | apply plugin: 'com.jfrog.bintray'
4 | android {
5 | compileSdkVersion rootProject.ext.compileVersion
6 | buildToolsVersion rootProject.ext.buildToolsVersion
7 |
8 | defaultConfig {
9 | minSdkVersion rootProject.ext.minSdk
10 | targetSdkVersion rootProject.ext.targetSdk
11 | versionCode rootProject.ext.version_code
12 | versionName rootProject.ext.version_name
13 |
14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
15 |
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | compile fileTree(dir: 'libs', include: ['*.jar'])
27 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
28 | exclude group: 'com.android.support', module: 'support-annotations'
29 | })
30 | compile "com.android.support:appcompat-v7:${rootProject.ext.supportVersion}"
31 | testCompile 'junit:junit:4.12'
32 | }
33 |
34 | //项目主页
35 | def siteUrl = 'https://github.com/yewei02538/HiPermission'
36 | //项目的git地址
37 | def gitUrl = 'https://github.com/yewei02538/HiPermission.git'
38 | //发布到JCenter上的项目名字
39 | def libName = "HiPermission"
40 |
41 | //发布到组织名称名字,必须填写
42 | group = "me.weyye.hipermission"
43 | // 版本号,下次更新是只需要更改版本号即可
44 | version = rootProject.ext.version_name
45 | //上面配置后上传至JCenter后的编译路径是这样的: compile 'me.songning.CircleView:library:1.0.0'
46 |
47 | //生成源文件
48 | task sourcesJar(type: Jar) {
49 | from android.sourceSets.main.java.srcDirs
50 | classifier = 'sources'
51 | }
52 |
53 | //生成Javadoc文档
54 | task javadoc(type: Javadoc) {
55 | source = android.sourceSets.main.java.srcDirs
56 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
57 | }
58 |
59 | //文档打包成jar
60 | task javadocJar(type: Jar, dependsOn: javadoc) {
61 | classifier = 'javadoc'
62 | from javadoc.destinationDir
63 | }
64 |
65 | //拷贝javadoc文件
66 | task copyDoc(type: Copy) {
67 | from "${buildDir}/docs/"
68 | into "docs"
69 | }
70 |
71 | //上传到JCenter所需要的源码文件
72 | artifacts {
73 | archives javadocJar
74 | archives sourcesJar
75 | }
76 |
77 | // 配置maven库,生成POM.xml文件
78 | install {
79 | repositories.mavenInstaller {
80 | // This generates POM.xml with proper parameters
81 | pom {
82 | project {
83 | packaging 'aar'
84 | //项目描述,随意填
85 | name '一个简单易用的漂亮的权限申请库'
86 | url siteUrl
87 | licenses {
88 | license {
89 | //开源协议
90 | name 'The Apache Software License, Version 2.0'
91 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
92 | }
93 | }
94 | developers {
95 | developer {
96 | //开发者的个人信息
97 | id 'yewei02538'
98 | name 'yewei02538'
99 | email 'hiweyye@gmail.com'
100 | }
101 | }
102 | scm {
103 | connection gitUrl
104 | developerConnection gitUrl
105 | url siteUrl
106 | }
107 | }
108 | }
109 | }
110 | }
111 |
112 | //上传到JCenter
113 | Properties properties = new Properties()
114 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
115 |
116 | bintray {
117 | user = properties.getProperty("bintray.user") //读取 local.properties 文件里面的 bintray.user
118 | key = properties.getProperty("bintray.apikey") //读取 local.properties 文件里面的 bintray.apikey
119 | configurations = ['archives']
120 | pkg {
121 | //这里的repo值必须要和你创建Maven仓库的时候的名字一样
122 | repo = "maven"
123 | //发布到JCenter上的项目名字
124 | name = libName
125 | //项目描述
126 | desc = '一个简单易用的漂亮的权限申请库'
127 | websiteUrl = siteUrl
128 | vcsUrl = gitUrl
129 | licenses = ["Apache-2.0"]
130 | publish = true
131 | }
132 | }
133 |
134 | javadoc {
135 | options{
136 | //如果你的项目里面有中文注释的话,必须将格式设置为UTF-8,不然会出现乱码
137 | encoding "UTF-8"
138 | charSet 'UTF-8'
139 | author true
140 | version true
141 | links "http://docs.oracle.com/javase/7/docs/api"
142 | }
143 | }
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | Android
39 |
40 |
41 | Android > Lint > Correctness
42 |
43 |
44 | Android > Lint > Internationalization
45 |
46 |
47 | Android > Lint > Performance
48 |
49 |
50 | Assignment issuesJava
51 |
52 |
53 | Class structureJava
54 |
55 |
56 | Code style issuesJava
57 |
58 |
59 | Control flow issuesJava
60 |
61 |
62 | CorrectnessLintAndroid
63 |
64 |
65 | Encapsulation issuesJava
66 |
67 |
68 | General
69 |
70 |
71 | Google Cloud Endpoints
72 |
73 |
74 | HTML
75 |
76 |
77 | Java
78 |
79 |
80 | LintAndroid
81 |
82 |
83 | Probable bugsJava
84 |
85 |
86 | RELAX NG
87 |
88 |
89 | Serialization issuesJava
90 |
91 |
92 | TestNGJava
93 |
94 |
95 | Threading issuesJava
96 |
97 |
98 |
99 |
100 | Android
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | 1.8
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/library/src/main/java/me/weyye/hipermission/PermissionView.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Color;
7 | import android.graphics.ColorFilter;
8 | import android.graphics.ColorMatrixColorFilter;
9 | import android.graphics.drawable.Drawable;
10 | import android.util.AttributeSet;
11 | import android.view.View;
12 | import android.widget.Button;
13 | import android.widget.FrameLayout;
14 | import android.widget.GridView;
15 | import android.widget.LinearLayout;
16 | import android.widget.ListAdapter;
17 | import android.widget.TextView;
18 |
19 | /**
20 | * Created by Administrator on 2017/5/11 0011.
21 | */
22 |
23 | public class PermissionView extends FrameLayout {
24 |
25 | private TextView mTvTitle;
26 | private TextView mTvDesc;
27 | private Button mBtnNext;
28 | private GridView mGvPermission;
29 | private LinearLayout mLlRoot;
30 |
31 | public PermissionView(Context context) {
32 | this(context, null);
33 | }
34 |
35 | public PermissionView(Context context, AttributeSet attrs) {
36 | this(context, attrs, 0);
37 | }
38 |
39 | public PermissionView(Context context, AttributeSet attrs, int defStyleAttr) {
40 | super(context, attrs, defStyleAttr);
41 | initView();
42 | }
43 |
44 | private void initView() {
45 | View permissionView = View.inflate(getContext(), R.layout.dialog_request_permission, this);
46 | mTvTitle = (TextView) permissionView.findViewById(R.id.tvTitle);
47 | mLlRoot = (LinearLayout) permissionView.findViewById(R.id.llRoot);
48 | mTvDesc = (TextView) permissionView.findViewById(R.id.tvDesc);
49 | mBtnNext = (Button) permissionView.findViewById(R.id.goto_settings);
50 | mGvPermission = (GridView) permissionView.findViewById(R.id.gvPermission);
51 | }
52 |
53 | public void setGridViewColum(int colum) {
54 | mGvPermission.setNumColumns(colum);
55 | }
56 |
57 | public void setGridViewAdapter(ListAdapter adapter) {
58 | mGvPermission.setAdapter(adapter);
59 | }
60 |
61 | public void setTitle(String title) {
62 | mTvTitle.setText(title);
63 | }
64 |
65 | public void setMsg(String msg) {
66 | mTvDesc.setText(msg);
67 | }
68 |
69 | public void setBtnOnClickListener(OnClickListener listener) {
70 | mBtnNext.setOnClickListener(listener);
71 | }
72 |
73 | @SuppressWarnings("ResourceType")
74 | public void setStyleId(int styleId) {
75 | if (styleId <= 0)
76 | return;
77 | int[] ints = {
78 | R.attr.PermissionMsgColor,
79 | R.attr.PermissionTitleColor,
80 | R.attr.PermissionItemTextColor,
81 | R.attr.PermissionButtonTextColor,
82 | R.attr.PermissionBackround,
83 | R.attr.PermissionButtonBackground,
84 | R.attr.PermissionBgFilterColor,
85 | R.attr.PermissionIconFilterColor
86 | };
87 | Resources.Theme theme = getResources().newTheme();
88 | theme.applyStyle(styleId, true);
89 |
90 | TypedArray typedArray = theme.obtainStyledAttributes(ints);
91 | int msgColor = typedArray.getColor(0, 0);
92 | int titleColor = typedArray.getColor(1, 0);
93 | int itemTextColor = typedArray.getColor(2, 0);
94 | int btnTextColor = typedArray.getColor(3, 0);
95 | Drawable background = typedArray.getDrawable(4);
96 | Drawable Btnbackground = typedArray.getDrawable(5);
97 | int bgFilterColor = typedArray.getColor(6, 0);
98 | int iconFilterColor = typedArray.getColor(7, 0);
99 |
100 | if (titleColor != 0)
101 | mTvTitle.setTextColor(titleColor);
102 | if (background != null) {
103 | if (bgFilterColor != 0)
104 | background.setColorFilter(getColorFilter(bgFilterColor));
105 | mLlRoot.setBackgroundDrawable(background);
106 | }
107 | if (msgColor != 0)
108 | mTvDesc.setTextColor(msgColor);
109 | if (itemTextColor != 0)
110 | ((PermissionAdapter) mGvPermission.getAdapter()).setTextColor(itemTextColor);
111 | if (Btnbackground != null)
112 | mBtnNext.setBackgroundDrawable(Btnbackground);
113 | if (btnTextColor != 0)
114 | mBtnNext.setTextColor(btnTextColor);
115 | if (iconFilterColor != 0)
116 | setFilterColor(iconFilterColor);
117 |
118 | typedArray.recycle();
119 |
120 | }
121 |
122 | private ColorFilter getColorFilter(int bgFilterColor) {
123 | int blue = Color.blue(bgFilterColor);
124 | int green = Color.green(bgFilterColor);
125 | int red = Color.red(bgFilterColor);
126 | float[] cm = new float[]{
127 | 1, 0, 0, 0, red,// 红色值
128 | 0, 1, 0, 0, green,// 绿色值
129 | 0, 0, 1, 0, blue,// 蓝色值
130 | 0, 0, 0, 1, 1 // 透明度
131 | };
132 | ColorMatrixColorFilter filter = new ColorMatrixColorFilter(cm);
133 | return filter;
134 | }
135 |
136 | public void setFilterColor(int color) {
137 | if (color == 0)
138 | return;
139 |
140 | ((PermissionAdapter) mGvPermission.getAdapter()).setFilterColor(color);
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/library/src/main/java/me/weyye/hipermission/HiPermission.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.PackageManager;
6 | import android.os.Build;
7 | import android.support.v4.content.ContextCompat;
8 |
9 | import java.io.Serializable;
10 | import java.util.ArrayList;
11 | import java.util.Iterator;
12 | import java.util.List;
13 |
14 | import static android.Manifest.permission.ACCESS_FINE_LOCATION;
15 | import static android.Manifest.permission.CAMERA;
16 | import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
17 |
18 | /**
19 | * Created by Administrator on 2017/5/10 0010.
20 | */
21 |
22 | public class HiPermission {
23 | private final Context mContext;
24 | // private static HiPermission mInstance;
25 |
26 | private String mTitle;
27 | private String mMsg;
28 | private int mStyleResId = -1;
29 | private PermissionCallback mCallback;
30 | private List mCheckPermissions;
31 | private int mPermissionType;
32 |
33 | private String[] mNormalPermissionNames;
34 | private String[] mNormalPermissions = {
35 | WRITE_EXTERNAL_STORAGE, ACCESS_FINE_LOCATION, CAMERA};
36 | private int[] mNormalPermissionIconRes = {
37 | R.drawable.permission_ic_storage, R.drawable.permission_ic_location, R.drawable.permission_ic_camera};
38 | private int mFilterColor = 0;
39 | private int mAnimStyleId = -1;
40 |
41 | public static HiPermission create(Context context) {
42 | return new HiPermission(context);
43 | }
44 |
45 | public HiPermission(Context context) {
46 | mContext = context;
47 | mNormalPermissionNames = mContext.getResources().getStringArray(R.array.permissionNames);
48 | }
49 |
50 | public HiPermission title(String title) {
51 | mTitle = title;
52 | return this;
53 | }
54 |
55 | public HiPermission msg(String msg) {
56 | mMsg = msg;
57 | return this;
58 | }
59 |
60 | public HiPermission permissions(List permissionItems) {
61 | mCheckPermissions = permissionItems;
62 | return this;
63 | }
64 |
65 | public HiPermission filterColor(int color) {
66 | mFilterColor = color;
67 | return this;
68 | }
69 |
70 | public HiPermission animStyle(int styleId) {
71 | mAnimStyleId = styleId;
72 | return this;
73 | }
74 |
75 | public HiPermission style(int styleResIdsId) {
76 | mStyleResId = styleResIdsId;
77 | return this;
78 | }
79 |
80 | private List getNormalPermissions() {
81 | List permissionItems = new ArrayList<>();
82 | for (int i = 0; i < mNormalPermissionNames.length; i++) {
83 | permissionItems.add(new PermissionItem(mNormalPermissions[i], mNormalPermissionNames[i], mNormalPermissionIconRes[i]));
84 | }
85 | return permissionItems;
86 | }
87 |
88 | public static boolean checkPermission(Context context, String permission) {
89 | int checkPermission = ContextCompat.checkSelfPermission(context, permission);
90 | if (checkPermission == PackageManager.PERMISSION_GRANTED) {
91 | return true;
92 | }
93 | return false;
94 | }
95 |
96 | /**
97 | * 检查多个权限
98 | *
99 | * @param callback
100 | */
101 | public void checkMutiPermission(PermissionCallback callback) {
102 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
103 | if (callback != null)
104 | callback.onFinish();
105 | return;
106 | }
107 |
108 | if (mCheckPermissions == null) {
109 | mCheckPermissions = new ArrayList<>();
110 | mCheckPermissions.addAll(getNormalPermissions());
111 | }
112 |
113 | //检查权限,过滤已允许的权限
114 | Iterator iterator = mCheckPermissions.listIterator();
115 | while (iterator.hasNext()) {
116 | if (checkPermission(mContext, iterator.next().Permission))
117 | iterator.remove();
118 | }
119 | mCallback = callback;
120 | if (mCheckPermissions.size() > 0) {
121 | startActivity();
122 | } else {
123 | if (callback != null)
124 | callback.onFinish();
125 | }
126 |
127 |
128 | }
129 |
130 | /**
131 | * 检查单个权限
132 | *
133 | * @param permission
134 | * @param callback
135 | */
136 | public void checkSinglePermission(String permission, PermissionCallback callback) {
137 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || checkPermission(mContext, permission)) {
138 | if (callback != null)
139 | callback.onGuarantee(permission, 0);
140 | return;
141 | }
142 | mCallback = callback;
143 | mPermissionType = PermissionActivity.PERMISSION_TYPE_SINGLE;
144 | mCheckPermissions = new ArrayList<>();
145 | mCheckPermissions.add(new PermissionItem(permission));
146 | startActivity();
147 | }
148 |
149 | private void startActivity() {
150 | PermissionActivity.setCallBack(mCallback);
151 | Intent intent = new Intent(mContext, PermissionActivity.class);
152 | intent.putExtra(ConstantValue.DATA_TITLE, mTitle);
153 | intent.putExtra(ConstantValue.DATA_PERMISSION_TYPE, mPermissionType);
154 | intent.putExtra(ConstantValue.DATA_MSG, mMsg);
155 | intent.putExtra(ConstantValue.DATA_FILTER_COLOR, mFilterColor);
156 | intent.putExtra(ConstantValue.DATA_STYLE_ID, mStyleResId);
157 | intent.putExtra(ConstantValue.DATA_ANIM_STYLE, mAnimStyleId);
158 | intent.putExtra(ConstantValue.DATA_PERMISSIONS, (Serializable) mCheckPermissions);
159 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
160 | mContext.startActivity(intent);
161 | }
162 |
163 | }
164 |
--------------------------------------------------------------------------------
/app/src/main/java/me/weyye/demo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package me.weyye.demo;
2 |
3 | import android.Manifest;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.widget.Toast;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | import me.weyye.hipermission.HiPermission;
14 | import me.weyye.hipermission.PermissionCallback;
15 | import me.weyye.hipermission.PermissionItem;
16 |
17 | public class MainActivity extends AppCompatActivity implements View.OnClickListener {
18 |
19 | private static final String TAG = "MainActivity";
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | setContentView(R.layout.activity_main);
25 | findViewById(R.id.btn1).setOnClickListener(this);
26 | findViewById(R.id.btn2).setOnClickListener(this);
27 | findViewById(R.id.btn3).setOnClickListener(this);
28 | findViewById(R.id.btn4).setOnClickListener(this);
29 | }
30 |
31 | private void showToast(String text) {
32 | Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
33 | }
34 |
35 | @Override
36 | public void onClick(View v) {
37 | switch (v.getId()) {
38 | case R.id.btn1:
39 | //default is normal style
40 | HiPermission.create(MainActivity.this)
41 | .animStyle(R.style.PermissionAnimFade)
42 | .checkMutiPermission(new PermissionCallback() {
43 | @Override
44 | public void onClose() {
45 | Log.i(TAG, "onClose");
46 | showToast(getString(R.string.permission_on_close));
47 | }
48 |
49 | @Override
50 | public void onFinish() {
51 | showToast(getString(R.string.permission_completed));
52 | }
53 |
54 | @Override
55 | public void onDeny(String permission, int position) {
56 | Log.i(TAG, "onDeny");
57 | }
58 |
59 | @Override
60 | public void onGuarantee(String permission, int position) {
61 | Log.i(TAG, "onGuarantee");
62 | }
63 | });
64 | break;
65 | case R.id.btn2:
66 | //After you have set the theme, you must called filterColor () to set the color of the icon
67 | // ,otherwise the default is black
68 | List permissionItems = new ArrayList();
69 | permissionItems.add(new PermissionItem(Manifest.permission.READ_PHONE_STATE, "手机状态", R.drawable.permission_ic_phone));
70 | HiPermission.create(MainActivity.this)
71 | .title(getString(R.string.permission_cus_title))
72 | .permissions(permissionItems)
73 | .msg(getString(R.string.permission_cus_msg))
74 | .animStyle(R.style.PermissionAnimScale)
75 | .style(R.style.PermissionDefaultBlueStyle)
76 | .checkMutiPermission(new PermissionCallback() {
77 | @Override
78 | public void onClose() {
79 | Log.i(TAG, "onClose");
80 | showToast(getString(R.string.permission_on_close));
81 | }
82 |
83 | @Override
84 | public void onFinish() {
85 | showToast(getString(R.string.permission_completed));
86 | }
87 |
88 | @Override
89 | public void onDeny(String permission, int position) {
90 | Log.i(TAG, "onDeny");
91 | }
92 |
93 | @Override
94 | public void onGuarantee(String permission, int position) {
95 | Log.i(TAG, "onGuarantee");
96 | }
97 | });
98 | break;
99 | case R.id.btn3:
100 | List permissions = new ArrayList();
101 | permissions.add(new PermissionItem(Manifest.permission.CALL_PHONE, getString(R.string.permission_cus_item_phone), R.drawable.permission_ic_phone));
102 | HiPermission.create(MainActivity.this)
103 | .title(getString(R.string.permission_cus_title))
104 | .permissions(permissions)
105 | .msg(getString(R.string.permission_cus_msg))
106 | .animStyle(R.style.PermissionAnimModal)
107 | .style(R.style.PermissionDefaultGreenStyle)
108 | // .style(R.style.CusStyle)
109 | .checkMutiPermission(new PermissionCallback() {
110 | @Override
111 | public void onClose() {
112 | Log.i(TAG, "onClose");
113 | showToast(getString(R.string.permission_on_close));
114 | }
115 |
116 | @Override
117 | public void onFinish() {
118 | showToast(getString(R.string.permission_completed));
119 | }
120 |
121 | @Override
122 | public void onDeny(String permission, int position) {
123 | Log.i(TAG, "onDeny");
124 | }
125 |
126 | @Override
127 | public void onGuarantee(String permission, int position) {
128 | Log.i(TAG, "onGuarantee");
129 | }
130 | });
131 | break;
132 | case R.id.btn4:
133 | //request single permission only called onDeny or onGuarantee
134 | HiPermission.create(MainActivity.this).checkSinglePermission(Manifest.permission.CAMERA, new PermissionCallback() {
135 | @Override
136 | public void onClose() {
137 |
138 | }
139 |
140 | @Override
141 | public void onFinish() {
142 |
143 | }
144 |
145 | @Override
146 | public void onDeny(String permission, int position) {
147 | showToast("onDeny");
148 | }
149 |
150 | @Override
151 | public void onGuarantee(String permission, int position) {
152 | showToast("onGuarantee");
153 | }
154 | });
155 | break;
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/README-CN.md:
--------------------------------------------------------------------------------
1 | # HiPermission
2 |
3 | 一个简单易用的漂亮权限申请库
4 |
5 | # 概述
6 | 随着Android6.0的普及,权限申请也变成了我们开发中必写的一段代码。比如sd卡权限、定位权限、拍照权限,这些几乎都是每个app必备的。而一般情况下我们都会在需要权限之前申请,然后各种判断。那既然是一些必备的是权限,我们为何不在我们一次打开app的时候就把这个全部都申请了呢?可是一下申请那么多权限对用户来说显然不是很友好,所以我们不妨在申请权限之前告诉一下用户,好让用户有个心理准备。于是借鉴了饿了么的权限申请界面,封装了一个库
7 |
8 | # 效果
9 |
10 | 
11 |
12 | # 过程
13 |
14 | 在申请权限的过程中难免会遭到用户无情的拒绝,那么就会弹出提示告诉用户这是必备的,你必须得同意!如果用户再一次手抖选择拒绝,那么我们会指引用户去权限管理里面打开我们的权限,如果还是拒绝那么..我特么真没辙了!!!
15 |
16 | # 使用
17 |
18 | Gradle:
19 |
20 | compile 'me.weyye.hipermission:library:1.0.7'
21 |
22 | Or Maven:
23 |
24 |
25 | me.weyye.hipermission
26 | library
27 | 1.0.7
28 | pom
29 |
30 |
31 | 一行代码搞定
32 |
33 | ``` java
34 | HiPermission.create(context)
35 | .checkMutiPermission(new PermissionCallback() {
36 | @Override
37 | public void onClose() {
38 | Log.i(TAG, "onClose");
39 | showToast("用户关闭权限申请");
40 | }
41 |
42 | @Override
43 | public void onFinish() {
44 | showToast("所有权限申请完成");
45 | }
46 |
47 | @Override
48 | public void onDeny(String permission, int position) {
49 | Log.i(TAG, "onDeny");
50 | }
51 |
52 | @Override
53 | public void onGuarantee(String permission, int position) {
54 | Log.i(TAG, "onGuarantee");
55 | }
56 | });
57 | ```
58 |
59 | 就这样轻松搞定三个必备的权限
60 |
61 | 你想申请别的权限?那也没问题
62 |
63 | ``` java
64 | List permissionItems = new ArrayList();
65 | permissionItems.add(new PermissionItem(Manifest.permission.CAMERA, "照相机", R.drawable.permission_ic_memory));
66 | permissionItems.add(new PermissionItem(Manifest.permission.ACCESS_FINE_LOCATION, "定位", R.drawable.permission_ic_location));
67 | HiPermission.create(MainActivity.this)
68 | .permissions(permissionItems)
69 | .checkMutiPermission(...);
70 | ```
71 |
72 | ## 自定义主题
73 |
74 | 什么?想改下提示信息?界面不符合你的主题颜色?so easy
75 |
76 | ``` java
77 | HiPermission.create(MainActivity.this)
78 | .title("亲爱的上帝")
79 | .permissions(permissionItems)
80 | .filterColor(ResourcesCompat.getColor(getResources(), R.color.colorPrimary, getTheme()))//图标的颜色
81 | .msg("为了保护世界的和平,开启这些权限吧!\n你我一起拯救世界!")
82 | .style(R.style.PermissionBlueStyle)
83 | .checkMutiPermission(...);
84 | ```
85 |
86 | > 设置主题后一定要调用`filterColor()`,否者权限图标会变成默认的黑色
87 |
88 |
89 | styles.xml
90 |
91 | ``` xml
92 |
100 | ```
101 |
102 |
103 | 
104 |
105 | ## 默认图标
106 | 如果你需要申请其他权限,但是没有图标?`HiPermission`已经给你准备好啦~
107 |
108 | | |日历|相机|联系人|定位|
109 | |:-:|:-:|:-:|:-:|:-:|
110 | | |||||
111 | |drawableId|permission_ic_calendar|permission_ic_camera|permission_ic_contacts|permission_ic_location|
112 |
113 |
114 | | |麦克风|手机|短信|存储|传感器|
115 | |:-:|:-:|:-:|:-:|:-:|:-:|
116 | | ||||||
117 | |drawableId|permission_ic_micro_phone|permission_ic_phone|permission_ic_sms|permission_ic_storage|permission_ic_sensors|
118 |
119 | 使用图标
120 |
121 | ``` java
122 | List permissions = new ArrayList();
123 | //使用图标
124 | permissions.add(new PermissionItem(Manifest.permission.CALL_PHONE, getString(R.string.permission_cus_item_phone), R.drawable.permission_ic_phone));
125 | HiPermission.create(MainActivity.this)
126 | .permissions(permissions)
127 | .style(R.style.PermissionDefaultGreenStyle)
128 | .checkMutiPermission(...);
129 | ```
130 |
131 | >图标默认是黑色,需要调用`filterColor()`更改图标颜色
132 |
133 | ## 默认主题
134 |
135 | 当然,目前有3种默认的主题和动画
136 |
137 | | |Screenshot| Screenshot|Screenshot|
138 | |:-:|:-:|:-:| :-:|
139 | | | |||
140 | |styleId|PermissionDefaultNormalStyle|PermissionDefaultGreenStyle|PermissionDefaultBlueStyle|
141 | |AnimId|PermissionAnimFade|PermissionAnimModal|PermissionAnimScale|
142 |
143 | 主题默认不带动画,需自己手动设置,像这样
144 |
145 | ``` java
146 | HiPermission.create(MainActivity.this)
147 | .title(getString(R.string.permission_cus_title))
148 | .permissions(permissions)
149 | .msg(getString(R.string.permission_cus_msg))
150 | .animStyle(R.style.PermissionAnimModal)//设置动画
151 | .style(R.style.PermissionDefaultGreenStyle)//设置主题
152 | .checkMutiPermission(...);
153 | ```
154 |
155 | 如果你想改style的个别属性,你可以在你的style里面继承某个style重写某个属性,像这样
156 |
157 | ``` xml
158 |
161 | ```
162 |
163 | 效果
164 |
165 | 
166 |
167 |
168 | 以下是每个属性的解释
169 |
170 | | 属性名 | 类型 | 解释 |
171 | | ------------- |:-------------:| -----:|
172 | | PermissionTitleColor | int | 标题文字颜色 |
173 | | PermissionMsgColor| int | 描述文字颜色 |
174 | | PermissionItemTextColor| int | 权限文字颜色 |
175 | | PermissionButtonTextColor| int | 按钮文字颜色 |
176 | | PermissionButtonBackground| drawable| 按钮背景 |
177 | | PermissionBackround| drawable| 对话框背景 |
178 | | PermissionBgFilterColor| int| 背景过滤色 |
179 | | PermissionIconFilterColor| int|图标颜色 |
180 |
181 | 如果设置主题后不想调用`filterColor()`可在你的style里面添加`PermissionIconFilterColor`属性
182 |
183 | # 注意
184 |
185 | > 清单文件一定要注册申请的权限,不然申请后会默认拒绝,而且设置-权限管理界面也无法看到此权限
186 |
187 | 以下原因不会弹框
188 |
189 | * 6.0以下版本(系统自动申请)
190 | * 暂时发现vivo、oppo、魅族的6.0以上版本
191 |
192 | >因为这些厂商修改了6.0系统申请机制,他们修改成系统自动申请权限了。也就是说这些系统会跟以前 6.0 以下的版本一样,需要用到权限的时候系统会自动申请,就算我们主动申请也是没用的(我拿饿了么测试也没弹出权限框)
193 |
194 | # 最后
195 | 如果这个对你有用,不妨来个star?
196 |
197 | # 联系我
198 |
199 | * QQ:505141450
200 | * Email:[hiweyye@gmail.com](mailto:hiweyye@gmail.com)
201 | * My Blog:[http://weyye.me](http://weyye.me)
202 | * 简书:[http://www.jianshu.com/u/c5da2f9c87fb](http://www.jianshu.com/u/c5da2f9c87fb)
203 | * CSDN:[http://blog.csdn.net/yewei02538](http://blog.csdn.net/yewei02538)
204 |
205 | # License
206 | Copyright (C) 2017 WeyYe
207 |
208 | Licensed under the Apache License, Version 2.0 (the "License");
209 | you may not use this file except in compliance with the License.
210 | You may obtain a copy of the License at
211 |
212 | http://www.apache.org/licenses/LICENSE-2.0
213 |
214 | Unless required by applicable law or agreed to in writing, software
215 | distributed under the License is distributed on an "AS IS" BASIS,
216 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
217 | See the License for the specific language governing permissions and
218 | limitations under the License.
219 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HiPermission
2 | A simple and beautiful runtime permission library on Android.[中文文档](/README-CN.md)
3 |
4 |
5 | # Features
6 | * One line of code to solve
7 | * Various logics are omitted
8 | * Support change permission Ui
9 |
10 | `ACCESS_FINE_LOCATION`,`WRITE_EXTERNAL_STORAGE` and `CAMERA`,these almost every app requires permissions ,so we can request these permissions when app launch.But it's not very friendly to request so many permissions at once.So before the request permission, we need to tell the user why we did this.The inspiration comes from [eleme](https://play.google.com/store/apps/details?id=me.ele)
11 |
12 | # Screenshot
13 |
14 | 
15 |
16 | # Demo
17 |
18 | [Download](/screenshot/app-debug.apk)
19 |
20 | # Usage
21 | Use Gradle:
22 |
23 | compile 'me.weyye.hipermission:library:1.0.7'
24 |
25 | Or Maven:
26 |
27 |
28 | me.weyye.hipermission
29 | library
30 | 1.0.7
31 | pom
32 |
33 |
34 | In your Activity or anywhere:
35 |
36 | They will request three necessary permissions:`CAMERA`,`ACCESS_FINE_LOCATION` and `WRITE_EXTERNAL_STORAGE`
37 | ``` java
38 | HiPermission.create(context)
39 | .checkMutiPermission(new PermissionCallback() {
40 | @Override
41 | public void onClose() {
42 | Log.i(TAG, "onClose");
43 | showToast("They cancelled our request");
44 | }
45 |
46 | @Override
47 | public void onFinish() {
48 | showToast("All permissions requested completed");
49 | }
50 |
51 | @Override
52 | public void onDeny(String permission, int position) {
53 | Log.i(TAG, "onDeny");
54 | }
55 |
56 | @Override
57 | public void onGuarantee(String permission, int position) {
58 | Log.i(TAG, "onGuarantee");
59 | }
60 | });
61 | ```
62 |
63 | Sometimes you don't need to request for these permissions,you can add permissions that you want to request like this
64 |
65 | ``` java
66 | List permissionItems = new ArrayList();
67 | permissionItems.add(new PermissionItem(Manifest.permission.CAMERA, "Camera", R.drawable.permission_ic_memory));
68 | permissionItems.add(new PermissionItem(Manifest.permission.ACCESS_FINE_LOCATION, "Location", R.drawable.permission_ic_location));
69 | HiPermission.create(MainActivity.this)
70 | .permissions(permissionItems)
71 | .checkMutiPermission(...);
72 | ```
73 |
74 | ## Custom Style
75 |
76 | Can I change the color of the interface? Or change hint information? Yes!
77 |
78 | ``` java
79 | HiPermission.create(MainActivity.this)
80 | .title("Dear God")
81 | .permissions(permissionItems)
82 | .filterColor(ResourcesCompat.getColor(getResources(), R.color.colorPrimary, getTheme()))//permission icon color
83 | .msg("To protect the peace of the world, open these permissions! You and I together save the world!")
84 | .style(R.style.PermissionBlueStyle)
85 | .checkMutiPermission(...);
86 | ```
87 |
88 | > After you have set the theme, you must called `filterColor ()` to set the color of the icon,otherwise the default is black
89 |
90 |
91 | styles.xml
92 |
93 | ``` xml
94 |
102 | ```
103 |
104 | 
105 |
106 | ## Default Icon
107 |
108 | If you need to request other permissions, but no icon? `HiPermission` has been prepared for you
109 |
110 | | |Calendar|Camera|Contacts|Location|
111 | |:-:|:-:|:-:|:-:|:-:|
112 | | |||||
113 | |drawableId|permission_ic_calendar|permission_ic_camera|permission_ic_contacts|permission_ic_location|
114 |
115 |
116 | | |Micro Phone|Phone|Sms|Storage|Sensors|
117 | |:-:|:-:|:-:|:-:|:-:|:-:|
118 | | ||||||
119 | |drawableId|permission_ic_micro_phone|permission_ic_phone|permission_ic_sms|permission_ic_storage|permission_ic_sensors|
120 |
121 | Use icon
122 |
123 | ``` java
124 | List permissions = new ArrayList();
125 | //use default icon
126 | permissions.add(new PermissionItem(Manifest.permission.CALL_PHONE, getString(R.string.permission_cus_item_phone), R.drawable.permission_ic_phone));
127 | HiPermission.create(MainActivity.this)
128 | .permissions(permissions)
129 | .style(R.style.PermissionDefaultGreenStyle)
130 | .checkMutiPermission(...);
131 | ```
132 |
133 | >The icon is black by default, and you need to called `filterColor ()` to change the icon color
134 |
135 | ## Default Style
136 |
137 | Of course, there are three default style and animations
138 |
139 | | |Screenshot| Screenshot|Screenshot|
140 | |:-:|:-:|:-:| :-:|
141 | | | |||
142 | |styleId|PermissionDefaultNormalStyle|PermissionDefaultGreenStyle|PermissionDefaultBlueStyle|
143 | |AnimId|PermissionAnimFade|PermissionAnimModal|PermissionAnimScale|
144 |
145 | Theme by default without animation, you need to call animStyle () like this:
146 |
147 | ``` java
148 | HiPermission.create(MainActivity.this)
149 | .title(getString(R.string.permission_cus_title))
150 | .permissions(permissions)
151 | .msg(getString(R.string.permission_cus_msg))
152 | .animStyle(R.style.PermissionAnimModal)//set dialog animation
153 | .style(R.style.PermissionDefaultGreenStyle)//set dialog style
154 | .checkMutiPermission(...);
155 | ```
156 |
157 | If you want to change the style of a attribute, you can extends a style inside your style override a attribute, like this
158 |
159 | ``` xml
160 |
163 | ```
164 |
165 | 
166 |
167 |
168 | The following are all attributes
169 |
170 |
171 | | attributes name | type
172 | | ------------- |:-------------:|
173 | | PermissionTitleColor | int |
174 | | PermissionMsgColor| int |
175 | | PermissionItemTextColor| int |
176 | | PermissionButtonTextColor| int |
177 | | PermissionButtonBackground| drawable|
178 | | PermissionBackround| drawable|
179 | | PermissionBgFilterColor|int|
180 | | PermissionIconFilterColor|int|
181 |
182 | # End
183 | If you like,please give a star as an encouragement to me
184 |
185 | # About me
186 | * Email:[hiweyye@gmail.com](mailto:hiweyye@gmail.com)
187 | * My Blog:[http://weyye.me](http://weyye.me)
188 | * 简书:[http://www.jianshu.com/u/c5da2f9c87fb](http://www.jianshu.com/u/c5da2f9c87fb)
189 | * CSDN:[http://blog.csdn.net/yewei02538](http://blog.csdn.net/yewei02538)
190 |
191 | # License
192 | Copyright (C) 2017 WeyYe
193 |
194 | Licensed under the Apache License, Version 2.0 (the "License");
195 | you may not use this file except in compliance with the License.
196 | You may obtain a copy of the License at
197 |
198 | http://www.apache.org/licenses/LICENSE-2.0
199 |
200 | Unless required by applicable law or agreed to in writing, software
201 | distributed under the License is distributed on an "AS IS" BASIS,
202 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
203 | See the License for the specific language governing permissions and
204 | limitations under the License.
205 |
--------------------------------------------------------------------------------
/library/src/main/java/me/weyye/hipermission/PermissionActivity.java:
--------------------------------------------------------------------------------
1 | package me.weyye.hipermission;
2 |
3 | import android.app.Dialog;
4 | import android.content.DialogInterface;
5 | import android.content.Intent;
6 | import android.content.pm.PackageManager;
7 | import android.graphics.Color;
8 | import android.graphics.drawable.ColorDrawable;
9 | import android.net.Uri;
10 | import android.os.Bundle;
11 | import android.provider.Settings;
12 | import android.support.annotation.NonNull;
13 | import android.support.annotation.Nullable;
14 | import android.support.v4.app.ActivityCompat;
15 | import android.support.v4.content.ContextCompat;
16 | import android.support.v7.app.AlertDialog;
17 | import android.support.v7.app.AppCompatActivity;
18 | import android.text.TextUtils;
19 | import android.util.Log;
20 | import android.view.View;
21 | import android.view.Window;
22 |
23 | import java.util.List;
24 | import java.util.ListIterator;
25 |
26 |
27 | /**
28 | * Created by Administrator on 2017/5/10 0010.
29 | */
30 |
31 | public class PermissionActivity extends AppCompatActivity {
32 |
33 | public static int PERMISSION_TYPE_SINGLE = 1;
34 | public static int PERMISSION_TYPE_MUTI = 2;
35 | private int mPermissionType;
36 | private String mTitle;
37 | private String mMsg;
38 | private static PermissionCallback mCallback;
39 | private List mCheckPermissions;
40 | private Dialog mDialog;
41 |
42 | private static final int REQUEST_CODE_SINGLE = 1;
43 | private static final int REQUEST_CODE_MUTI = 2;
44 | public static final int REQUEST_CODE_MUTI_SINGLE = 3;
45 | private static final int REQUEST_SETTING = 110;
46 |
47 | private static final String TAG = "PermissionActivity";
48 | private CharSequence mAppName;
49 | private int mStyleId;
50 | private int mFilterColor;
51 | private int mAnimStyleId;
52 |
53 | public static void setCallBack(PermissionCallback callBack) {
54 | PermissionActivity.mCallback = callBack;
55 | }
56 |
57 | @Override
58 | protected void onDestroy() {
59 | super.onDestroy();
60 | mCallback = null;
61 | if (mDialog != null && mDialog.isShowing())
62 | mDialog.dismiss();
63 | }
64 |
65 | @Override
66 | protected void onCreate(@Nullable Bundle savedInstanceState) {
67 | super.onCreate(savedInstanceState);
68 | getDatas();
69 | if (mPermissionType == PERMISSION_TYPE_SINGLE) {
70 | //单个权限申请
71 | if (mCheckPermissions == null || mCheckPermissions.size() == 0)
72 | return;
73 |
74 | requestPermission(new String[]{mCheckPermissions.get(0).Permission}, REQUEST_CODE_SINGLE);
75 | } else {
76 | mAppName = getApplicationInfo().loadLabel(getPackageManager());
77 | //多个权限
78 | showPermissionDialog();
79 | }
80 | }
81 |
82 |
83 | private String getPermissionTitle() {
84 | return TextUtils.isEmpty(mTitle) ? String.format(getString(R.string.permission_dialog_title), mAppName) : mTitle;
85 | }
86 |
87 | private void showPermissionDialog() {
88 |
89 | String title = getPermissionTitle();
90 | String msg = TextUtils.isEmpty(mMsg) ? String.format(getString(R.string.permission_dialog_msg), mAppName) : mMsg;
91 |
92 | PermissionView contentView = new PermissionView(this);
93 | contentView.setGridViewColum(mCheckPermissions.size() < 3 ? mCheckPermissions.size() : 3);
94 | contentView.setTitle(title);
95 | contentView.setMsg(msg);
96 | //这里没有使用RecyclerView,可以少引入一个库
97 | contentView.setGridViewAdapter(new PermissionAdapter(mCheckPermissions));
98 | if (mStyleId == -1) {
99 | //用户没有设置,使用默认绿色主题
100 | mStyleId = R.style.PermissionDefaultNormalStyle;
101 | mFilterColor = getResources().getColor(R.color.permissionColorGreen);
102 | }
103 |
104 | contentView.setStyleId(mStyleId);
105 | contentView.setFilterColor(mFilterColor);
106 | contentView.setBtnOnClickListener(new View.OnClickListener() {
107 | @Override
108 | public void onClick(View v) {
109 | if (mDialog != null && mDialog.isShowing())
110 | mDialog.dismiss();
111 | String[] strs = getPermissionStrArray();
112 | ActivityCompat.requestPermissions(PermissionActivity.this, strs, REQUEST_CODE_MUTI);
113 | }
114 | });
115 | mDialog = new Dialog(this);
116 | mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
117 | mDialog.setContentView(contentView);
118 | if (mAnimStyleId != -1)
119 | mDialog.getWindow().setWindowAnimations(mAnimStyleId);
120 |
121 | mDialog.setCanceledOnTouchOutside(false);
122 | mDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
123 | mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
124 | @Override
125 | public void onCancel(DialogInterface dialog) {
126 | dialog.dismiss();
127 | if (mCallback != null)
128 | mCallback.onClose();
129 | finish();
130 | }
131 | });
132 | mDialog.show();
133 | }
134 |
135 |
136 | private void reRequestPermission(final String permission) {
137 | String permissionName = getPermissionItem(permission).PermissionName;
138 | String alertTitle = String.format(getString(R.string.permission_title), permissionName);
139 | String msg = String.format(getString(R.string.permission_denied), permissionName, mAppName);
140 | showAlertDialog(alertTitle, msg, getString(R.string.permission_cancel), getString(R.string.permission_ensure), new DialogInterface.OnClickListener() {
141 | @Override
142 | public void onClick(DialogInterface dialog, int which) {
143 | dialog.dismiss();
144 | requestPermission(new String[]{permission}, REQUEST_CODE_MUTI_SINGLE);
145 | }
146 | });
147 | }
148 |
149 | private void requestPermission(String[] permissions, int requestCode) {
150 | ActivityCompat.requestPermissions(PermissionActivity.this, permissions, requestCode);
151 | }
152 |
153 | private void showAlertDialog(String title, String msg, String cancelTxt, String PosTxt, DialogInterface.OnClickListener onClickListener) {
154 | AlertDialog alertDialog = new AlertDialog.Builder(this)
155 | .setTitle(title)
156 | .setMessage(msg)
157 | .setCancelable(false)
158 | .setNegativeButton(cancelTxt, new DialogInterface.OnClickListener() {
159 | @Override
160 | public void onClick(DialogInterface dialog, int which) {
161 | dialog.dismiss();
162 | onClose();
163 | }
164 | })
165 | .setPositiveButton(PosTxt, onClickListener).create();
166 | alertDialog.show();
167 | }
168 |
169 | private String[] getPermissionStrArray() {
170 | String[] str = new String[mCheckPermissions.size()];
171 | for (int i = 0; i < mCheckPermissions.size(); i++) {
172 | str[i] = mCheckPermissions.get(i).Permission;
173 | }
174 | return str;
175 | }
176 |
177 |
178 | private void getDatas() {
179 | Intent intent = getIntent();
180 | mPermissionType = intent.getIntExtra(ConstantValue.DATA_PERMISSION_TYPE, PERMISSION_TYPE_SINGLE);
181 | mTitle = intent.getStringExtra(ConstantValue.DATA_TITLE);
182 | mMsg = intent.getStringExtra(ConstantValue.DATA_MSG);
183 | mFilterColor = intent.getIntExtra(ConstantValue.DATA_FILTER_COLOR, 0);
184 | mStyleId = intent.getIntExtra(ConstantValue.DATA_STYLE_ID, -1);
185 | mAnimStyleId = intent.getIntExtra(ConstantValue.DATA_ANIM_STYLE, -1);
186 | mCheckPermissions = (List) intent.getSerializableExtra(ConstantValue.DATA_PERMISSIONS);
187 | }
188 |
189 | /**
190 | * 重新申请权限数组的索引
191 | */
192 | private int mRePermissionIndex;
193 |
194 | @Override
195 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
196 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
197 | switch (requestCode) {
198 | case REQUEST_CODE_SINGLE:
199 | String permission = getPermissionItem(permissions[0]).Permission;
200 | if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
201 | onGuarantee(permission, 0);
202 | } else {
203 | onDeny(permission, 0);
204 | }
205 | finish();
206 | break;
207 | case REQUEST_CODE_MUTI:
208 | for (int i = 0; i < grantResults.length; i++) {
209 | //权限允许后,删除需要检查的权限
210 | if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
211 | PermissionItem item = getPermissionItem(permissions[i]);
212 | mCheckPermissions.remove(item);
213 | onGuarantee(permissions[i], i);
214 | } else {
215 | //权限拒绝
216 | onDeny(permissions[i], i);
217 | }
218 | }
219 | if (mCheckPermissions.size() > 0) {
220 | //用户拒绝了某个或多个权限,重新申请
221 | reRequestPermission(mCheckPermissions.get(mRePermissionIndex).Permission);
222 | } else {
223 | onFinish();
224 | }
225 | break;
226 | case REQUEST_CODE_MUTI_SINGLE:
227 | if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
228 | //重新申请后再次拒绝
229 | //弹框警告! haha
230 | try {
231 | //permissions可能返回空数组,所以try-catch
232 | String name = getPermissionItem(permissions[0]).PermissionName;
233 | String title = String.format(getString(R.string.permission_title), name);
234 | String msg = String.format(getString(R.string.permission_denied_with_naac), mAppName, name, mAppName);
235 | showAlertDialog(title, msg, getString(R.string.permission_reject), getString(R.string.permission_go_to_setting), new DialogInterface.OnClickListener() {
236 | @Override
237 | public void onClick(DialogInterface dialog, int which) {
238 | try {
239 | Uri packageURI = Uri.parse("package:" + getPackageName());
240 | Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
241 | startActivityForResult(intent, REQUEST_SETTING);
242 | } catch (Exception e) {
243 | e.printStackTrace();
244 | onClose();
245 | }
246 | }
247 | });
248 | onDeny(permissions[0], 0);
249 | } catch (Exception e) {
250 | e.printStackTrace();
251 | onClose();
252 | }
253 | } else {
254 | onGuarantee(permissions[0], 0);
255 | if (mRePermissionIndex < mCheckPermissions.size() - 1) {
256 | //继续申请下一个被拒绝的权限
257 | reRequestPermission(mCheckPermissions.get(++mRePermissionIndex).Permission);
258 | } else {
259 | //全部允许了
260 | onFinish();
261 | }
262 | }
263 | break;
264 | }
265 | }
266 |
267 | @Override
268 | public void finish() {
269 | super.finish();
270 | overridePendingTransition(0, 0);
271 | }
272 |
273 | @Override
274 | public void onBackPressed() {
275 | finish();
276 | }
277 |
278 | @Override
279 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
280 | super.onActivityResult(requestCode, resultCode, data);
281 | Log.e(TAG, "onActivityResult--requestCode:" + requestCode + ",resultCode:" + resultCode);
282 | if (requestCode == REQUEST_SETTING) {
283 | if (mDialog != null && mDialog.isShowing())
284 | mDialog.dismiss();
285 | checkPermission();
286 | if (mCheckPermissions.size() > 0) {
287 | mRePermissionIndex = 0;
288 | reRequestPermission(mCheckPermissions.get(mRePermissionIndex).Permission);
289 | } else {
290 | onFinish();
291 | }
292 | }
293 |
294 | }
295 |
296 | private void checkPermission() {
297 |
298 | ListIterator iterator = mCheckPermissions.listIterator();
299 | while (iterator.hasNext()) {
300 | int checkPermission = ContextCompat.checkSelfPermission(getApplicationContext(), iterator.next().Permission);
301 | if (checkPermission == PackageManager.PERMISSION_GRANTED) {
302 | iterator.remove();
303 | }
304 | }
305 | }
306 |
307 | private void onFinish() {
308 | if (mCallback != null)
309 | mCallback.onFinish();
310 | finish();
311 | }
312 |
313 | private void onClose() {
314 | if (mCallback != null)
315 | mCallback.onClose();
316 | finish();
317 | }
318 |
319 | private void onDeny(String permission, int position) {
320 | if (mCallback != null)
321 | mCallback.onDeny(permission, position);
322 | }
323 |
324 | private void onGuarantee(String permission, int position) {
325 | if (mCallback != null)
326 | mCallback.onGuarantee(permission, position);
327 | }
328 |
329 | private PermissionItem getPermissionItem(String permission) {
330 | for (PermissionItem permissionItem : mCheckPermissions) {
331 | if (permissionItem.Permission.equals(permission))
332 | return permissionItem;
333 | }
334 | return null;
335 | }
336 | }
337 |
--------------------------------------------------------------------------------