diff --git a/README.md b/README.md
index adec374..0322741 100644
--- a/README.md
+++ b/README.md
@@ -8,9 +8,22 @@
# 效果图
-#使用Gradle构建时添加一下依赖即可:
+#使用Gradle构建时添加一下依赖即可
+Step 1. Add the JitPack repository to your build file
+Add it in your root build.gradle at the end of repositories:
```javascript
-compile 'com.mylhyl:acp:1.1.7'
+ allprojects {
+ repositories {
+ ...
+ maven { url 'https://jitpack.io' }
+ }
+ }
+```
+Step 2. Add the dependency
+```
+ dependencies {
+ implementation 'com.github.mylhyl:AndroidAcp:1.2.2'
+ }
```
# 使用说明
@@ -45,8 +58,6 @@ compile 'com.mylhyl:acp:1.1.7'
### [下载APK体验](/preview/sample-debug.apk)
-## QQ交流群:435173211
-
#### 版本日志
> 1.1.7 修复内存泄露
@@ -58,4 +69,4 @@ compile 'com.mylhyl:acp:1.1.7'
> 1.0.2 修复申请的权限不在`AndroidManifest.xml`配置文件时,中仍然显示`RationalMessage`对话框的问题
-> 1.0.1 修改 minSdkVersion 14
\ No newline at end of file
+> 1.0.1 修改 minSdkVersion 14
diff --git a/acp/build.gradle b/acp/build.gradle
deleted file mode 100644
index 9b2f45d..0000000
--- a/acp/build.gradle
+++ /dev/null
@@ -1,103 +0,0 @@
-apply plugin: 'com.android.library'
-apply plugin: 'com.github.dcendents.android-maven'
-apply plugin: 'com.jfrog.bintray'
-
-android {
- compileSdkVersion 23
- buildToolsVersion "23.0.3"
- defaultConfig {
- minSdkVersion 14
- targetSdkVersion 23
- versionCode 1
- versionName version
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
- lintOptions {
- abortOnError false
- }
-}
-
-def siteUrl = 'https://github.com/mylhyl/AndroidAcp'
-def gitUrl = 'https://github.com/mylhyl/AndroidAcp.git'
-
-group = "com.mylhyl"
-version = "1.1.7"
-
-install {
- repositories.mavenInstaller {
- pom {
- project {
- packaging 'aar'
- artifactId 'acp'
- name 'Simplify Android 6.0 complex permissions operation'
- url siteUrl
-
- licenses {
- license {
- name 'The Apache Software License, Version 2.0'
- url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
- }
- }
-
- developers {
- developer {
- id 'mylhyl'
- name 'mylhylAndroid'
- email 'hupei132@qq.com'
- }
- }
-
- scm {
- connection gitUrl
- developerConnection gitUrl
- url siteUrl
- }
- }
- }
- }
-}
-
-task sourcesJar(type: Jar) {
- from android.sourceSets.main.java.srcDirs
- classifier = 'sources'
-}
-
-task javadoc(type: Javadoc) {
- options.encoding = "UTF-8"
- source = android.sourceSets.main.java.srcDirs
- classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
-}
-
-task javadocJar(type: Jar, dependsOn: javadoc) {
- classifier = 'javadoc'
- from javadoc.destinationDir
-}
-
-artifacts {
- archives javadocJar
- archives sourcesJar
-}
-
-Properties properties = new Properties()
-properties.load(project.rootProject.file('local.properties').newDataInputStream())
-bintray {
- user = properties.getProperty("BINTRAY_USER")
- key = properties.getProperty("BINTRAY_KEY")
- configurations = ['archives']
- pkg {
- repo = "maven"
- name = "acp"
- websiteUrl = siteUrl
- vcsUrl = gitUrl
- licenses = ["Apache-2.0"]
- publish = true //是否发布
- }
-}
-dependencies {
- compile 'com.android.support:appcompat-v7:23.4.0'
-}
diff --git a/acp/src/androidTest/java/com/mylhyl/acp/ApplicationTest.java b/acp/src/androidTest/java/com/mylhyl/acp/ApplicationTest.java
deleted file mode 100644
index 273e514..0000000
--- a/acp/src/androidTest/java/com/mylhyl/acp/ApplicationTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.mylhyl.acp;
-
-import android.app.Application;
-import android.test.ApplicationTestCase;
-
-/**
- * Testing Fundamentals
- */
-public class ApplicationTest extends ApplicationTestCase {
- public ApplicationTest() {
- super(Application.class);
- }
-}
\ No newline at end of file
diff --git a/acp/src/main/java/com/mylhyl/acp/MiuiOs.java b/acp/src/main/java/com/mylhyl/acp/MiuiOs.java
deleted file mode 100644
index 263b3c1..0000000
--- a/acp/src/main/java/com/mylhyl/acp/MiuiOs.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.mylhyl.acp;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
-import android.text.TextUtils;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-/**
- * 参考 http://blog.csdn.net/tgbus18990140382/article/details/47058043
- * Created by hupei on 2016/7/22.
- */
-public class MiuiOs {
- public static final String UNKNOWN = "UNKNOWN";
-
- /**
- * 获取应用权限设置 Intent
- * http://blog.csdn.net/dawanganban/article/details/41749911
- *
- * @param context
- */
- public static Intent getSettingIntent(Context context) {
- // 之兼容miui v5/v6/v7 的应用权限设置页面
- if (getSystemVersionCode() >= 6) {
- Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
- intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
- intent.putExtra("extra_pkgname", context.getPackageName());
- return intent;
- }
- return null;
- }
-
- /**
- * 获取 V5/V6 后面的数字
- *
- * @return
- */
- public static int getSystemVersionCode() {
- String systemProperty = getSystemProperty();
- if (!TextUtils.isEmpty(systemProperty) && !systemProperty.equals(UNKNOWN)
- && systemProperty.length() == 2 && systemProperty.toUpperCase().startsWith("V")) {
- Integer code = 0;
- try {
- code = Integer.valueOf(systemProperty.substring(1));
- } catch (NumberFormatException e) {
- e.printStackTrace();
- }
- return code;
- }
- return 0;
- }
-
- /**
- * 判断V5/V6
- *
- * @return V5 、V6 、V7 字符
- */
- public static String getSystemProperty() {
- String line = UNKNOWN;
- BufferedReader reader = null;
- try {
- Process p = Runtime.getRuntime().exec("getprop ro.miui.ui.version.name");
- reader = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
- line = reader.readLine();
- return line;
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (reader != null)
- try {
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return line;
- }
-
- /**
- * 判断 activity 是否存在
- *
- * @param context
- * @param intent
- * @return
- */
- public static boolean isIntentAvailable(Context context, Intent intent) {
- if (intent == null) return false;
- return context.getPackageManager().queryIntentActivities(intent, 0).size() > 0;
- }
-
- /**
- * 检查手机是否是miui
- *
- * @return
- * @ref http://dev.xiaomi.com/doc/p=254/index.html
- */
- public static boolean isMIUI() {
- String device = Build.MANUFACTURER;
- if (device.equals("Xiaomi")) {
- return true;
- } else {
- return false;
- }
- }
-}
diff --git a/acp/.gitignore b/app/.gitignore
similarity index 100%
rename from acp/.gitignore
rename to app/.gitignore
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..b1ab9e9
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,31 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ applicationId "com.mylhyl.acp.sample"
+ minSdkVersion 15
+ targetSdkVersion 28
+ versionCode 1
+ versionName "20180425"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ lintOptions {
+ abortOnError false
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation project(':library')
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4'
+ releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
+ androidTestImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
+ implementation 'com.yanzhenjie.permission:support:2.0.1'
+}
diff --git a/acp/proguard-rules.pro b/app/proguard-rules.pro
similarity index 100%
rename from acp/proguard-rules.pro
rename to app/proguard-rules.pro
diff --git a/sample/src/androidTest/java/com/mylhyl/acp/sample/ApplicationTest.java b/app/src/androidTest/java/com/mylhyl/acp/sample/ApplicationTest.java
similarity index 100%
rename from sample/src/androidTest/java/com/mylhyl/acp/sample/ApplicationTest.java
rename to app/src/androidTest/java/com/mylhyl/acp/sample/ApplicationTest.java
diff --git a/sample/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
similarity index 57%
rename from sample/src/main/AndroidManifest.xml
rename to app/src/main/AndroidManifest.xml
index 9abf3a3..3c2c2e0 100644
--- a/sample/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,23 +1,31 @@
+ package="com.mylhyl.acp.sample">
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
diff --git a/sample/src/main/java/com/mylhyl/acp/sample/App.java b/app/src/main/java/com/mylhyl/acp/sample/App.java
similarity index 50%
rename from sample/src/main/java/com/mylhyl/acp/sample/App.java
rename to app/src/main/java/com/mylhyl/acp/sample/App.java
index 5e952d5..7314db5 100644
--- a/sample/src/main/java/com/mylhyl/acp/sample/App.java
+++ b/app/src/main/java/com/mylhyl/acp/sample/App.java
@@ -7,10 +7,15 @@
/**
* Created by hupei on 2016/9/5.
*/
-public class App extends Application{
+public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
+ if (LeakCanary.isInAnalyzerProcess(this)) {
+ // This process is dedicated to LeakCanary for heap analysis.
+ // You should not init your app in this process.
+ return;
+ }
LeakCanary.install(this);
}
}
diff --git a/sample/src/main/java/com/mylhyl/acp/sample/BlankActivity.java b/app/src/main/java/com/mylhyl/acp/sample/BlankActivity.java
similarity index 90%
rename from sample/src/main/java/com/mylhyl/acp/sample/BlankActivity.java
rename to app/src/main/java/com/mylhyl/acp/sample/BlankActivity.java
index da19727..61493eb 100644
--- a/sample/src/main/java/com/mylhyl/acp/sample/BlankActivity.java
+++ b/app/src/main/java/com/mylhyl/acp/sample/BlankActivity.java
@@ -1,12 +1,13 @@
package com.mylhyl.acp.sample;
import android.Manifest;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
+import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -23,6 +24,10 @@
public class BlankActivity extends AppCompatActivity {
+ public static void gotoAct(Activity act) {
+ act.startActivity(new Intent(act, BlankActivity.class));
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -31,10 +36,6 @@ protected void onCreate(Bundle savedInstanceState) {
.add(android.R.id.content, BlankFragment.newInstance()).commitAllowingStateLoss();
}
- public static void gotoAct(Activity act) {
- act.startActivity(new Intent(act, BlankActivity.class));
- }
-
public static class BlankFragment extends Fragment implements View.OnClickListener {
public BlankFragment() {
@@ -51,7 +52,8 @@ public static BlankFragment newInstance() {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
- textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup
+ .LayoutParams.MATCH_PARENT));
textView.setGravity(Gravity.CENTER);
textView.setText(R.string.hello_blank_fragment);
textView.append("\n\nFragment中申请权限");
@@ -71,11 +73,14 @@ public void onGranted() {
@Override
public void onDenied(List permissions) {
- Toast.makeText(BlankFragment.this.getActivity(), permissions.toString() + "权限拒绝", Toast.LENGTH_SHORT).show();
+ Toast.makeText(BlankFragment.this.getActivity(), permissions.toString() + "权限拒绝", Toast
+ .LENGTH_SHORT).show();
}
+
});
}
+ @SuppressLint("MissingPermission")
private void getIMEI() {
FragmentActivity activity = this.getActivity();
TelephonyManager tm = (TelephonyManager) this.getActivity().getSystemService(Activity.TELEPHONY_SERVICE);
diff --git a/sample/src/main/java/com/mylhyl/acp/sample/MainActivity.java b/app/src/main/java/com/mylhyl/acp/sample/MainActivity.java
similarity index 77%
rename from sample/src/main/java/com/mylhyl/acp/sample/MainActivity.java
rename to app/src/main/java/com/mylhyl/acp/sample/MainActivity.java
index 50004a1..ed1da67 100644
--- a/sample/src/main/java/com/mylhyl/acp/sample/MainActivity.java
+++ b/app/src/main/java/com/mylhyl/acp/sample/MainActivity.java
@@ -1,6 +1,7 @@
package com.mylhyl.acp.sample;
import android.Manifest;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -8,6 +9,7 @@
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.telephony.TelephonyManager;
+import android.util.Log;
import android.view.View;
import android.widget.Toast;
@@ -19,36 +21,32 @@
import java.util.List;
public class MainActivity extends AppCompatActivity {
+ private static final String TAG = "MainActivity";
// static final int READ_PHONE_STATE_REQUEST_CODE = 0x38;
// static final int WRITE_EXTERNAL_STORAGE_REQUEST_CODE = 0x39;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Acp.getInstance(this).request(new AcpOptions.Builder()
- .setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE
- , Manifest.permission.READ_PHONE_STATE
- , Manifest.permission.SEND_SMS)
- /*以下为自定义提示语、按钮文字
- .setDeniedMessage()
- .setDeniedCloseBtn()
- .setDeniedSettingBtn()
- .setRationalMessage()
- .setRationalBtn()*/
- .build(),
- new AcpListener() {
- @Override
- public void onGranted() {
- writeSD();
- getIMEI();
- }
+ public static File getCacheDir(String dirName, Context context) {
+ File result;
+ if (existsSdcard()) {
+ File cacheDir = context.getExternalCacheDir();
+ if (cacheDir == null) {
+ result = new File(Environment.getExternalStorageDirectory(),
+ "Android/data/" + context.getPackageName() + "/cache/" + dirName);
+ } else {
+ result = new File(cacheDir, dirName);
+ }
+ } else {
+ result = new File(context.getCacheDir(), dirName);
+ }
+ if (result.exists() || result.mkdirs()) {
+ return result;
+ } else {
+ return null;
+ }
+ }
- @Override
- public void onDenied(List permissions) {
- makeText(permissions.toString() + "权限拒绝");
- }
- });
+ public static Boolean existsSdcard() {
+ return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
public void onClickFragment(View v) {
@@ -60,12 +58,12 @@ public void onClickAll(View v) {
.setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE
, Manifest.permission.READ_PHONE_STATE
, Manifest.permission.SEND_SMS)
- /*以下为自定义提示语、按钮文字
- .setDeniedMessage()
- .setDeniedCloseBtn()
- .setDeniedSettingBtn()
- .setRationalMessage()
- .setRationalBtn()*/
+ /*以下为自定义提示语、按钮文字
+ .setDeniedMessage()
+ .setDeniedCloseBtn()
+ .setDeniedSettingBtn()
+ .setRationalMessage()
+ .setRationalBtn()*/
.build(),
new AcpListener() {
@Override
@@ -78,6 +76,7 @@ public void onGranted() {
public void onDenied(List permissions) {
makeText(permissions.toString() + "权限拒绝");
}
+
});
}
@@ -87,7 +86,8 @@ public void onClickSd(View v) {
// writeSD();
// } else {
// ActivityCompat.requestPermissions(this,
-// new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
+// new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
+// WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
// }
Acp.getInstance(this).request(new AcpOptions.Builder()
.setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)
@@ -102,6 +102,7 @@ public void onGranted() {
public void onDenied(List permissions) {
makeText(permissions.toString() + "权限拒绝");
}
+
});
}
@@ -112,13 +113,15 @@ public void onClickImei(View v) {
// getIMEI();
// } else {
// //处理“不再提醒”,判断是否需要 向用户解释,为什么要申请该权限
-// if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) {
+// if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission
+// .READ_PHONE_STATE)) {
// new AlertDialog.Builder(this).setMessage("需要申请imei")
// .setPositiveButton("申请", new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// ActivityCompat.requestPermissions(MainActivity.this,
-// new String[]{Manifest.permission.READ_PHONE_STATE}, READ_PHONE_STATE_REQUEST_CODE);
+// new String[]{Manifest.permission.READ_PHONE_STATE},
+// READ_PHONE_STATE_REQUEST_CODE);
// }
// }).create().show();
// } else {
@@ -140,6 +143,7 @@ public void onGranted() {
public void onDenied(List permissions) {
makeText(permissions.toString() + "权限拒绝");
}
+
});
}
@@ -157,24 +161,29 @@ public void onGranted() {
startActivity(intentCall);
*/
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_CALL);
- intent.setData(Uri.parse("tel:13800138000"));
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
+ try {
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_CALL);
+ intent.setData(Uri.parse("tel:13800138000"));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
@Override
public void onDenied(List permissions) {
makeText(permissions.toString() + "权限拒绝");
}
+
});
}
-
//
// @Override
-// public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+// public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]
+// grantResults) {
// super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// //用户选择允许或拒绝后,都会回调此方法
// switch (requestCode) {
@@ -201,42 +210,66 @@ public void onDenied(List permissions) {
// return PackageManager.PERMISSION_GRANTED == permissionCheck;
// }
+ public void onClickCamera(View view) {
+ Acp.getInstance(this).request(new AcpOptions.Builder()
+ .setPermissions(Manifest.permission.CAMERA)
+ .build(),
+ new AcpListener() {
+ @Override
+ public void onGranted() {
+ makeText("同意");
+ }
+
+ @Override
+ public void onDenied(List permissions) {
+ makeText(permissions.toString() + "权限拒绝");
+ }
+
+ });
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+// Acp.getInstance(this).request(new AcpOptions.Builder()
+// .setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE
+// , Manifest.permission.READ_PHONE_STATE
+// , Manifest.permission.SEND_SMS)
+// /*以下为自定义提示语、按钮文字
+// .setDeniedMessage()
+// .setDeniedCloseBtn()
+// .setDeniedSettingBtn()
+// .setRationalMessage()
+// .setRationalBtn()*/
+// .build(),
+// new AcpListener() {
+// @Override
+// public void onGranted() {
+// writeSD();
+// getIMEI();
+// }
+//
+// @Override
+// public void onDenied(List permissions) {
+// makeText(permissions.toString() + "权限拒绝");
+// }
+// });
+ }
+
private void writeSD() {
File acpDir = getCacheDir("acp", this);
if (acpDir != null)
makeText("写SD成功:" + acpDir.getAbsolutePath());
}
+ @SuppressLint("MissingPermission")
private void getIMEI() {
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if (tm != null)
makeText("读imei成功:" + tm.getDeviceId());
}
- public static File getCacheDir(String dirName, Context context) {
- File result;
- if (existsSdcard()) {
- File cacheDir = context.getExternalCacheDir();
- if (cacheDir == null) {
- result = new File(Environment.getExternalStorageDirectory(),
- "Android/data/" + context.getPackageName() + "/cache/" + dirName);
- } else {
- result = new File(cacheDir, dirName);
- }
- } else {
- result = new File(context.getCacheDir(), dirName);
- }
- if (result.exists() || result.mkdirs()) {
- return result;
- } else {
- return null;
- }
- }
-
- public static Boolean existsSdcard() {
- return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
- }
-
private void makeText(String text) {
Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..0d20661
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
similarity index 100%
rename from sample/src/main/res/mipmap-hdpi/ic_launcher.png
rename to app/src/main/res/mipmap-hdpi/ic_launcher.png
diff --git a/sample/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
similarity index 100%
rename from sample/src/main/res/mipmap-mdpi/ic_launcher.png
rename to app/src/main/res/mipmap-mdpi/ic_launcher.png
diff --git a/sample/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
similarity index 100%
rename from sample/src/main/res/mipmap-xhdpi/ic_launcher.png
rename to app/src/main/res/mipmap-xhdpi/ic_launcher.png
diff --git a/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
similarity index 100%
rename from sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
rename to app/src/main/res/mipmap-xxhdpi/ic_launcher.png
diff --git a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
similarity index 100%
rename from sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
rename to app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
diff --git a/sample/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
similarity index 100%
rename from sample/src/main/res/values-w820dp/dimens.xml
rename to app/src/main/res/values-w820dp/dimens.xml
diff --git a/sample/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
similarity index 100%
rename from sample/src/main/res/values/colors.xml
rename to app/src/main/res/values/colors.xml
diff --git a/sample/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
similarity index 100%
rename from sample/src/main/res/values/dimens.xml
rename to app/src/main/res/values/dimens.xml
diff --git a/sample/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
similarity index 100%
rename from sample/src/main/res/values/strings.xml
rename to app/src/main/res/values/strings.xml
diff --git a/sample/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
similarity index 100%
rename from sample/src/main/res/values/styles.xml
rename to app/src/main/res/values/styles.xml
diff --git a/build.gradle b/build.gradle
index 8e38983..e0597e5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,16 +1,27 @@
buildscript {
repositories {
jcenter()
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.1.2'
- classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
- classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
+ classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.novoda:bintray-release:0.8.1'
}
}
allprojects {
repositories {
jcenter()
+ maven { url "https://jitpack.io" }
+ google()
+ }
+
+ tasks.withType(Javadoc) {
+ options {
+ encoding "UTF-8"
+ charSet 'UTF-8'
+ links "http://docs.oracle.com/javase/7/docs/api"
+ failOnError false
+ }
}
}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 122a0dc..abdc840 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon Dec 28 10:00:20 PST 2015
+#Wed Apr 25 16:27:49 CST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
diff --git a/sample/.gitignore b/library/.gitignore
similarity index 100%
rename from sample/.gitignore
rename to library/.gitignore
diff --git a/library/build.gradle b/library/build.gradle
new file mode 100644
index 0000000..150641b
--- /dev/null
+++ b/library/build.gradle
@@ -0,0 +1,36 @@
+apply plugin: 'com.android.library'
+apply plugin: 'maven'
+apply plugin: 'com.novoda.bintray-release'
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 28
+ versionCode 1
+ versionName '1.2.1'
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ lintOptions {
+ abortOnError false
+ checkReleaseBuilds false
+ }
+}
+
+dependencies {
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+}
+
+publish {
+ userOrg = 'mylhyl'
+ groupId = 'com.mylhyl'
+ artifactId = 'acp'
+ publishVersion = '1.2.1'
+ desc = 'Simplify Android 6.0 complex permissions operation'
+ website = "https://github.com/mylhyl/AndroidAcp"
+}
\ No newline at end of file
diff --git a/sample/proguard-rules.pro b/library/proguard-rules.pro
similarity index 100%
rename from sample/proguard-rules.pro
rename to library/proguard-rules.pro
diff --git a/acp/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml
similarity index 87%
rename from acp/src/main/AndroidManifest.xml
rename to library/src/main/AndroidManifest.xml
index 297b5c9..08a54b1 100644
--- a/acp/src/main/AndroidManifest.xml
+++ b/library/src/main/AndroidManifest.xml
@@ -5,7 +5,6 @@
diff --git a/acp/src/main/java/com/mylhyl/acp/Acp.java b/library/src/main/java/com/mylhyl/acp/Acp.java
similarity index 60%
rename from acp/src/main/java/com/mylhyl/acp/Acp.java
rename to library/src/main/java/com/mylhyl/acp/Acp.java
index ce33a4c..b4b9849 100644
--- a/acp/src/main/java/com/mylhyl/acp/Acp.java
+++ b/library/src/main/java/com/mylhyl/acp/Acp.java
@@ -5,23 +5,14 @@
/**
* Created by hupei on 2016/4/26.
*/
-public class Acp {
-
- private static Acp mInstance;
+public final class Acp {
+ private volatile boolean mInitialized;
private AcpManager mAcpManager;
public static Acp getInstance(Context context) {
- if (mInstance == null)
- synchronized (Acp.class) {
- if (mInstance == null) {
- mInstance = new Acp(context);
- }
- }
- return mInstance;
- }
-
- private Acp(Context context) {
- mAcpManager = new AcpManager(context.getApplicationContext());
+ Acp instance = HolderClass.instance;
+ instance.init(context);
+ return instance;
}
/**
@@ -36,7 +27,23 @@ public void request(AcpOptions options, AcpListener acpListener) {
mAcpManager.request(options, acpListener);
}
+ public void onDestroy() {
+ mAcpManager.onDestroy();
+ }
+
AcpManager getAcpManager() {
return mAcpManager;
}
+
+ private void init(Context context) {
+ if (mInitialized) {
+ return;
+ }
+ mAcpManager = new AcpManager(context.getApplicationContext());
+ mInitialized = true;
+ }
+
+ private static class HolderClass {
+ private static final Acp instance = new Acp();
+ }
}
diff --git a/acp/src/main/java/com/mylhyl/acp/AcpActivity.java b/library/src/main/java/com/mylhyl/acp/AcpActivity.java
similarity index 100%
rename from acp/src/main/java/com/mylhyl/acp/AcpActivity.java
rename to library/src/main/java/com/mylhyl/acp/AcpActivity.java
diff --git a/acp/src/main/java/com/mylhyl/acp/AcpListener.java b/library/src/main/java/com/mylhyl/acp/AcpListener.java
similarity index 94%
rename from acp/src/main/java/com/mylhyl/acp/AcpListener.java
rename to library/src/main/java/com/mylhyl/acp/AcpListener.java
index 12a5017..8639ca1 100644
--- a/acp/src/main/java/com/mylhyl/acp/AcpListener.java
+++ b/library/src/main/java/com/mylhyl/acp/AcpListener.java
@@ -7,7 +7,7 @@
*/
public interface AcpListener {
/**
- *同意
+ * 同意
*/
void onGranted();
@@ -15,4 +15,5 @@ public interface AcpListener {
* 拒绝
*/
void onDenied(List permissions);
+
}
diff --git a/acp/src/main/java/com/mylhyl/acp/AcpManager.java b/library/src/main/java/com/mylhyl/acp/AcpManager.java
similarity index 70%
rename from acp/src/main/java/com/mylhyl/acp/AcpManager.java
rename to library/src/main/java/com/mylhyl/acp/AcpManager.java
index a9775b2..27d3bef 100644
--- a/acp/src/main/java/com/mylhyl/acp/AcpManager.java
+++ b/library/src/main/java/com/mylhyl/acp/AcpManager.java
@@ -2,17 +2,16 @@
import android.app.Activity;
import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.net.Uri;
import android.os.Build;
-import android.provider.Settings;
import android.util.Log;
+import com.mylhyl.acp.os.OsHelper;
+
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -25,25 +24,95 @@ class AcpManager {
private static final String TAG = "AcpManager";
private static final int REQUEST_CODE_PERMISSION = 0x38;
private static final int REQUEST_CODE_SETTING = 0x39;
- private Context mContext;
- private Activity mActivity;
- private AcpService mService;
- private AcpOptions mOptions;
- private AcpListener mCallback;
private final List mDeniedPermissions = new LinkedList<>();
private final Set mManifestPermissions = new HashSet<>(1);
+ private Context appContext;
+ private Activity internalActivity;
+ private AcpOptions mOptions;
+ private AcpListener mListener;
AcpManager(Context context) {
- mContext = context;
- mService = new AcpService();
+ appContext = context;
getManifestPermissions();
}
+ /**
+ * 开始请求
+ *
+ * @param options
+ * @param acpListener
+ */
+ synchronized void request(AcpOptions options, AcpListener acpListener) {
+ mListener = acpListener;
+ mOptions = options;
+ checkSelfPermission();
+ }
+
+ /**
+ * 检查权限是否存在拒绝不再提示
+ *
+ * @param activity
+ */
+ synchronized void checkRequestPermissionRationale(Activity activity) {
+ internalActivity = activity;
+ boolean rationale = false;
+ //如果有拒绝则提示申请理由提示框,否则直接向系统请求权限
+ for (String permission : mDeniedPermissions) {
+ rationale = rationale || AcpService.shouldShowRequestPermissionRationale(internalActivity, permission);
+ }
+ Log.i(TAG, "rationale = " + rationale);
+ String[] permissions = mDeniedPermissions.toArray(new String[mDeniedPermissions.size()]);
+ if (rationale) showRationalDialog(permissions);
+ else requestPermissions(permissions);
+ }
+
+ /**
+ * 响应向系统请求权限结果
+ *
+ * @param requestCode
+ * @param permissions
+ * @param grantResults
+ */
+ synchronized void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ switch (requestCode) {
+ case REQUEST_CODE_PERMISSION:
+ LinkedList grantedPermissions = new LinkedList<>();
+ LinkedList deniedPermissions = new LinkedList<>();
+ for (int i = 0; i < permissions.length; i++) {
+ String permission = permissions[i];
+ if (grantResults[i] == PackageManager.PERMISSION_GRANTED)
+ grantedPermissions.add(permission);
+ else deniedPermissions.add(permission);
+ }
+ //全部允许才回调 onGranted 否则只要有一个拒绝都回调 onDenied
+ if (!grantedPermissions.isEmpty() && deniedPermissions.isEmpty()) {
+ if (mListener != null) {
+ mListener.onGranted();
+ }
+ } else if (!deniedPermissions.isEmpty()) showDeniedDialog(deniedPermissions);
+ break;
+ }
+ }
+
+ /**
+ * 响应设置权限返回结果
+ *
+ * @param requestCode
+ * @param resultCode
+ * @param data
+ */
+ synchronized void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (mListener == null || mOptions == null || requestCode != REQUEST_CODE_SETTING) {
+ return;
+ }
+ checkSelfPermission();
+ }
+
private synchronized void getManifestPermissions() {
PackageInfo packageInfo = null;
try {
- packageInfo = mContext.getPackageManager().getPackageInfo(
- mContext.getPackageName(), PackageManager.GET_PERMISSIONS);
+ packageInfo = appContext.getPackageManager().getPackageInfo(appContext.getPackageName()
+ , PackageManager.GET_PERMISSIONS);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
@@ -57,18 +126,6 @@ private synchronized void getManifestPermissions() {
}
}
- /**
- * 开始请求
- *
- * @param options
- * @param acpListener
- */
- synchronized void request(AcpOptions options, AcpListener acpListener) {
- mCallback = acpListener;
- mOptions = options;
- checkSelfPermission();
- }
-
/**
* 检查权限
*/
@@ -76,29 +133,31 @@ private synchronized void checkSelfPermission() {
mDeniedPermissions.clear();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.i(TAG, "Build.VERSION.SDK_INT < Build.VERSION_CODES.M");
- if (mCallback != null)
- mCallback.onGranted();
- onDestroy();
+ if (mListener != null) {
+ mListener.onGranted();
+ }
return;
}
String[] permissions = mOptions.getPermissions();
for (String permission : permissions) {
//检查申请的权限是否在 AndroidManifest.xml 中
if (mManifestPermissions.contains(permission)) {
- int checkSelfPermission = mService.checkSelfPermission(mContext, permission);
+ int checkSelfPermission = AcpService.checkSelfPermission(appContext, permission);
Log.i(TAG, "checkSelfPermission = " + checkSelfPermission);
//如果是拒绝状态则装入拒绝集合中
if (checkSelfPermission == PackageManager.PERMISSION_DENIED) {
mDeniedPermissions.add(permission);
}
+ } else {
+ throw new RuntimeException("AndroidManifest.xml no uses permission " + permission);
}
}
//检查如果没有一个拒绝响应 onGranted 回调
if (mDeniedPermissions.isEmpty()) {
Log.i(TAG, "mDeniedPermissions.isEmpty()");
- if (mCallback != null)
- mCallback.onGranted();
- onDestroy();
+ if (mListener != null) {
+ mListener.onGranted();
+ }
return;
}
startAcpActivity();
@@ -108,27 +167,9 @@ private synchronized void checkSelfPermission() {
* 启动处理权限过程的 Activity
*/
private synchronized void startAcpActivity() {
- Intent intent = new Intent(mContext, AcpActivity.class);
+ Intent intent = new Intent(appContext, AcpActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(intent);
- }
-
- /**
- * 检查权限是否存在拒绝不再提示
- *
- * @param activity
- */
- synchronized void checkRequestPermissionRationale(Activity activity) {
- mActivity = activity;
- boolean rationale = false;
- //如果有拒绝则提示申请理由提示框,否则直接向系统请求权限
- for (String permission : mDeniedPermissions) {
- rationale = rationale || mService.shouldShowRequestPermissionRationale(mActivity, permission);
- }
- Log.i(TAG, "rationale = " + rationale);
- String[] permissions = mDeniedPermissions.toArray(new String[mDeniedPermissions.size()]);
- if (rationale) showRationalDialog(permissions);
- else requestPermissions(permissions);
+ appContext.startActivity(intent);
}
/**
@@ -137,14 +178,17 @@ synchronized void checkRequestPermissionRationale(Activity activity) {
* @param permissions
*/
private synchronized void showRationalDialog(final String[] permissions) {
- new AlertDialog.Builder(mActivity)
+ AlertDialog alertDialog = new AlertDialog.Builder(internalActivity)
.setMessage(mOptions.getRationalMessage())
.setPositiveButton(mOptions.getRationalBtnText(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissions);
}
- }).show();
+ }).create();
+ alertDialog.setCancelable(mOptions.isDialogCancelable());
+ alertDialog.setCanceledOnTouchOutside(mOptions.isDialogCanceledOnTouchOutside());
+ alertDialog.show();
}
/**
@@ -153,35 +197,7 @@ public void onClick(DialogInterface dialog, int which) {
* @param permissions
*/
private synchronized void requestPermissions(String[] permissions) {
- mService.requestPermissions(mActivity, permissions, REQUEST_CODE_PERMISSION);
- }
-
- /**
- * 响应向系统请求权限结果
- *
- * @param requestCode
- * @param permissions
- * @param grantResults
- */
- synchronized void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
- switch (requestCode) {
- case REQUEST_CODE_PERMISSION:
- LinkedList grantedPermissions = new LinkedList<>();
- LinkedList deniedPermissions = new LinkedList<>();
- for (int i = 0; i < permissions.length; i++) {
- String permission = permissions[i];
- if (grantResults[i] == PackageManager.PERMISSION_GRANTED)
- grantedPermissions.add(permission);
- else deniedPermissions.add(permission);
- }
- //全部允许才回调 onGranted 否则只要有一个拒绝都回调 onDenied
- if (!grantedPermissions.isEmpty() && deniedPermissions.isEmpty()) {
- if (mCallback != null)
- mCallback.onGranted();
- onDestroy();
- } else if (!deniedPermissions.isEmpty()) showDeniedDialog(deniedPermissions);
- break;
- }
+ AcpService.requestPermissions(internalActivity, permissions, REQUEST_CODE_PERMISSION);
}
/**
@@ -190,15 +206,14 @@ synchronized void onRequestPermissionsResult(int requestCode, String[] permissio
* @param permissions
*/
private synchronized void showDeniedDialog(final List permissions) {
- new AlertDialog.Builder(mActivity)
+ AlertDialog alertDialog = new AlertDialog.Builder(internalActivity)
.setMessage(mOptions.getDeniedMessage())
- .setCancelable(false)
.setNegativeButton(mOptions.getDeniedCloseBtn(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
- if (mCallback != null)
- mCallback.onDenied(permissions);
- onDestroy();
+ if (mListener != null) {
+ mListener.onDenied(permissions);
+ }
}
})
.setPositiveButton(mOptions.getDeniedSettingBtn(), new DialogInterface.OnClickListener() {
@@ -206,60 +221,27 @@ public void onClick(DialogInterface dialogInterface, int i) {
public void onClick(DialogInterface dialog, int which) {
startSetting();
}
- }).show();
+ }).create();
+ alertDialog.setCancelable(mOptions.isDialogCancelable());
+ alertDialog.setCanceledOnTouchOutside(mOptions.isDialogCanceledOnTouchOutside());
+ alertDialog.show();
}
/**
* 摧毁本库的 AcpActivity
*/
- private void onDestroy() {
- if (mActivity != null) {
- mActivity.finish();
- mActivity = null;
+ void onDestroy() {
+ if (internalActivity != null) {
+ internalActivity.finish();
+ internalActivity = null;
}
- mCallback = null;
+ mListener = null;
}
/**
* 跳转到设置界面
*/
private void startSetting() {
- if (MiuiOs.isMIUI()) {
- Intent intent = MiuiOs.getSettingIntent(mActivity);
- if (MiuiOs.isIntentAvailable(mActivity, intent)) {
- mActivity.startActivityForResult(intent, REQUEST_CODE_SETTING);
- return;
- }
- }
- try {
- Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
- .setData(Uri.parse("package:" + mActivity.getPackageName()));
- mActivity.startActivityForResult(intent, REQUEST_CODE_SETTING);
- } catch (ActivityNotFoundException e) {
- e.printStackTrace();
- try {
- Intent intent = new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
- mActivity.startActivityForResult(intent, REQUEST_CODE_SETTING);
- } catch (Exception e1) {
- e1.printStackTrace();
- }
- }
-
- }
-
- /**
- * 响应设置权限返回结果
- *
- * @param requestCode
- * @param resultCode
- * @param data
- */
- synchronized void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (mCallback == null || mOptions == null
- || requestCode != REQUEST_CODE_SETTING) {
- onDestroy();
- return;
- }
- checkSelfPermission();
+ OsHelper.startSetting(internalActivity, REQUEST_CODE_SETTING);
}
}
diff --git a/acp/src/main/java/com/mylhyl/acp/AcpOptions.java b/library/src/main/java/com/mylhyl/acp/AcpOptions.java
similarity index 80%
rename from acp/src/main/java/com/mylhyl/acp/AcpOptions.java
rename to library/src/main/java/com/mylhyl/acp/AcpOptions.java
index 4468991..cc82b6d 100644
--- a/acp/src/main/java/com/mylhyl/acp/AcpOptions.java
+++ b/library/src/main/java/com/mylhyl/acp/AcpOptions.java
@@ -10,6 +10,8 @@ public final class AcpOptions {
private String mDeniedSettingBtn;
private String mRationalBtn;
private String[] mPermissions;
+ private boolean mDialogCancelable;
+ private boolean mDialogCanceledOnTouchOutside;
private AcpOptions(Builder builder) {
mRationalMessage = builder.mRationalMessage;
@@ -17,7 +19,9 @@ private AcpOptions(Builder builder) {
mDeniedCloseBtn = builder.mDeniedCloseBtn;
mDeniedSettingBtn = builder.mDeniedSettingBtn;
mRationalBtn = builder.mRationalBtn;
- this.mPermissions = builder.mPermissions;
+ mPermissions = builder.mPermissions;
+ mDialogCancelable = builder.dialogCancelable;
+ mDialogCanceledOnTouchOutside = builder.dialogCanceledOnTouchOutside;
}
public String getRationalMessage() {
@@ -44,6 +48,14 @@ public String[] getPermissions() {
return mPermissions;
}
+ public boolean isDialogCancelable() {
+ return mDialogCancelable;
+ }
+
+ public boolean isDialogCanceledOnTouchOutside() {
+ return mDialogCanceledOnTouchOutside;
+ }
+
public static class Builder {
private static final String DEF_RATIONAL_MESSAGE = "此功能需要您授权,否则将不能正常使用";
private static final String DEF_DENIED_MESSAGE = "您拒绝权限申请,此功能将不能正常使用,您可以去设置页面重新授权";
@@ -56,6 +68,8 @@ public static class Builder {
private String mDeniedSettingBtn = DEF_DENIED_SETTINGS_BTN_TEXT;
private String mRationalBtn = DEF_RATIONAL_BTN_TEXT;
private String[] mPermissions;
+ private boolean dialogCancelable = false;
+ private boolean dialogCanceledOnTouchOutside = false;
/**
* 申请权限理由框提示语
@@ -123,6 +137,16 @@ public Builder setPermissions(String... mPermissions) {
return this;
}
+ public Builder setDialogCancelable(boolean dialogCancelable) {
+ this.dialogCancelable = dialogCancelable;
+ return this;
+ }
+
+ public Builder setDialogCanceledOnTouchOutside(boolean dialogCanceledOnTouchOutside) {
+ this.dialogCanceledOnTouchOutside = dialogCanceledOnTouchOutside;
+ return this;
+ }
+
public AcpOptions build() {
if (this.mPermissions == null || this.mPermissions.length == 0) {
throw new IllegalArgumentException("mPermissions no found...");
diff --git a/acp/src/main/java/com/mylhyl/acp/AcpService.java b/library/src/main/java/com/mylhyl/acp/AcpService.java
similarity index 85%
rename from acp/src/main/java/com/mylhyl/acp/AcpService.java
rename to library/src/main/java/com/mylhyl/acp/AcpService.java
index 3a4fce1..acfc1b2 100644
--- a/acp/src/main/java/com/mylhyl/acp/AcpService.java
+++ b/library/src/main/java/com/mylhyl/acp/AcpService.java
@@ -13,7 +13,10 @@
/**
* Created by hupei on 2016/4/26.
*/
-class AcpService {
+final class AcpService {
+ private AcpService() {
+ //no instance
+ }
private static final String TAG = "AcpService";
/**
@@ -23,7 +26,7 @@ class AcpService {
* @param permission
* @return
*/
- int checkSelfPermission(Context context, String permission) {
+ static int checkSelfPermission(Context context, String permission) {
try {
final PackageInfo info = context.getPackageManager().getPackageInfo(
context.getPackageName(), 0);
@@ -49,7 +52,7 @@ int checkSelfPermission(Context context, String permission) {
* @param permissions
* @param requestCode
*/
- void requestPermissions(Activity activity, String[] permissions, int requestCode) {
+ static void requestPermissions(Activity activity, String[] permissions, int requestCode) {
ActivityCompat.requestPermissions(activity, permissions, requestCode);
}
@@ -60,7 +63,7 @@ void requestPermissions(Activity activity, String[] permissions, int requestCode
* @param permission
* @return
*/
- boolean shouldShowRequestPermissionRationale(Activity activity, String permission) {
+ static boolean shouldShowRequestPermissionRationale(Activity activity, String permission) {
boolean shouldShowRational = ActivityCompat.shouldShowRequestPermissionRationale(activity, permission);
Log.i(TAG, "shouldShowRational = " + shouldShowRational);
return shouldShowRational;
diff --git a/library/src/main/java/com/mylhyl/acp/os/HuaWei.java b/library/src/main/java/com/mylhyl/acp/os/HuaWei.java
new file mode 100644
index 0000000..3c7bfdc
--- /dev/null
+++ b/library/src/main/java/com/mylhyl/acp/os/HuaWei.java
@@ -0,0 +1,33 @@
+package com.mylhyl.acp.os;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+/**
+ * Created by hupei on 2019/5/21 20:30.
+ */
+public class HuaWei implements SettingPage {
+
+ private Context context;
+
+ public HuaWei(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public Intent createIntent() throws PackageManager.NameNotFoundException {
+
+ Intent intent = new Intent();
+ intent.putExtra("packageName", context.getPackageName());
+ intent.putExtra(EXTRA_PKG_NAME, context.getPackageName());
+ intent.putExtra(EXTRA_PKG, context.getPackageName());
+
+ intent.setClassName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+
+ return null;
+ }
+}
diff --git a/library/src/main/java/com/mylhyl/acp/os/MeiZu.java b/library/src/main/java/com/mylhyl/acp/os/MeiZu.java
new file mode 100644
index 0000000..d136231
--- /dev/null
+++ b/library/src/main/java/com/mylhyl/acp/os/MeiZu.java
@@ -0,0 +1,45 @@
+package com.mylhyl.acp.os;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+/**
+ * Created by hupei on 2019/5/21 20:54.
+ */
+public class MeiZu implements SettingPage {
+
+ private static final String PKG = "com.meizu.safe";
+ private static final String L_MAIN_CLS = "com.meizu.safe.SecurityMainActivity";
+ private static final String N_MAIN_CLS = "com.meizu.safe.permission.PermissionMainActivity";
+
+ private Context context;
+
+ public MeiZu(Context context) {
+ this.context = context;
+ }
+
+ private static String getCls() {
+ if (OsHelper.isAndroidL()) {
+ return L_MAIN_CLS;
+ } else {
+ return N_MAIN_CLS;
+ }
+ }
+
+ @Override
+ public Intent createIntent() throws PackageManager.NameNotFoundException {
+
+ Intent intent = new Intent();
+ intent.putExtra("packageName", context.getPackageName());
+ intent.putExtra(EXTRA_PKG_NAME, context.getPackageName());
+ intent.putExtra(EXTRA_PKG, context.getPackageName());
+
+ intent.setClassName(PKG, getCls());
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+
+ return null;
+ }
+}
diff --git a/library/src/main/java/com/mylhyl/acp/os/Native.java b/library/src/main/java/com/mylhyl/acp/os/Native.java
new file mode 100644
index 0000000..a907a8a
--- /dev/null
+++ b/library/src/main/java/com/mylhyl/acp/os/Native.java
@@ -0,0 +1,28 @@
+package com.mylhyl.acp.os;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.Settings;
+
+/**
+ * Created by hupei on 2019/5/21 20:14.
+ */
+public class Native implements SettingPage {
+
+ private Context context;
+
+ public Native(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public Intent createIntent() {
+
+ Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ Uri uri = Uri.fromParts(EXTRA_PKG, context.getPackageName(), null);
+ intent.setData(uri);
+
+ return intent;
+ }
+}
diff --git a/library/src/main/java/com/mylhyl/acp/os/Oppo.java b/library/src/main/java/com/mylhyl/acp/os/Oppo.java
new file mode 100644
index 0000000..c418d97
--- /dev/null
+++ b/library/src/main/java/com/mylhyl/acp/os/Oppo.java
@@ -0,0 +1,56 @@
+package com.mylhyl.acp.os;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+/**
+ * Created by hupei on 2019/5/21 20:36.
+ */
+public class Oppo implements SettingPage {
+
+ private Context context;
+
+ public Oppo(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public Intent createIntent() throws PackageManager.NameNotFoundException {
+
+ Intent intent = new Intent();
+ intent.putExtra("packageName", context.getPackageName());
+ intent.putExtra(EXTRA_PKG_NAME, context.getPackageName());
+ intent.putExtra(EXTRA_PKG, context.getPackageName());
+
+ intent.setClassName("com.color.safecenter", "com.color.safecenter.permission.PermissionManagerActivity");
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+
+ intent.setClassName("com.oppo.safe", "com.oppo.safe.permission.PermissionAppListActivity");
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+
+ intent.setClassName("com.coloros.safecenter"
+ , "com.coloros.safecenter.permission.singlepage.PermissionSinglePageActivity");
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+
+
+ intent.setClassName("com.coloros.securitypermission"
+ , "com.coloros.securitypermission.permission.PermissionGroupsActivity");
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+
+ intent.setClassName("com.coloros.securitypermission"
+ , "com.coloros.securitypermission.permission.PermissionAppAllPermissionActivity");
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+ return null;
+ }
+}
diff --git a/library/src/main/java/com/mylhyl/acp/os/OsHelper.java b/library/src/main/java/com/mylhyl/acp/os/OsHelper.java
new file mode 100644
index 0000000..84bd0f4
--- /dev/null
+++ b/library/src/main/java/com/mylhyl/acp/os/OsHelper.java
@@ -0,0 +1,90 @@
+package com.mylhyl.acp.os;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Build;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Created by hupei on 2019/5/21 20:26.
+ */
+public final class OsHelper {
+ private static final String OS_HUAWEI = "HUAWEI";
+ private static final String OS_XIAOMI = "XiaoMi";
+ private static final String OS_OPPO = "Oppo";
+ private static final String OS_VIVO = "vivo";
+ private static final String OS_MEIZU = "meizu";
+ private static final String OS_NATIVE = Build.MANUFACTURER;
+
+ private OsHelper() {
+ //no instance
+ }
+
+ public static Intent getIntentNative(Context context) {
+ return new Native(context).createIntent();
+ }
+
+ public static void startSetting(Activity activity, int requestCode) {
+ Intent intent = null;
+ try {
+ SettingPage settingPage = null;
+ if (OS_HUAWEI.equalsIgnoreCase(OS_NATIVE)) {
+ settingPage = new HuaWei(activity);
+ } else if (OS_OPPO.equalsIgnoreCase(OS_NATIVE)) {
+ settingPage = new Oppo(activity);
+ } else if (OS_VIVO.equalsIgnoreCase(OS_NATIVE)) {
+ settingPage = new Vivo(activity);
+ } else if (OS_XIAOMI.equalsIgnoreCase(OS_NATIVE)) {
+ settingPage = new XiaoMi(activity);
+ } else if (OS_MEIZU.equalsIgnoreCase(OS_NATIVE)) {
+ settingPage = new MeiZu(activity);
+ }
+ intent = settingPage.createIntent();
+ } catch (Exception e) {
+ Log.e("acp", "OsHelper startSetting " + OS_NATIVE + " " + e.getMessage());
+ }
+ if (intent == null) {
+ intent = getIntentNative(activity);
+ }
+ try {
+ activity.startActivityForResult(intent, requestCode);
+ } catch (Exception e) {
+ Log.e("acp", "OsHelper startActivityForResult " + OS_NATIVE + " " + e.getMessage());
+ intent = new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
+ activity.startActivityForResult(intent, requestCode);
+ }
+ }
+
+ static boolean isAndroidL() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT < Build.VERSION_CODES.M;
+ }
+
+ /**
+ * 判断 activity 是否存在
+ *
+ * @param context
+ * @param intent
+ * @return
+ */
+ static boolean isIntentAvailable(Context context, Intent intent) {
+ if (intent == null) return false;
+ PackageManager packageManager = context.getPackageManager();
+ List resolveInfo = packageManager.queryIntentActivities(intent
+ , PackageManager.MATCH_DEFAULT_ONLY);
+ return resolveInfo.size() > 0;
+ }
+
+ static boolean isActivityExported(Context context, Intent intent) throws PackageManager.NameNotFoundException {
+ PackageManager packageManager = context.getPackageManager();
+ ActivityInfo activityInfo = packageManager.getActivityInfo(intent.getComponent()
+ , PackageManager.MATCH_DEFAULT_ONLY);
+ return activityInfo != null && activityInfo.exported;
+ }
+}
diff --git a/library/src/main/java/com/mylhyl/acp/os/SettingPage.java b/library/src/main/java/com/mylhyl/acp/os/SettingPage.java
new file mode 100644
index 0000000..4386bf9
--- /dev/null
+++ b/library/src/main/java/com/mylhyl/acp/os/SettingPage.java
@@ -0,0 +1,16 @@
+package com.mylhyl.acp.os;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+/**
+ * Created by hupei on 2019/5/21 20:03.
+ */
+public interface SettingPage {
+
+ String EXTRA_PKG = "package";
+ String EXTRA_PKG_NAME = "packagename";
+
+ Intent createIntent() throws PackageManager.NameNotFoundException;
+
+}
diff --git a/library/src/main/java/com/mylhyl/acp/os/Vivo.java b/library/src/main/java/com/mylhyl/acp/os/Vivo.java
new file mode 100644
index 0000000..1970205
--- /dev/null
+++ b/library/src/main/java/com/mylhyl/acp/os/Vivo.java
@@ -0,0 +1,46 @@
+package com.mylhyl.acp.os;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+/**
+ * Created by hupei on 2019/5/21 20:04.
+ */
+public class Vivo implements SettingPage {
+
+ private Context context;
+
+ public Vivo(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public Intent createIntent() throws PackageManager.NameNotFoundException {
+
+ Intent intent = new Intent();
+ intent.putExtra("packageName", context.getPackageName());
+ intent.putExtra(EXTRA_PKG_NAME, context.getPackageName());
+ intent.putExtra(EXTRA_PKG, context.getPackageName());
+
+ intent.setClassName("com.vivo.permissionmanager"
+ , "com.vivo.permissionmanager.activity.SoftPermissionDetailActivity");
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+
+ intent.setClassName("com.iqoo.secure"
+ , "com.iqoo.secure.safeguard.SoftPermissionDetailActivity");
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+
+ intent.setClassName("com.iqoo.secure", "com.iqoo.secure.MainActivity");
+ if (OsHelper.isIntentAvailable(context, intent) && OsHelper.isActivityExported(context, intent)) {
+ return intent;
+ }
+
+ return null;
+ }
+
+}
diff --git a/library/src/main/java/com/mylhyl/acp/os/XiaoMi.java b/library/src/main/java/com/mylhyl/acp/os/XiaoMi.java
new file mode 100644
index 0000000..23a0bb5
--- /dev/null
+++ b/library/src/main/java/com/mylhyl/acp/os/XiaoMi.java
@@ -0,0 +1,68 @@
+package com.mylhyl.acp.os;
+
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * Created by hupei on 2019/5/21 20:41.
+ */
+public class XiaoMi implements SettingPage {
+
+ private static final String PKG = "com.miui.securitycenter";
+ private static final String EXTRA_MIUI_PKG = "extra_pkgname";
+ private static final String MIUI_ACTION = "miui.intent.action.APP_PERM_EDITOR";
+ private static final String MIUI8_MAIN_CLS = "com.miui.securityscan.MainActivity";
+ private static final String MIUI_MAIN_CLS = "com.miui.permcenter.permissions.AppPermissionsEditorActivity";
+ private static final String MIUI_COMMAND_VERSION = "getprop ro.miui.ui.version.name";
+
+ private Context context;
+
+ public XiaoMi(Context context) {
+ this.context = context;
+ }
+
+ private static String getSystemProperty() {
+ String line = "";
+ BufferedReader input = null;
+ try {
+ Process p = Runtime.getRuntime().exec(MIUI_COMMAND_VERSION);
+ input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
+ line = input.readLine();
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ return "";
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return line;
+ }
+
+ @Override
+ public Intent createIntent() throws ActivityNotFoundException {
+ Intent intent = new Intent();
+ String systemProperty = getSystemProperty();
+ if (systemProperty.contains("7") || systemProperty.contains("6") || systemProperty.contains("5")) {
+ intent = new Intent(MIUI_ACTION);
+ intent.setComponent(new ComponentName(PKG, MIUI_MAIN_CLS));
+ intent.putExtra(EXTRA_MIUI_PKG, context.getPackageName());
+ } else {
+ // miui 8
+ intent.putExtra(EXTRA_PKG, context.getPackageName());
+ intent.setComponent(new ComponentName(PKG, MIUI8_MAIN_CLS));
+ }
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return intent;
+ }
+}
diff --git a/acp/src/main/res/values/style.xml b/library/src/main/res/values/style.xml
similarity index 100%
rename from acp/src/main/res/values/style.xml
rename to library/src/main/res/values/style.xml
diff --git a/sample/build.gradle b/sample/build.gradle
deleted file mode 100644
index 3889f38..0000000
--- a/sample/build.gradle
+++ /dev/null
@@ -1,28 +0,0 @@
-apply plugin: 'com.android.application'
-
-android {
- compileSdkVersion 23
- buildToolsVersion "23.0.2"
-
- defaultConfig {
- applicationId "com.mylhyl.acp.sample"
- minSdkVersion 15
- targetSdkVersion 23
- versionCode 1
- versionName "1.0"
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-}
-
-dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- compile project(':acp')
- compile 'com.android.support:appcompat-v7:23.1.1'
- compile 'com.android.support:support-v4:23.1.1'
- debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
-}
diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml
deleted file mode 100644
index a5f3418..0000000
--- a/sample/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/settings.gradle b/settings.gradle
index 7d3916c..3306997 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':sample', ':acp'
+include ':app', ':library'