關(guān)于android 懸浮窗和自啟動的設(shè)置, 以及獲取系統(tǒng)的信息
標簽(空格分隔):Android
懸浮窗
對于是否有開懸浮窗,程序是可以檢測到的系瓢。
權(quán)限聲明:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
權(quán)限檢查:
對于android6.0 以上的機型來說,google將懸浮窗權(quán)限和其他危險權(quán)限單獨列出往枷,因此可以檢測菲驴, 方法:
fun checkFloatWindowPermission(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val result = Settings.canDrawOverlays(BaseContext.application)
return result
} else {
//6.0 以下
val result = checkRomFloatWindowPermission()
return result
}
return true
}
android 4.4以下大部分機型聲明即獲取(包括大部分國產(chǎn)機)错英, 因此只需判斷4.4.4 -- 5.1之間的系統(tǒng)即可入撒。
//如下,經(jīng)過我的測試椭岩,只有小米和魅族茅逮, 華為需要在`api<=19`時單獨處理,其他正常判哥。
fun checkRomFloatWindowPermission(): Boolean {
val brand = Build.MANUFACTURER
if (brand.contains("Xiaomi")) {
//check miui permission
return checkMeizuAndMIUIFloatWindowPermission()
}
if (brand.contains("Huawei") || brand.contains("HUAWEI")) {
return checkMeizuAndMIUIFloatWindowPermission()
}
if (Build.VERSION.SDK_INT <= 19) {
return true
}
when (brand) {
"Meizu" -> return checkMeizuAndMIUIFloatWindowPermission()
"OPPO" -> return true
"vivo" -> return true
"Sony" -> return true
"Letv" -> return true
"LG" -> return true
}
return true
}
//-------------- Meizu MIUI huawei start---------------------
fun checkMeizuAndMIUIFloatWindowPermission(): Boolean {
if (Build.VERSION.SDK_INT >= 19) {
return checkMeizuAndMIUIOp(24)
}
return true
}
fun checkMeizuAndMIUIOp(op: Int): Boolean {
if (Build.VERSION.SDK_INT >= 19) {
val opsManager = BaseContext.application.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
try {
val clazz = AppOpsManager::class.java
val method = clazz.getDeclaredMethod("checkOp",
Int::class.javaPrimitiveType, Int::class.javaPrimitiveType, String::class.java)
return AppOpsManager.MODE_ALLOWED == method.invoke(opsManager, op, Binder.getCallingUid(), BaseContext.application.packageName)
} catch (e: Exception) {
Logger.d(TAG, "checkOp", e)
}
} else {
Logger.d(TAG, "Below API 19 cannot invoke!")
}
return false
}
//-------------- Meizu MIUI end ---------------------
至此献雅,權(quán)限檢查完畢。
不能動態(tài)獲取塌计,只能跳轉(zhuǎn)到這只頁去手動開啟惩琉。
fun applyFloatWindowPermission(context: Context) {
if (Build.VERSION.SDK_INT >= 23) {
applySystemPermission(context)
return
}
val brand = Build.MANUFACTURER
when (brand) {
"Huawei", "HUAWEI" -> applyHuaweiPermission(context)
"Xiaomi" -> applyMIUIPermSetting(context)
"Meizu" -> applyMeizuPermission(context)
"OPPO" -> openOppoPermSetting(context)
"vivo" -> openVivoPermSetting(context)
else -> applySystemPermission(context)
}
}
//-------------- Sysytem start ---------------------
fun applySystemPermission(activity: Activity) {
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
intent.data = Uri.parse("package:" + activity.packageName)
activity.startActivityForResult(intent, 1)
}
//-------------- Sysytem end ---------------------
//-------------- Meizu start---------------------
fun applyMeizuPermission(activity: Activity) {
val intent = Intent("com.meizu.safe.security.SHOW_APPSEC")
intent.setClassName("com.meizu.safe", "com.meizu.safe.security.AppSecActivity")
intent.putExtra("packageName", activity.packageName)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
activity.startActivity(intent)
}
//-------------- Meizu end ---------------------
//-------------- MIUI start---------------------
fun applyMIUIPermSetting(activity: Activity) {
openMIUIPermSetting(activity)
}
fun openMIUIPermSetting(context: Context): Boolean {
val i = Intent("miui.intent.action.APP_PERM_EDITOR")
val componentName = ComponentName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity")
i.component = componentName
i.putExtra("extra_pkgname", context.packageName)
try {
context.startActivity(i)
} catch (e: Exception) {
Logger.e(TAG, "openMIUIPermSetting jump e:" + e.message)
openSystemSetting(context)
return false
}
return true
}
//-------------- MIUI start---------------------
//-------------- huawei start---------------------
fun applyHuaweiPermission(context: Context) {
try {
val intent = Intent()
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
var comp = ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.addviewmonitor.AddViewMonitorActivity")//懸浮窗管理頁面
intent.component = comp
val version = getEmuiVersion()
Logger.d(TAG, "applyHuaweiPermission:" + version)
if (version == 3.0) {
comp = ComponentName("com.huawei.systemmanager", "com.huawei.notificationmanager.ui.NotificationManagmentActivity")//懸浮窗管理頁面
intent.component = comp
context.startActivity(intent)
return
}
context.startActivity(intent)
// if (version == 3.1) {
// //emui 3.1 的適配
// context.startActivity(intent)
// } else {
// //emui 3.0 的適配
// comp = ComponentName("com.huawei.systemmanager", "com.huawei.notificationmanager.ui.NotificationManagmentActivity")//懸浮窗管理頁面
// intent.component = comp
// context.startActivity(intent)
// }
} catch (e: Exception) {
//拋出異常時提示信息
Toast.makeText(context, "進入設(shè)置頁面失敗,請手動設(shè)置", Toast.LENGTH_LONG).show()
Log.e(TAG, Log.getStackTraceString(e))
}
}
fun getEmuiVersion(): Double {
try {
val emuiVersion = getSystemProperty("ro.build.version.emui") ?: return 4.0
val version = emuiVersion.substring(emuiVersion.indexOf("_") + 1)
return java.lang.Double.parseDouble(version)
} catch (e: Exception) {
e.printStackTrace()
}
return 4.0
}
//-------------- huawei end---------------------
附: 各手機廠商跳轉(zhuǎn)到設(shè)置頁的方法:(context)
// open app setting according to rom ----------------
fun applyBrandStrategy(activity: Activity) {
val brand = Build.MANUFACTURER
when (brand) {
"Huawei", "HUAWEI" -> openHuaweiPermSetting(activity)
"Xiaomi" -> openMIUIPermSetting(activity)
"Meizu" -> openMeizuPermSetting(activity)
"OPPO" -> openOppoPermSetting(activity)
"vivo" -> openVivoPermSetting(activity)
"Sony" -> openSonyPermSetting(activity)
"Letv" -> openLetvPermSetting(activity)
"LG" -> openLGPermSetting(activity)
else -> openSystemSetting(activity)
}
}
fun openMIUIPermSetting(activity: Activity): Boolean {
val i = Intent("miui.intent.action.APP_PERM_EDITOR")
val componentName = ComponentName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity")
i.component = componentName
i.putExtra("extra_pkgname", activity.packageName)
try {
activity.startActivity(i)
} catch (e: Exception) {
Logger.e(TAG, "openMIUIPermSetting jump e:" + e.message)
openSystemSetting(activity)
return false
}
return true
}
fun openMeizuPermSetting(activity: Activity): Boolean {
val intent = Intent("com.meizu.safe.security.SHOW_APPSEC")
intent.addCategory(Intent.CATEGORY_DEFAULT)
intent.putExtra("packageName", activity.packageName)
try {
activity.startActivity(intent)
} catch (e: Exception) {
Logger.e(TAG, "openMeizuPermSetting jump e:" + e.message)
openSystemSetting(activity)
return false
}
return true
}
fun openHuaweiPermSetting(activity: Activity): Boolean {
val intent = Intent()
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("packageName", activity.packageName)
var comp = ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity")
intent.component = comp
try {
activity.startActivity(intent)
} catch (e: Exception) {
Logger.e(TAG, "openHuaweiPermSetting jump e:" + e.message)
comp = ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.SingleAppActivity")
intent.component = comp
try {
activity.startActivity(intent)
} catch (e1: Exception) {
Logger.e(TAG, "openHuaweiPermSetting jump e1:" + e.message)
openSystemSetting(activity)
return false
}
}
return true
}
fun openOppoPermSetting(activity: Activity): Boolean {
val intent = Intent()
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("packageName", activity.packageName)
val comp = ComponentName("com.oppo.safe", "com.oppo.safe.permission.PermissionSettingsActivity")
intent.component = comp
try {
activity.startActivity(intent)
} catch (e: Exception) {
Logger.e(TAG, "openOppoPermSetting jump e:" + e.message)
openSystemSetting(activity)
return false
}
return true
}
fun openVivoPermSetting(activity: Activity): Boolean {
val intent = Intent()
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("packageName", activity.packageName)
val comp = ComponentName("com.iqoo.secure", "com.iqoo.secure.MainActivity")
intent.component = comp
try {
activity.startActivity(intent)
} catch (e: Exception) {
Logger.e(TAG, "openVivoPermSetting jump e:" + e.message)
openSystemSetting(activity)
return false
}
return true
}
fun openSonyPermSetting(activity: Activity): Boolean {
val intent = Intent()
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("packageName", activity.packageName)
val comp = ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity")
intent.component = comp
try {
activity.startActivity(intent)
} catch (e: Exception) {
Logger.e(TAG, "openSonyPermSetting jump e:" + e.message)
openSystemSetting(activity)
return false
}
return true
}
fun openLGPermSetting(activity: Activity): Boolean {
val intent = Intent("android.intent.action.MAIN")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("packageName", activity.packageName)
val comp = ComponentName("com.android.settings", "com.android.settings.Settings\$AccessLockSummaryActivity")
intent.component = comp
try {
activity.startActivity(intent)
} catch (e: Exception) {
Logger.e(TAG, "openLGPermSetting jump e:" + e.message)
openSystemSetting(activity)
return false
}
return true
}
fun openLetvPermSetting(activity: Activity): Boolean {
val intent = Intent()
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("packageName", activity.packageName)
val comp = ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.PermissionAndApps")
intent.component = comp
try {
activity.startActivity(intent)
} catch (e: Exception) {
Logger.e(TAG, "openLetvPermSetting jump e:" + e.message)
openSystemSetting(activity)
return false
}
return true
}
fun openSystemSetting(activity: Activity): Boolean {
val localIntent = Intent()
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
localIntent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"
localIntent.data = Uri.fromParts("package", activity.packageName, null)
try {
activity.startActivity(localIntent)
} catch (e: Exception) {
Logger.e(TAG, "openSystemSetting jump e:" + e.message)
return false
}
return true
}
開啟自啟動
自啟動比較簡單夺荒,android系統(tǒng)無法檢測到是否開啟,一般做法是首次安裝提示用戶跳轉(zhuǎn)設(shè)置:
private fun applySelfStartSetting() {
var intent = Intent()
try {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
var componentName: ComponentName? = null
val brand = Build.MANUFACTURER
when (brand) {
"Xiaomi" -> {
componentName = ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")
}
"samsung", "Samsung" -> {
componentName = ComponentName("com.samsung.android.sm" ,"com.samsung.android.sm.app.dashboard.SmartManagerDashBoardActivity")
}
"Huawei", "HUAWEI" -> {
componentName = ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")
}
"Meizu" -> {
componentName = ComponentName.unflattenFromString("com.meizu.safe/.permission.SmartBGActivity")
}
"OPPO" -> {
componentName = ComponentName.unflattenFromString("com.oppo.safe/.permission.startup.StartupAppListActivity")
}
"vivo" -> {
componentName = ComponentName.unflattenFromString("com.iqoo.secure/.safeguard.PurviewTabActivity")
}
"Letv" -> {
intent.action = "com.letv.android.permissionautoboot"
}
else -> {
intent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"
intent.data = Uri.fromParts("package", packageName, null)
}
}
intent.component = componentName
startActivity(intent)
} catch (e: Exception) {
Logger.d(PhoneDialogActivity.TAG, "applySelfStartSetting:" + e)
intent = Intent(Settings.ACTION_SETTINGS)
startActivity(intent)
}
}
android 相關(guān)信息的獲取方法:
1.獲取手機型號(Build)
所屬包: android.os.Build
作用(含義): 從系統(tǒng)屬性中提取設(shè)備硬件和版本信息
靜態(tài)屬性:
1. BOARD 主板:The name of the underlying board, like goldfish.
2. BOOTLOADER 系統(tǒng)啟動程序版本號:The system bootloader version number.
3. BRAND 系統(tǒng)定制商:The consumer-visible brand with which the product/hardware will be associated, if any.
4. CPU_ABI cpu指令集:The name of the instruction set (CPU type + ABI convention) of native code.
5. CPU_ABI2 cpu指令集2:The name of the second instruction set (CPU type + ABI convention) of native code.
6. DEVICE 設(shè)備參數(shù):The name of the industrial design.
7. DISPLAY 顯示屏參數(shù):A build ID string meant for displaying to the user
8. FINGERPRINT 唯一識別碼:A string that uniquely identifies this build. Do not attempt to parse this value.
9. HARDWARE 硬件名稱:The name of the hardware (from the kernel command line or /proc).
10. HOST
11. ID 修訂版本列表:Either a changelist number, or a label like M4-rc20.
12. MANUFACTURER 硬件制造商:The manufacturer of the product/hardware.(我們目前只需要關(guān)注這個靜態(tài)屬性即可)
13. MODEL 版本即最終用戶可見的名稱:The end-user-visible name for the end product.
14. PRODUCT 整個產(chǎn)品的名稱:The name of the overall product.
15. RADIO 無線電固件版本:The radio firmware version number. 在API14后已過時良蒸。使用 getRadioVersion()代替技扼。
16. SERIAL 硬件序列號:A hardware serial number, if available. Alphanumeric only, case-insensitive.
17. TAGS 描述build的標簽,如未簽名,debug等等嫩痰。:Comma-separated tags describing the build, like unsigned,debug.
18. TIME
19. TYPE build的類型:The type of build, like user or eng.
20. USER
打開其他應(yīng)用程序中的Activity或服務(wù)(ComponentName)
所屬包: android.content.ComponentName
構(gòu)造方法使用方式如下:
- 傳遞當(dāng)前上下文和將要跳轉(zhuǎn)的類名剿吻;
- 傳遞一個String包名和String類名;
- 傳遞一個Parcel數(shù)據(jù)容器串纺。
需要關(guān)注的方法:unflattenFromString(“傳遞將要跳轉(zhuǎn)的地址丽旅,格式為包名/跳轉(zhuǎn)Activity Name”)
通過adb獲取跳轉(zhuǎn)包名路徑
adb為我們提供了一個可以打印出當(dāng)前系統(tǒng)所有service信息,在后面可加上具體的服務(wù)名的命令
adb shell dumpsys
獲取設(shè)備電池信息:adb shell dumpsys battery
獲取cpu信息:adb shell dumpsys cpuinfo
獲取內(nèi)存信息:adb shell dumpsys meminfo
要獲取具體應(yīng)用的內(nèi)存信息纺棺,可加上包名
adb shell dumpsys meminfo PACKAGE_NAME
獲取Activity信息:adb shell dumpsys activity
獲取package信息:adb shell dumpsys package
加上-h可以獲取幫助信息
獲取某個包的信息:adb shell dumpsys package PACKAGE_NAME
獲取通知信息:adb shell dumpsys notification
獲取wifi信息:adb shell dumpsys wifi
可以獲取到當(dāng)前連接的wifi名榄笙、搜索到的wifi列表、wifi強度等
獲取電源管理信息:adb shell dumpsys power
可以獲取到是否處于鎖屏狀態(tài):mWakefulness=Asleep或者mScreenOn=false
獲取電話信息:adb shell dumpsys telephony.registry
可以獲取到電話狀態(tài)祷蝌,例如mCallState值為0茅撞,表示待機狀態(tài)、1表示來電未接聽狀態(tài)、2表示電話占線狀態(tài)
mCallForwarding=false #是否啟用呼叫轉(zhuǎn)移
mDataConnectionState=2 #0:無數(shù)據(jù)連接 1:正在創(chuàng)建數(shù)據(jù)連接 2:已連接mDataConnectionPossible=true #是否有數(shù)據(jù)連接mDataConnectionApn= #APN名稱等
adb shell dumpsys activity top
//獲取當(dāng)前顯示activity的詳細信息米丘,包括所屬包名和activity名剑令,activity的布局信息等等。
參考資料 : http://www.voidcn.com/article/p-dpiicqfm-zw.html