Grant里面一共有三個類,分別是:
嘉魚ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信: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
}
這是一個枚舉類,用來對應(yīng)三種狀態(tài):已授權(quán),授權(quán)失敗,未發(fā)現(xiàn)的權(quán)限
(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;
這個類主要是獲取單例下的權(quán)限管理類,然后通過內(nèi)部方法進行權(quán)限管理
(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 中,如果要使用系統(tǒng)限制的權(quán)限(比如 android.permission.WRITE_SECURE_SETTINGS),我們需要把程序安裝到 /system/app/ 下。
下面以 SecureSetting.apk 為例,演示這個操作。需要準(zhǔn)備一臺已經(jīng)獲得 Root 權(quán)限的手機。
1、通過 USB 連接手機和電腦。
2、使用 adb 控制手機。
源碼打???
1. $ adb push SecureSetting.apk /sdcard/ // 上傳要安裝的文件,為安裝做準(zhǔn)備。
2. $ adb shell
3. $ su // 切換到 root 用戶。如果沒有獲得 Root 權(quán)限,這一步不會成功。
4. # mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system // 讓分區(qū)可寫。
5. # cat /sdcard/SecureSetting.apk /system/app/SecureSetting.apk // 這一步可以用 cp 實現(xiàn),但一般設(shè)備中沒有包含該命令。如果使用 mv 會出現(xiàn)錯誤:failed on '/sdcard/NetWork.apk' - Cross-device link。
6. # mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system // 還原分區(qū)屬性,只讀。
7. # exit
8. $ exit
$ adb push SecureSetting.apk /sdcard/ // 上傳要安裝的文件,為安裝做準(zhǔn)備。
$ adb shell
$ su // 切換到 root 用戶。如果沒有獲得 Root 權(quán)限,這一步不會成功。
# mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system // 讓分區(qū)可寫。
# cat /sdcard/SecureSetting.apk /system/app/SecureSetting.apk // 這一步可以用 cp 實現(xiàn),但一般設(shè)備中沒有包含該命令。如果使用 mv 會出現(xiàn)錯誤:failed on '/sdcard/NetWork.apk' - Cross-device link。
# mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system // 還原分區(qū)屬性,只讀。
# exit
$ exit
我們知道 Android 應(yīng)用程序是沙箱隔離的,每個應(yīng)用都有一個只有自己具有讀寫權(quán)限的專用數(shù)據(jù)目錄。但是如果應(yīng)用要訪問別人的組件或者一些設(shè)備上全局可訪問的資源,這時候權(quán)限機制就能系統(tǒng)化地規(guī)范并強制各類應(yīng)用程序的行為準(zhǔn)則。
Android 安全性概覽
在 Android 中,一個權(quán)限,本質(zhì)上是一個字符串,一個可以表示執(zhí)行特定操作的能力的字符串。比如說:訪問 SD 卡的能力,訪問通訊錄的能力,啟動或訪問一個第三方應(yīng)用中的組件的能力。 權(quán)限被授予了之后,首先會在內(nèi)存和本地中有記錄,這在調(diào)用系統(tǒng)binder服務(wù)和其他應(yīng)用組件時做鑒權(quán)依據(jù),比如調(diào)用系統(tǒng)binder服務(wù)時會通過Binder.getCallingUid()拿到調(diào)用者的Uid,而Uid一般都是與應(yīng)用包名一一對應(yīng)的,再拿這個Uid到PMS里去查這個應(yīng)用對應(yīng)的權(quán)限。 其次會按被授予的權(quán)限將應(yīng)用分到某個組。 可以參考
自定義權(quán)限的應(yīng)用場景在于限制其它應(yīng)用對本應(yīng)用四大組件的訪問。具體用法可以參考
pm list permissions -f 命令可以詳細(xì)查看 Android 所有預(yù)定義的權(quán)限。
更詳細(xì)的權(quán)限信息參考
可以看到一個權(quán)限的信息包括:定義的包名、標(biāo)簽、描述、 權(quán)限組 和 保護級別 。
權(quán)限根據(jù)設(shè)備的功能或特性分為多個組。如果應(yīng)用已在相同權(quán)限組中被授予另一危險權(quán)限,系統(tǒng)將立即授予該權(quán)限,如READ_CONTACTS和WRITE_CONTACTS。
SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 由于其特殊性,其申請方式與其它權(quán)限都不同。
其授予流程如下:
(關(guān)于 AppOpsManager 是什么可以參考: )
這里簡要分析下ActivityCompat#requestPermissions的流程:
更詳細(xì)的權(quán)限授予流程源碼分析可以參考:
普通權(quán)限: 清單文件中聲明即可。
危險權(quán)限: 方式一: pm grant application_package android.permission.CHANGE_CONFIGURATION 方式二:appops set application_package permission_num 0/1
appops可以授予的權(quán)限參考 android.app.AppOpsManager 中的聲明
系統(tǒng)簽名權(quán)限: 方式一:將app遷移到system/priv-app目錄中。 方式二:看不懂,參考
android 4.4 訪問sd卡需要申請權(quán)限。 您的應(yīng)用在 Android 4.4 上運行時無法讀取外部存儲空間上的共享文件,除非您的應(yīng)用具有 READ_EXTERNAL_STORAGE 權(quán)限。也就是說,沒有此權(quán)限,您無法再訪問 getExternalStoragePublicDirectory() 返回的目錄中的文件。但是,如果您僅需要訪問 getExternalFilesDir() 提供的您的應(yīng)用特有目錄,那么,您不需要 READ_EXTERNAL_STORAGE `權(quán)限。
android 6.0 運行時權(quán)限。 此版本引入了一種新的權(quán)限模式,如今,用戶可直接在運行時管理應(yīng)用權(quán)限。這種模式讓用戶能夠更好地了解和控制權(quán)限,同時為應(yīng)用開發(fā)者精簡了安裝和自動更新過程。用戶可為所安裝的各個應(yīng)用分別授予或撤銷權(quán)限。 對于以 Android 6.0(API 級別 23)或更高版本為目標(biāo)平臺的應(yīng)用,請務(wù)必在運行時檢查和請求權(quán)限。要確定您的應(yīng)用是否已被授予權(quán)限,請調(diào)用新增的 checkSelfPermission() 方法。要請求權(quán)限,請調(diào)用新增的 requestPermissions() 方法。即使您的應(yīng)用并不以 Android 6.0(API 級別 23)為目標(biāo)平臺,您也應(yīng)該在新權(quán)限模式下測試您的應(yīng)用。 如需了解有關(guān)在您的應(yīng)用中支持新權(quán)限模式的詳情,請參閱 使用系統(tǒng)權(quán)限 。如需了解有關(guān)如何評估新模式對應(yīng)用的影響的提示,請參閱 權(quán)限最佳做法 。
android 7.+ 應(yīng)用間共享文件要使用FileProvider。 對于面向 Android 7.0 的應(yīng)用,Android 框架執(zhí)行的 StrictMode API 政策禁止在您的應(yīng)用外部公開 。如果一項包含文件 URI 的 intent 離開您的應(yīng)用,則應(yīng)用出現(xiàn)故障,并出現(xiàn) FileUriExposedException 異常。 要在應(yīng)用間共享文件,您應(yīng)發(fā)送一項 content:// URI,并授予 URI 臨時訪問權(quán)限。進行此授權(quán)的最簡單方式是使用 FileProvider `類。如需了解有關(guān)權(quán)限和共享文件的詳細(xì)信息,請參閱 共享文件 。
android 8.+
同一權(quán)限組的權(quán)限在被授予了之后也需要顯式的再申請一次。
在 Android 8.0 之前,如果應(yīng)用在運行時請求權(quán)限并且被授予該權(quán)限,系統(tǒng)會錯誤地將屬于同一權(quán)限組并且在清單中注冊的其他權(quán)限也一起授予應(yīng)用。 對于針對 Android 8.0 的應(yīng)用,此行為已被糾正。系統(tǒng)只會授予應(yīng)用明確請求的權(quán)限。然而,一旦用戶為應(yīng)用授予某個權(quán)限,則所有后續(xù)對該權(quán)限組中權(quán)限的請求都將被自動批準(zhǔn)。 例如,假設(shè)某個應(yīng)用在其清單中列出 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 。應(yīng)用請求 READ_EXTERNAL_STORAGE ,并且用戶授予了該權(quán)限。如果該應(yīng)用針對的是 API 級別 24 或更低級別,系統(tǒng)還會同時授予 WRITE_EXTERNAL_STORAGE ,因為該權(quán)限也屬于同一 STORAGE 權(quán)限組并且也在清單中注冊過。如果該應(yīng)用針對的是 Android 8.0,則系統(tǒng)此時僅會授予 READ_EXTERNAL_STORAGE ;不過,如果該應(yīng)用后來又請求 WRITE_EXTERNAL_STORAGE ,則系統(tǒng)會立即授予該權(quán)限,而不會提示用戶。
android 9
隱私權(quán)限變更。
為了增強用戶隱私,Android 9 引入了若干行為變更,如限制后臺應(yīng)用訪問設(shè)備傳感器、限制通過 Wi-Fi 掃描檢索到的信息,以及與通話、手機狀態(tài)和 Wi-Fi 掃描相關(guān)的新權(quán)限規(guī)則和權(quán)限組。
android 10
隱私權(quán)變更。
外部存儲訪問權(quán)限范圍限定為應(yīng)用文件和媒體,在后臺運行時訪問設(shè)備位置信息需要權(quán)限,針對從后臺啟動 Activity 的限制等。
android 11
隱私權(quán)限變更。
更詳細(xì)的版本變更請參考
方法一
直接使用Intent卸載
Uri uri = Uri.fromParts("package", "com.example.demo", null);
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
startActivity(intent);123
這是最簡單的方式,調(diào)用卸載方法系統(tǒng)會彈出卸載APP對話框,點擊確定就會立即卸載,不需要額外權(quán)限
方法二
使用PackageManager靜默卸載
谷歌認(rèn)為該方法是不安全的行為,因此該接口是@hide的,不是公開的接口,調(diào)用此接口需要有系統(tǒng)簽名和相應(yīng)的系統(tǒng)級權(quán)限
具體來說就是需要?
uses-permission android:name="android.permission.DELETE_PACKAGES"/權(quán)限,但uses-permission android:name="android.permission.DELETE_PACKAGES"/?是系統(tǒng)級權(quán)限,普通APP根本無法獲取到,如果在AndroidManifest.xml強行加入該權(quán)限編譯也不會通過
唯一的辦法就是使用APK反編譯工具在Android Studio之外修改權(quán)限,比如用apktool反編譯工具先把apk文件解壓出來,用編輯器在AndroidManifest.xml中加入上面的兩個權(quán)限,然后在用工具apktool重新打包
獲得uses-permission android:name="android.permission.DELETE_PACKAGES"/權(quán)限后,定義PackageDeleteObserver實現(xiàn)類,實現(xiàn)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 對象,調(diào)用deletePackage方法
PackageManager pkgManager = mContext.getPackageManager(); ?
PackageDeleteObserver observer = new PackageDeleteObserver(currVirus, 1); ?
pkgManager.deletePackage(pakName, observer, 0); ?123
最后,還需要進行系統(tǒng)簽名才能使用
對apk進行系統(tǒng)簽名:
java -jar signapk.jar platform.x509.pem platform.pk8 test.apk test_signed.apk1
將簽名之后的文件 push到手機中,需要root權(quán)限
方法三
通過pm命令方式實現(xiàn)靜默卸載
該方法直接對Android系統(tǒng)執(zhí)行卸載命令,需要root權(quán)限
//pm命令可以通過adb在shell中執(zhí)行,同樣,我們可以通過代碼來執(zhí)行 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
執(zhí)行卸載命令
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" ?
跟手機有關(guān),android是開源的,很多手機廠商都自己做了修改,包括權(quán)限,SD卡路徑等。
另外看看你報錯的log,貼出來
android得到的系統(tǒng)時間判斷是白天還是晚上一般由兩種方法,第一種,如果是24小時制直接看就可以了;第二種,12小時制,一般系統(tǒng)都會標(biāo)示am和pm,其中am為上午,pm為下午。二十四小時制,是把每日由午夜至午夜共分為二十四個小時,從數(shù)字0至23(24是每日完結(jié)的午夜)。這個時間記錄系統(tǒng)是現(xiàn)今全世界最常用的。 美國的人們還不能習(xí)慣二十四小時制,這在工業(yè)化國家中是僅有的。二十四小時制在美國和加拿大仍然被稱為軍事時間,而在英國則被稱作大陸時間。二十四小時制還是國際標(biāo)準(zhǔn)時間系統(tǒng)(國際標(biāo)準(zhǔn) 8601)。 十二小時制是一個時間規(guī)則把一日二十四小時分為兩個時段,分別為上午(a.m.,拉丁文ante meridiem表示中午之前)和 下午(p.m.,拉丁文post meridiem表示中午之后)。每個時段由十二個小時構(gòu)成,以數(shù)字12、1、2、3、4、5、6、7、8、9、10、11依次序表示。上午時段由午夜至中午,而下午時段由中午至午夜。