十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
Grant里面一共有三个类,分别是:
嘉鱼ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:13518219792(备注:SSL证书合作)期待与您的合作!
(1)Permissions
[java] view plain
copy
package com.anthonycr.grant;
/**
* Enum class to handle the different states
* of permissions since the PackageManager only
* has a granted and denied state.
*/
enum Permissions {
GRANTED,
DENIED,
NOT_FOUND
}
这是一个枚举类,用来对应三种状态:已授权,授权失败,未发现的权限
(2)PermissionsManager
package com.anthonycr.grant;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.util.Log;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
这个类主要是获取单例下的权限管理类,然后通过内部方法进行权限管理
(3)PermissionsResultAction
[java] view plain
copy
package com.anthonycr.grant;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.util.Log;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/
在 Android 中,如果要使用系统限制的权限(比如 android.permission.WRITE_SECURE_SETTINGS),我们需要把程序安装到 /system/app/ 下。
下面以 SecureSetting.apk 为例,演示这个操作。需要准备一台已经获得 Root 权限的手机。
1、通过 USB 连接手机和电脑。
2、使用 adb 控制手机。
源码打印?
1. $ adb push SecureSetting.apk /sdcard/ // 上传要安装的文件,为安装做准备。
2. $ adb shell
3. $ su // 切换到 root 用户。如果没有获得 Root 权限,这一步不会成功。
4. # mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system // 让分区可写。
5. # cat /sdcard/SecureSetting.apk /system/app/SecureSetting.apk // 这一步可以用 cp 实现,但一般设备中没有包含该命令。如果使用 mv 会出现错误:failed on '/sdcard/NetWork.apk' - Cross-device link。
6. # mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system // 还原分区属性,只读。
7. # exit
8. $ exit
$ adb push SecureSetting.apk /sdcard/ // 上传要安装的文件,为安装做准备。
$ adb shell
$ su // 切换到 root 用户。如果没有获得 Root 权限,这一步不会成功。
# mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system // 让分区可写。
# cat /sdcard/SecureSetting.apk /system/app/SecureSetting.apk // 这一步可以用 cp 实现,但一般设备中没有包含该命令。如果使用 mv 会出现错误:failed on '/sdcard/NetWork.apk' - Cross-device link。
# mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system // 还原分区属性,只读。
# exit
$ exit
我们知道 Android 应用程序是沙箱隔离的,每个应用都有一个只有自己具有读写权限的专用数据目录。但是如果应用要访问别人的组件或者一些设备上全局可访问的资源,这时候权限机制就能系统化地规范并强制各类应用程序的行为准则。
Android 安全性概览
在 Android 中,一个权限,本质上是一个字符串,一个可以表示执行特定操作的能力的字符串。比如说:访问 SD 卡的能力,访问通讯录的能力,启动或访问一个第三方应用中的组件的能力。 权限被授予了之后,首先会在内存和本地中有记录,这在调用系统binder服务和其他应用组件时做鉴权依据,比如调用系统binder服务时会通过Binder.getCallingUid()拿到调用者的Uid,而Uid一般都是与应用包名一一对应的,再拿这个Uid到PMS里去查这个应用对应的权限。 其次会按被授予的权限将应用分到某个组。 可以参考
自定义权限的应用场景在于限制其它应用对本应用四大组件的访问。具体用法可以参考
pm list permissions -f 命令可以详细查看 Android 所有预定义的权限。
更详细的权限信息参考
可以看到一个权限的信息包括:定义的包名、标签、描述、 权限组 和 保护级别 。
权限根据设备的功能或特性分为多个组。如果应用已在相同权限组中被授予另一危险权限,系统将立即授予该权限,如READ_CONTACTS和WRITE_CONTACTS。
SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 由于其特殊性,其申请方式与其它权限都不同。
其授予流程如下:
(关于 AppOpsManager 是什么可以参考: )
这里简要分析下ActivityCompat#requestPermissions的流程:
更详细的权限授予流程源码分析可以参考:
普通权限: 清单文件中声明即可。
危险权限: 方式一: pm grant application_package android.permission.CHANGE_CONFIGURATION 方式二:appops set application_package permission_num 0/1
appops可以授予的权限参考 android.app.AppOpsManager 中的声明
系统签名权限: 方式一:将app迁移到system/priv-app目录中。 方式二:看不懂,参考
android 4.4 访问sd卡需要申请权限。 您的应用在 Android 4.4 上运行时无法读取外部存储空间上的共享文件,除非您的应用具有 READ_EXTERNAL_STORAGE 权限。也就是说,没有此权限,您无法再访问 getExternalStoragePublicDirectory() 返回的目录中的文件。但是,如果您仅需要访问 getExternalFilesDir() 提供的您的应用特有目录,那么,您不需要 READ_EXTERNAL_STORAGE `权限。
android 6.0 运行时权限。 此版本引入了一种新的权限模式,如今,用户可直接在运行时管理应用权限。这种模式让用户能够更好地了解和控制权限,同时为应用开发者精简了安装和自动更新过程。用户可为所安装的各个应用分别授予或撤销权限。 对于以 Android 6.0(API 级别 23)或更高版本为目标平台的应用,请务必在运行时检查和请求权限。要确定您的应用是否已被授予权限,请调用新增的 checkSelfPermission() 方法。要请求权限,请调用新增的 requestPermissions() 方法。即使您的应用并不以 Android 6.0(API 级别 23)为目标平台,您也应该在新权限模式下测试您的应用。 如需了解有关在您的应用中支持新权限模式的详情,请参阅 使用系统权限 。如需了解有关如何评估新模式对应用的影响的提示,请参阅 权限最佳做法 。
android 7.+ 应用间共享文件要使用FileProvider。 对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。 要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider `类。如需了解有关权限和共享文件的详细信息,请参阅 共享文件 。
android 8.+
同一权限组的权限在被授予了之后也需要显式的再申请一次。
在 Android 8.0 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。 对于针对 Android 8.0 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。 例如,假设某个应用在其清单中列出 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 。应用请求 READ_EXTERNAL_STORAGE ,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 WRITE_EXTERNAL_STORAGE ,因为该权限也属于同一 STORAGE 权限组并且也在清单中注册过。如果该应用针对的是 Android 8.0,则系统此时仅会授予 READ_EXTERNAL_STORAGE ;不过,如果该应用后来又请求 WRITE_EXTERNAL_STORAGE ,则系统会立即授予该权限,而不会提示用户。
android 9
隐私权限变更。
为了增强用户隐私,Android 9 引入了若干行为变更,如限制后台应用访问设备传感器、限制通过 Wi-Fi 扫描检索到的信息,以及与通话、手机状态和 Wi-Fi 扫描相关的新权限规则和权限组。
android 10
隐私权变更。
外部存储访问权限范围限定为应用文件和媒体,在后台运行时访问设备位置信息需要权限,针对从后台启动 Activity 的限制等。
android 11
隐私权限变更。
更详细的版本变更请参考
方法一
直接使用Intent卸载
Uri uri = Uri.fromParts("package", "com.example.demo", null);
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
startActivity(intent);123
这是最简单的方式,调用卸载方法系统会弹出卸载APP对话框,点击确定就会立即卸载,不需要额外权限
方法二
使用PackageManager静默卸载
谷歌认为该方法是不安全的行为,因此该接口是@hide的,不是公开的接口,调用此接口需要有系统签名和相应的系统级权限
具体来说就是需要
uses-permission android:name="android.permission.DELETE_PACKAGES"/权限,但uses-permission android:name="android.permission.DELETE_PACKAGES"/ 是系统级权限,普通APP根本无法获取到,如果在AndroidManifest.xml强行加入该权限编译也不会通过
唯一的办法就是使用APK反编译工具在Android Studio之外修改权限,比如用apktool反编译工具先把apk文件解压出来,用编辑器在AndroidManifest.xml中加入上面的两个权限,然后在用工具apktool重新打包
获得uses-permission android:name="android.permission.DELETE_PACKAGES"/权限后,定义PackageDeleteObserver实现类,实现packageDeleted方法
private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
private int position;
private int mFlag;
public PackageDeleteObserver(int index, int flag) {
position = index;
mFlag = flag;// 0卸载1个包,1卸载N个包 N1
}
@Override
public void packageDeleted(String arg0, int arg1)
throws RemoteException {
// TODO Auto-generated method stub
Message msg;
msg = mHandle.obtainMessage();
msg.what = FLAG_DELETE_VIRUS;
msg.arg1 = position;
msg.arg2 = mFlag;
msg.sendToTarget();
}
} 123456789101112131415161718192021
获取PackageManager 对象,调用deletePackage方法
PackageManager pkgManager = mContext.getPackageManager();
PackageDeleteObserver observer = new PackageDeleteObserver(currVirus, 1);
pkgManager.deletePackage(pakName, observer, 0); 123
最后,还需要进行系统签名才能使用
对apk进行系统签名:
java -jar signapk.jar platform.x509.pem platform.pk8 test.apk test_signed.apk1
将签名之后的文件 push到手机中,需要root权限
方法三
通过pm命令方式实现静默卸载
该方法直接对Android系统执行卸载命令,需要root权限
//pm命令可以通过adb在shell中执行,同样,我们可以通过代码来执行 public static String execCommand(String... command) {
Process process = null;
InputStream errIs = null;
InputStream inIs = null;
String result = ""; try {
process = new ProcessBuilder().command(command).start();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); int read = -1;
errIs = process.getErrorStream(); while ((read = errIs.read()) != -1) {
baos.write(read);
}
inIs = process.getInputStream(); while ((read = inIs.read()) != -1) {
baos.write(read);
}
result = new String(baos.toByteArray()); if (inIs != null)
inIs.close(); if (errIs != null)
errIs.close();
process.destroy();
} catch (IOException e) {
result = e.getMessage();
} return result;
}123456789101112131415161718192021222324252627282930
执行卸载命令
execCommand("pm","uninstall", "packageName");1
编译生成apk时,要在manifest文件下添加Android:sharedUserId=”android.uid.system”
manifest xmlns:android=""
package="com.xieyuan.mhfilemanager"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="internalOnly"
android:sharedUserId="android.uid.system"
跟手机有关,android是开源的,很多手机厂商都自己做了修改,包括权限,SD卡路径等。
另外看看你报错的log,贴出来
android得到的系统时间判断是白天还是晚上一般由两种方法,第一种,如果是24小时制直接看就可以了;第二种,12小时制,一般系统都会标示am和pm,其中am为上午,pm为下午。二十四小时制,是把每日由午夜至午夜共分为二十四个小时,从数字0至23(24是每日完结的午夜)。这个时间记录系统是现今全世界最常用的。 美国的人们还不能习惯二十四小时制,这在工业化国家中是仅有的。二十四小时制在美国和加拿大仍然被称为军事时间,而在英国则被称作大陆时间。二十四小时制还是国际标准时间系统(国际标准 8601)。 十二小时制是一个时间规则把一日二十四小时分为两个时段,分别为上午(a.m.,拉丁文ante meridiem表示中午之前)和 下午(p.m.,拉丁文post meridiem表示中午之后)。每个时段由十二个小时构成,以数字12、1、2、3、4、5、6、7、8、9、10、11依次序表示。上午时段由午夜至中午,而下午时段由中午至午夜。