denied);
40 |
41 | /**
42 | * Start install.
43 | */
44 | void start();
45 | }
--------------------------------------------------------------------------------
/permission/src/main/java/com/yanzhenjie/permission/source/ActivitySource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.source;
17 |
18 | import android.app.Activity;
19 | import android.content.Context;
20 | import android.content.Intent;
21 | import android.os.Build;
22 |
23 | /**
24 | * Context Wrapper.
25 | * Created by Zhenjie Yan on 2017/5/1.
26 | */
27 | public class ActivitySource extends Source {
28 |
29 | private Activity mActivity;
30 |
31 | public ActivitySource(Activity activity) {
32 | this.mActivity = activity;
33 | }
34 |
35 | @Override
36 | public Context getContext() {
37 | return mActivity;
38 | }
39 |
40 | @Override
41 | public void startActivity(Intent intent) {
42 | mActivity.startActivity(intent);
43 | }
44 |
45 | @Override
46 | public void startActivityForResult(Intent intent, int requestCode) {
47 | mActivity.startActivityForResult(intent, requestCode);
48 | }
49 |
50 | @Override
51 | public boolean isShowRationalePermission(String permission) {
52 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
53 |
54 | return mActivity.shouldShowRequestPermissionRationale(permission);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/permission/src/main/java/com/yanzhenjie/permission/source/ContextSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.source;
17 |
18 | import android.content.Context;
19 | import android.content.Intent;
20 | import android.content.pm.PackageManager;
21 | import android.os.Build;
22 |
23 | import java.lang.reflect.Method;
24 |
25 | /**
26 | * Context Wrapper.
27 | * Created by Zhenjie Yan on 2017/5/1.
28 | */
29 | public class ContextSource extends Source {
30 |
31 | private Context mContext;
32 |
33 | public ContextSource(Context context) {
34 | this.mContext = context;
35 | }
36 |
37 | @Override
38 | public Context getContext() {
39 | return mContext;
40 | }
41 |
42 | @Override
43 | public void startActivity(Intent intent) {
44 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
45 | mContext.startActivity(intent);
46 | }
47 |
48 | @Override
49 | public void startActivityForResult(Intent intent, int requestCode) {
50 | throw new UnsupportedOperationException("Unsupported operation.");
51 | }
52 |
53 | @Override
54 | public boolean isShowRationalePermission(String permission) {
55 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
56 |
57 | PackageManager packageManager = mContext.getPackageManager();
58 | Class> pkManagerClass = packageManager.getClass();
59 | try {
60 | Method method = pkManagerClass.getMethod("shouldShowRequestPermissionRationale", String.class);
61 | if (!method.isAccessible()) method.setAccessible(true);
62 | return (boolean)method.invoke(packageManager, permission);
63 | } catch (Exception ignored) {
64 | return false;
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/permission/src/main/java/com/yanzhenjie/permission/source/FragmentSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.source;
17 |
18 | import android.app.Fragment;
19 | import android.content.Context;
20 | import android.content.Intent;
21 | import android.os.Build;
22 |
23 | /**
24 | * android.app.Fragment Wrapper.
25 | * Created by Zhenjie Yan on 2017/5/1.
26 | */
27 | public class FragmentSource extends Source {
28 |
29 | private Fragment mFragment;
30 |
31 | public FragmentSource(Fragment fragment) {
32 | this.mFragment = fragment;
33 | }
34 |
35 | @Override
36 | public Context getContext() {
37 | return mFragment.getActivity();
38 | }
39 |
40 | @Override
41 | public void startActivity(Intent intent) {
42 | mFragment.startActivity(intent);
43 | }
44 |
45 | @Override
46 | public void startActivityForResult(Intent intent, int requestCode) {
47 | mFragment.startActivityForResult(intent, requestCode);
48 | }
49 |
50 | @Override
51 | public boolean isShowRationalePermission(String permission) {
52 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
53 | return mFragment.shouldShowRequestPermissionRationale(permission);
54 | }
55 | }
--------------------------------------------------------------------------------
/permission/src/main/java/com/yanzhenjie/permission/source/WrapperSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.source;
17 |
18 | import android.content.Context;
19 | import android.content.Intent;
20 |
21 | /**
22 | * Created by Zhenjie Yan on 2/22/19.
23 | */
24 | public class WrapperSource extends Source {
25 |
26 | private Source mSource;
27 |
28 | public WrapperSource(Source source) {
29 | this.mSource = source;
30 | }
31 |
32 | @Override
33 | public Context getContext() {
34 | return mSource.getContext();
35 | }
36 |
37 | @Override
38 | public void startActivity(Intent intent) {
39 | mSource.startActivity(intent);
40 | }
41 |
42 | @Override
43 | public void startActivityForResult(Intent intent, int requestCode) {
44 | mSource.startActivityForResult(intent, requestCode);
45 | }
46 |
47 | @Override
48 | public boolean isShowRationalePermission(String permission) {
49 | return mSource.isShowRationalePermission(permission);
50 | }
51 | }
--------------------------------------------------------------------------------
/permission/src/main/java/com/yanzhenjie/permission/source/XFragmentSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.source;
17 |
18 | import android.content.Context;
19 | import android.content.Intent;
20 | import android.os.Build;
21 |
22 | import androidx.fragment.app.Fragment;
23 |
24 | /**
25 | * android.support.v4.app.Fragment Wrapper.
26 | * Created by Zhenjie Yan on 2017/5/1.
27 | */
28 | public class XFragmentSource extends Source {
29 |
30 | private Fragment mFragment;
31 |
32 | public XFragmentSource(Fragment fragment) {
33 | this.mFragment = fragment;
34 | }
35 |
36 | @Override
37 | public Context getContext() {
38 | return mFragment.getContext();
39 | }
40 |
41 | @Override
42 | public void startActivity(Intent intent) {
43 | mFragment.startActivity(intent);
44 | }
45 |
46 | @Override
47 | public void startActivityForResult(Intent intent, int requestCode) {
48 | mFragment.startActivityForResult(intent, requestCode);
49 | }
50 |
51 | @Override
52 | public boolean isShowRationalePermission(String permission) {
53 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
54 | return mFragment.shouldShowRequestPermissionRationale(permission);
55 | }
56 | }
--------------------------------------------------------------------------------
/permission/src/main/java/com/yanzhenjie/permission/task/TaskExecutor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.task;
17 |
18 | import android.app.Dialog;
19 | import android.content.Context;
20 | import android.os.AsyncTask;
21 |
22 | import java.util.concurrent.Executor;
23 | import java.util.concurrent.Executors;
24 |
25 | /**
26 | * Created by Zhenjie Yan on 2019-09-23.
27 | */
28 | public abstract class TaskExecutor extends AsyncTask {
29 |
30 | private static Executor sExecutor = Executors.newSingleThreadExecutor();
31 |
32 | private Dialog mDialog;
33 |
34 | public TaskExecutor(Context context) {
35 | this.mDialog = new WaitDialog(context);
36 | this.mDialog.setCancelable(false);
37 | }
38 |
39 | @Override
40 | protected final void onPreExecute() {
41 | if (!mDialog.isShowing()) {
42 | mDialog.show();
43 | }
44 | }
45 |
46 | @Override
47 | protected final void onPostExecute(T t) {
48 | if (mDialog.isShowing()) {
49 | mDialog.dismiss();
50 | }
51 | onFinish(t);
52 | }
53 |
54 | protected abstract void onFinish(T t);
55 |
56 | /**
57 | * Just call this method.
58 | */
59 | public final void execute() {
60 | executeOnExecutor(sExecutor);
61 | }
62 | }
--------------------------------------------------------------------------------
/permission/src/main/java/com/yanzhenjie/permission/task/WaitDialog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.task;
17 |
18 | import android.content.Context;
19 |
20 | import androidx.annotation.NonNull;
21 | import androidx.appcompat.app.AppCompatDialog;
22 |
23 | import com.yanzhenjie.permission.R;
24 |
25 | /**
26 | * Created by Zhenjie Yan on 2019-09-23.
27 | */
28 | public class WaitDialog extends AppCompatDialog {
29 |
30 | public WaitDialog(@NonNull Context context) {
31 | super(context, R.style.Permission_Theme_Dialog_Wait);
32 | setContentView(R.layout.permission_dialog_wait);
33 | }
34 | }
--------------------------------------------------------------------------------
/permission/src/main/java/com/yanzhenjie/permission/util/StringUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.util;
17 |
18 | /**
19 | * Created Zhenjie Yan on 2019-10-02.
20 | */
21 | public class StringUtils {
22 |
23 | private static final String DIGITS_TEXT = "0123456789ABCDEF";
24 | private static final char[] DIGITS_ARRAY = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
25 |
26 | public static String textToHex(String text) {
27 | StringBuilder builder = new StringBuilder();
28 | byte[] textBytes = text.getBytes();
29 | int bit;
30 |
31 | for (int i = 0; i < textBytes.length; i++) {
32 | bit = (textBytes[i] & 0x0f0) >> 4;
33 | builder.append(DIGITS_ARRAY[bit]);
34 | bit = textBytes[i] & 0x0f;
35 | builder.append(DIGITS_ARRAY[bit]);
36 | }
37 | return builder.toString().trim();
38 | }
39 |
40 | public static String hexToText(String hexText) {
41 | char[] hexArray = hexText.toCharArray();
42 | byte[] hexBytes = new byte[hexText.length() / 2];
43 | for (int i = 0; i < hexBytes.length; i++) {
44 | int n = DIGITS_TEXT.indexOf(hexArray[2 * i]) * 16;
45 | n += DIGITS_TEXT.indexOf(hexArray[2 * i + 1]);
46 | hexBytes[i] = (byte) (n & 0xff);
47 | }
48 | return new String(hexBytes);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/permission/src/main/res/drawable/permission_shape_wait_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/permission/src/main/res/layout/permission_dialog_wait.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
27 |
28 |
32 |
33 |
40 |
41 |
--------------------------------------------------------------------------------
/permission/src/main/res/values-v21/style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
35 |
36 |
--------------------------------------------------------------------------------
/permission/src/main/res/values-zh-RHK/string.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 | 日曆
20 | 相機
21 | 手機賬號/通訊錄
22 | 位置信息
23 | 麥克風
24 | 電話
25 | 通話記錄
26 | 身體傳感器
27 | 健身運動
28 | 短訊
29 | 存儲空間
30 |
31 | 正在請求授權…
32 |
--------------------------------------------------------------------------------
/permission/src/main/res/values-zh-RTW/string.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 | 日曆
20 | 相機
21 | 手機賬號/通訊錄
22 | 位置信息
23 | 麥克風
24 | 電話
25 | 通話記錄
26 | 身體感測器
27 | 健身運動
28 | 簡訊
29 | 存儲空間
30 |
31 | 正在請求授權…
32 |
--------------------------------------------------------------------------------
/permission/src/main/res/values-zh/string.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 | 日历
20 | 相机
21 | 手机账号/通讯录
22 | 位置信息
23 | 麦克风
24 | 电话
25 | 通话记录
26 | 身体传感器
27 | 健身运动
28 | 短信
29 | 存储空间
30 |
31 | 正在请求授权…
32 |
--------------------------------------------------------------------------------
/permission/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | 3dp
21 | 5dp
22 | 10dp
23 | 15dp
24 | 20dp
25 | 25dp
26 | 30dp
27 | 35dp
28 | 40dp
29 |
30 | 12sp
31 | 14sp
32 | 16sp
33 | 18sp
34 | 20sp
35 |
36 |
--------------------------------------------------------------------------------
/permission/src/main/res/values/string.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 | Calendar
20 | Camera
21 | Accounts/Contacts
22 | Location
23 | Microphone
24 | Phone
25 | Call Log
26 | Body Sensors
27 | Activity Recognition
28 | SMS
29 | Storage
30 |
31 | Requesting permissions…
32 |
--------------------------------------------------------------------------------
/permission/src/main/res/values/style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
31 |
32 |
37 |
38 |
39 |
40 |
45 |
46 |
53 |
54 |
55 |
56 |
57 |
58 |
61 |
62 |
66 |
67 |
71 |
72 |
--------------------------------------------------------------------------------
/permission/src/main/res/xml/permission_file_paths.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
24 |
25 |
28 |
29 |
32 |
33 |
36 |
37 |
40 |
41 |
44 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: rootProject.ext.plugins.application
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.android.compileSdkVersion
5 | buildToolsVersion rootProject.ext.android.buildToolsVersion
6 |
7 | defaultConfig {
8 | applicationId rootProject.ext.android.applicationId
9 | minSdkVersion rootProject.ext.android.minSdkVersion
10 | targetSdkVersion rootProject.ext.android.targetSdkVersion
11 | versionCode rootProject.ext.android.versionCode
12 | versionName rootProject.ext.android.versionName
13 | }
14 | }
15 |
16 | dependencies {
17 | implementation project(':permission')
18 |
19 | implementation rootProject.ext.dependencies.fragment
20 | }
--------------------------------------------------------------------------------
/sample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | -optimizationpasses 5
2 | -ignorewarnings
3 | -dontusemixedcaseclassnames
4 | -dontskipnonpubliclibraryclasses
5 | -dontskipnonpubliclibraryclassmembers
6 | -useuniqueclassmembernames
7 | -allowaccessmodification
8 | -dontpreverify
9 | -verbose
10 | -dontoptimize
11 | -renamesourcefileattribute SourceFile
12 | -keepattributes SourceFile,LineNumberTable
13 | -keepattributes Signature
14 | -keepattributes *Annotation*
15 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
16 | -keepclassmembers class * extends android.app.Activity {
17 | public void *(android.view.View);
18 | }
19 | -keepclassmembers enum * {
20 | public static **[] values();
21 | public static ** valueOf(java.lang.String);
22 | }
23 | -keep public class **.R$*{
24 | public static final int *;
25 | }
26 | -keepclassmembers class **.R$* {
27 | public static ;
28 | }
29 | -keepclassmembers class * {
30 | native ;
31 | }
32 | -keepclasseswithmembernames class * {
33 | native ;
34 | }
35 | -keepclasseswithmembers class * {
36 | public (android.content.Context);
37 | public (android.content.Context, android.util.AttributeSet);
38 | public (android.content.Context, android.util.AttributeSet, int);
39 | public void set*(***);
40 | public *** set*(***);
41 | public *** get*(***);
42 | public *** get*();
43 | }
44 | -keep class android.support.annotation.Keep
45 | -keep @android.support.annotation.Keep class * {*;}
46 | -keepclasseswithmembers class * {
47 | @android.support.annotation.Keep ;
48 | }
49 | -keepclasseswithmembers class * {
50 | @android.support.annotation.Keep ;
51 | }
52 | -keepclasseswithmembers class * {
53 | @android.support.annotation.Keep (...);
54 | }
55 | -keep public class * implements android.os.Parcelable{*;}
56 | -keepclasseswithmembers class * implements android.os.Parcelable {
57 | public static final android.os.Parcelable$Creator *;
58 | }
59 | -keep public class android.support.v7.widget.SearchView{*;}
60 | -keep public class * extends android.support.v4.view.ActionProvider{*;}
--------------------------------------------------------------------------------
/sample/src/main/assets/android.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yanzhenjie/AndPermission/00bedd6a3a939ce6dab22885723699025c63377b/sample/src/main/assets/android.apk
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/App.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample;
17 |
18 | import android.app.Application;
19 | import android.view.View;
20 |
21 | import com.yanzhenjie.permission.sample.widget.AlertWindow;
22 | import com.yanzhenjie.permission.sample.widget.LauncherView;
23 |
24 | /**
25 | * Created by Zhenjie Yan on 2018/5/30.
26 | */
27 | public class App extends Application {
28 |
29 | private static App _instance;
30 |
31 | @Override
32 | public void onCreate() {
33 | super.onCreate();
34 | _instance = this;
35 | }
36 |
37 | public static App get() {
38 | return _instance;
39 | }
40 |
41 | public void showLauncherView() {
42 | final AlertWindow alertWindow = new AlertWindow(this);
43 | LauncherView view = new LauncherView(this);
44 | view.setCancelClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View v) {
47 | alertWindow.dismiss();
48 | }
49 | });
50 | alertWindow.setContentView(view);
51 | alertWindow.show();
52 | }
53 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/InstallRationale.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample;
17 |
18 | import android.app.AlertDialog;
19 | import android.content.Context;
20 | import android.content.DialogInterface;
21 |
22 | import com.yanzhenjie.permission.Rationale;
23 | import com.yanzhenjie.permission.RequestExecutor;
24 |
25 | import java.io.File;
26 |
27 | /**
28 | * Created by Zhenjie Yan on 2018/4/29.
29 | */
30 | public class InstallRationale implements Rationale {
31 |
32 | @Override
33 | public void showRationale(Context context, File data, final RequestExecutor executor) {
34 | new AlertDialog.Builder(context).setCancelable(false)
35 | .setTitle(R.string.title_dialog)
36 | .setMessage(R.string.message_install_failed)
37 | .setPositiveButton(R.string.setting, new DialogInterface.OnClickListener() {
38 | @Override
39 | public void onClick(DialogInterface dialog, int which) {
40 | executor.execute();
41 | }
42 | })
43 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
44 | @Override
45 | public void onClick(DialogInterface dialog, int which) {
46 | executor.cancel();
47 | }
48 | })
49 | .show();
50 | }
51 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/NotifyListenerRationale.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample;
17 |
18 | import android.app.AlertDialog;
19 | import android.content.Context;
20 | import android.content.DialogInterface;
21 |
22 | import com.yanzhenjie.permission.Rationale;
23 | import com.yanzhenjie.permission.RequestExecutor;
24 |
25 | /**
26 | * Created by Zhenjie Yan on 2018/5/30.
27 | */
28 | public class NotifyListenerRationale implements Rationale {
29 |
30 | @Override
31 | public void showRationale(Context context, Void data, final RequestExecutor executor) {
32 | new AlertDialog.Builder(context).setCancelable(false)
33 | .setTitle(R.string.title_dialog)
34 | .setMessage(R.string.message_notification_listener_rationale)
35 | .setPositiveButton(R.string.setting, new DialogInterface.OnClickListener() {
36 | @Override
37 | public void onClick(DialogInterface dialog, int which) {
38 | executor.execute();
39 | }
40 | })
41 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
42 | @Override
43 | public void onClick(DialogInterface dialog, int which) {
44 | executor.cancel();
45 | }
46 | })
47 | .show();
48 | }
49 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/NotifyRationale.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample;
17 |
18 | import android.app.AlertDialog;
19 | import android.content.Context;
20 | import android.content.DialogInterface;
21 |
22 | import com.yanzhenjie.permission.Rationale;
23 | import com.yanzhenjie.permission.RequestExecutor;
24 |
25 | /**
26 | * Created by Zhenjie Yan on 2018/5/30.
27 | */
28 | public class NotifyRationale implements Rationale {
29 |
30 | @Override
31 | public void showRationale(Context context, Void data, final RequestExecutor executor) {
32 | new AlertDialog.Builder(context).setCancelable(false)
33 | .setTitle(R.string.title_dialog)
34 | .setMessage(R.string.message_notification_rationale)
35 | .setPositiveButton(R.string.setting, new DialogInterface.OnClickListener() {
36 | @Override
37 | public void onClick(DialogInterface dialog, int which) {
38 | executor.execute();
39 | }
40 | })
41 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
42 | @Override
43 | public void onClick(DialogInterface dialog, int which) {
44 | executor.cancel();
45 | }
46 | })
47 | .show();
48 | }
49 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/OverlayRationale.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample;
17 |
18 | import android.app.AlertDialog;
19 | import android.content.Context;
20 | import android.content.DialogInterface;
21 |
22 | import com.yanzhenjie.permission.Rationale;
23 | import com.yanzhenjie.permission.RequestExecutor;
24 |
25 | /**
26 | * Created by Zhenjie Yan on 2018/5/30.
27 | */
28 | public class OverlayRationale implements Rationale {
29 |
30 | @Override
31 | public void showRationale(Context context, Void data, final RequestExecutor executor) {
32 | new AlertDialog.Builder(context).setCancelable(false)
33 | .setTitle(R.string.title_dialog)
34 | .setMessage(R.string.message_overlay_failed)
35 | .setPositiveButton(R.string.setting, new DialogInterface.OnClickListener() {
36 | @Override
37 | public void onClick(DialogInterface dialog, int which) {
38 | executor.execute();
39 | }
40 | })
41 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
42 | @Override
43 | public void onClick(DialogInterface dialog, int which) {
44 | executor.cancel();
45 | }
46 | })
47 | .show();
48 | }
49 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/RuntimeRationale.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample;
17 |
18 | import android.app.AlertDialog;
19 | import android.content.Context;
20 | import android.content.DialogInterface;
21 | import android.text.TextUtils;
22 |
23 | import com.yanzhenjie.permission.Rationale;
24 | import com.yanzhenjie.permission.RequestExecutor;
25 | import com.yanzhenjie.permission.runtime.Permission;
26 |
27 | import java.util.List;
28 |
29 | /**
30 | * Created by Zhenjie Yan on 2018/1/1.
31 | */
32 | public final class RuntimeRationale implements Rationale> {
33 |
34 | @Override
35 | public void showRationale(Context context, List permissions, final RequestExecutor executor) {
36 | List permissionNames = Permission.transformText(context, permissions);
37 | String message = context.getString(R.string.message_permission_rationale,
38 | TextUtils.join("\n", permissionNames));
39 |
40 | new AlertDialog.Builder(context).setCancelable(false)
41 | .setTitle(R.string.title_dialog)
42 | .setMessage(message)
43 | .setPositiveButton(R.string.resume, new DialogInterface.OnClickListener() {
44 | @Override
45 | public void onClick(DialogInterface dialog, int which) {
46 | executor.execute();
47 | }
48 | })
49 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
50 | @Override
51 | public void onClick(DialogInterface dialog, int which) {
52 | executor.cancel();
53 | }
54 | })
55 | .show();
56 | }
57 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/WriteSettingRationale.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample;
17 |
18 | import android.app.AlertDialog;
19 | import android.content.Context;
20 | import android.content.DialogInterface;
21 |
22 | import com.yanzhenjie.permission.Rationale;
23 | import com.yanzhenjie.permission.RequestExecutor;
24 |
25 | /**
26 | * Created by Zhenjie Yan on 3/1/19.
27 | */
28 | public class WriteSettingRationale implements Rationale {
29 |
30 | @Override
31 | public void showRationale(Context context, Void data, final RequestExecutor executor) {
32 | new AlertDialog.Builder(context).setCancelable(false)
33 | .setTitle(R.string.title_dialog)
34 | .setMessage(R.string.message_write_setting_failed)
35 | .setPositiveButton(R.string.setting, new DialogInterface.OnClickListener() {
36 | @Override
37 | public void onClick(DialogInterface dialog, int which) {
38 | executor.execute();
39 | }
40 | })
41 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
42 | @Override
43 | public void onClick(DialogInterface dialog, int which) {
44 | executor.cancel();
45 | }
46 | })
47 | .show();
48 | }
49 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/app/NotifyListenerService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample.app;
17 |
18 | import android.os.Build;
19 | import android.service.notification.NotificationListenerService;
20 | import android.service.notification.StatusBarNotification;
21 |
22 | import androidx.annotation.RequiresApi;
23 |
24 | /**
25 | * Created by Zhenjie Yan on 2/14/19.
26 | */
27 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
28 | public class NotifyListenerService extends NotificationListenerService {
29 |
30 | @Override
31 | public void onNotificationPosted(StatusBarNotification sbn) {
32 | }
33 |
34 | @Override
35 | public void onNotificationRemoved(StatusBarNotification sbn) {
36 | }
37 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/util/FileUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample.util;
17 |
18 | import android.content.Context;
19 | import android.os.Environment;
20 | import android.text.TextUtils;
21 |
22 | import androidx.annotation.Nullable;
23 |
24 | import java.io.File;
25 |
26 | /**
27 | * Created Zhenjie Yan on 2019-10-10.
28 | */
29 | public class FileUtils {
30 |
31 | public static File getFileDir(Context context) {
32 | return getFileDir(context, null);
33 | }
34 |
35 | public static File getFileDir(Context context, @Nullable String type) {
36 | File root = context.getFilesDir();
37 | if (TextUtils.isEmpty(type)) {
38 | return root;
39 | } else {
40 | File dir = new File(root, type);
41 | createDir(dir);
42 | return dir;
43 | }
44 | }
45 |
46 | public static boolean externalAvailable() {
47 | return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
48 | }
49 |
50 | public static File getExternalDir(Context context) {
51 | return getExternalDir(context, null);
52 | }
53 |
54 | public static File getExternalDir(Context context, @Nullable String type) {
55 | if (externalAvailable()) {
56 | if (TextUtils.isEmpty(type)) {
57 | return context.getExternalFilesDir(null);
58 | }
59 |
60 | File dir = context.getExternalFilesDir(type);
61 | if (dir == null) {
62 | dir = context.getExternalFilesDir(null);
63 | dir = new File(dir, type);
64 | createDir(dir);
65 | }
66 |
67 | return dir;
68 | }
69 | throw new RuntimeException("External storage device is not available.");
70 | }
71 |
72 | public static File getRootDir() {
73 | return getRootDir(null);
74 | }
75 |
76 | public static File getRootDir(@Nullable String type) {
77 | if (externalAvailable()) {
78 | File root = Environment.getExternalStorageDirectory();
79 | File appRoot = new File(root, "AndPermission");
80 | createDir(appRoot);
81 |
82 | if (TextUtils.isEmpty(type)) {
83 | return appRoot;
84 | }
85 |
86 | File dir = new File(appRoot, type);
87 | createDir(dir);
88 |
89 | return dir;
90 | }
91 | throw new RuntimeException("External storage device is not available.");
92 | }
93 |
94 | public static void createDir(File dir) {
95 | if (dir.exists()) {
96 | if (!dir.isDirectory()) {
97 | dir.delete();
98 | }
99 | }
100 | if (!dir.exists()) {
101 | dir.mkdirs();
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/util/IOUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample.util;
17 |
18 | import java.io.Closeable;
19 | import java.io.Flushable;
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.io.OutputStream;
23 |
24 | /**
25 | * Created Zhenjie Yan on 2019-10-10.
26 | */
27 | public class IOUtils {
28 |
29 | public static void write(InputStream in, OutputStream out) throws IOException {
30 | byte[] buffer = new byte[2048];
31 | int len;
32 | while ((len = in.read(buffer)) != -1) {
33 | out.write(buffer, 0, len);
34 | out.flush();
35 | }
36 | }
37 |
38 | public static void close(Closeable closeable) {
39 | try {
40 | closeable.close();
41 | } catch (IOException e) {
42 | e.printStackTrace();
43 | }
44 | }
45 |
46 | public static void flush(Flushable flushable) {
47 | try {
48 | flushable.flush();
49 | } catch (IOException e) {
50 | e.printStackTrace();
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yanzhenjie/permission/sample/widget/LauncherView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Zhenjie Yan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.yanzhenjie.permission.sample.widget;
17 |
18 | import android.content.Context;
19 | import android.util.AttributeSet;
20 | import android.view.View;
21 | import android.widget.RelativeLayout;
22 |
23 | import com.yanzhenjie.permission.sample.R;
24 |
25 | /**
26 | * Created by Zhenjie Yan on 2018/5/30.
27 | */
28 | public class LauncherView extends RelativeLayout implements View.OnClickListener {
29 |
30 | private View.OnClickListener mCancelClickListener;
31 |
32 | public LauncherView(Context context) {
33 | this(context, null, 0);
34 | }
35 |
36 | public LauncherView(Context context, AttributeSet attrs) {
37 | this(context, attrs, 0);
38 | }
39 |
40 | public LauncherView(Context context, AttributeSet attrs, int defStyleAttr) {
41 | super(context, attrs, defStyleAttr);
42 | inflate(context, R.layout.window_launcher, this);
43 | findViewById(R.id.btn_cancel).setOnClickListener(this);
44 | }
45 |
46 | @Override
47 | public void onClick(View v) {
48 | int id = v.getId();
49 | switch (id) {
50 | case R.id.btn_cancel: {
51 | if (mCancelClickListener != null) {
52 | mCancelClickListener.onClick(v);
53 | }
54 | break;
55 | }
56 | }
57 | }
58 |
59 | public void setCancelClickListener(OnClickListener cancelClickListener) {
60 | this.mCancelClickListener = cancelClickListener;
61 | }
62 | }
--------------------------------------------------------------------------------
/sample/src/main/res/layout/window_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
23 |
24 |
31 |
32 |
39 |
40 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yanzhenjie/AndPermission/00bedd6a3a939ce6dab22885723699025c63377b/sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yanzhenjie/AndPermission/00bedd6a3a939ce6dab22885723699025c63377b/sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yanzhenjie/AndPermission/00bedd6a3a939ce6dab22885723699025c63377b/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yanzhenjie/AndPermission/00bedd6a3a939ce6dab22885723699025c63377b/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yanzhenjie/AndPermission/00bedd6a3a939ce6dab22885723699025c63377b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/values/array_string.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | - Read_Calendar
21 | - Write_Calendar
22 | - All
23 |
24 |
25 |
26 | - Read_Contacts
27 | - Write_Contacts
28 | - Get_Accounts
29 | - All
30 |
31 |
32 |
33 | - Fine Location
34 | - Coarse Location
35 | - All
36 |
37 |
38 |
39 | - Read_Phone_State
40 | - Call_Phone
41 | - Read_Phone_Numbers
42 | - Answer_Phone_Calls
43 | - Use_Sip
44 | - Add_Voicemail
45 | - All
46 |
47 |
48 |
49 | - Read_Call_Log
50 | - Write_Call_Log
51 | - Process_Outgoing_Calls
52 | - All
53 |
54 |
55 |
56 | - Send_SMS
57 | - Receive_SMS
58 | - Read_SMS
59 | - Receive_Wap_Push
60 | - Receive_MMS
61 | - All
62 |
63 |
64 |
65 | - Read_External_Storage
66 | - Write_External_Storage
67 | - All
68 |
69 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | #3F51B5
19 | #303F9F
20 | #FF4081
21 |
22 | #FFF
23 |
24 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 1dp
19 | 10dp
20 | 20dp
21 | 100dp
22 | 120dp
23 | 150dp
24 |
25 | 14sp
26 | 16sp
27 | 18sp
28 | 20sp
29 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 | AndPermission
20 |
21 | Setting
22 | Resume
23 | Cancel
24 | @android:string/ok
25 |
26 | Successful
27 | Failure
28 |
29 | Camera
30 | Contact
31 | Location
32 |
33 | Calendar
34 | Microphone
35 | Storage
36 |
37 | Phone
38 | Call Log
39 | Activity Recognition
40 | Sensors
41 | SMS
42 | Permission Setting
43 |
44 | Notification
45 | Notification Listener
46 |
47 | Install Apk
48 | AlertWindow
49 |
50 | Write System Setting
51 |
52 | Tips
53 | Grant the following permissions to continue the program:\n\n%1$s
54 | Please give us permission in the settings:\n\n%1$s
55 | The user comes back from the settings page.
56 |
57 | Your device does not allow us to pop up notifications.
58 | Your device does not allow us to access notifications.
59 |
60 | Your device is not allowed us to install apps.
61 |
62 | Your device is not allowed us to draw on other applications.
63 |
64 | Your device is not allowed us to modify the system settings.
65 |
66 | Please check the external storage device.
67 | External storage device is not available.
68 |
69 | Save failed, please try again.
70 |
71 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
30 |
31 |
35 |
36 |
39 |
40 |
44 |
45 |
49 |
50 |
51 |
52 |
56 |
57 |
60 |
61 |
64 |
65 |
71 |
72 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':permission', ':sample'
--------------------------------------------------------------------------------