Android 6.0適配
在6.0之前丈咐,在應(yīng)用安裝的時候,提示用戶所需要用到的權(quán)限列表龙宏,同意之后安裝棵逊,該app就被賦予所有的權(quán)限,我們暫且稱它為安裝時權(quán)限银酗,安裝后辆影,被賦予的權(quán)限也無法取消;在6.0之后黍特,google對權(quán)限進行了運行時的管理蛙讥,而不是在安裝時候,危險權(quán)限需要在運行時申請灭衷,我們暫且稱它為運行時權(quán)限次慢,非危險權(quán)限,在安裝時由用戶授予,這樣簡化了應(yīng)用安裝過程迫像,因為用戶在安裝或更新應(yīng)用時不需要授予權(quán)限拭抬,也給予了用戶對app功能更多的控制
-
系統(tǒng)權(quán)限主要分為兩類,正常權(quán)限和危險權(quán)限
正常權(quán)限不會直接危及用戶的隱私侵蒙,如果你的應(yīng)用在它的Manifest中列出了正常權(quán)限造虎,系統(tǒng)會自動授予權(quán)限
危險權(quán)限可以讓app訪問用戶的機密數(shù)據(jù),如果你的應(yīng)用在它的Manifest列出了危險權(quán)限纷闺,用戶必須明確批準你的app使用該權(quán)限 當然算凿,不管哪個版本的android,你應(yīng)用中所用到的所有權(quán)限犁功,不管是正常權(quán)限還是危險權(quán)限氓轰,都需要在應(yīng)用的Manifest中申明
如果你的設(shè)備運行Android 5.1以及5.1以下版本,或者你的應(yīng)用的目標SDK是22以及22以下版本:如果你在應(yīng)用的Manifest中申明了危險權(quán)限浸卦,用戶在安裝時必須授予權(quán)限署鸡,如果拒絕授予權(quán)限,那么系統(tǒng)就不會安裝應(yīng)用限嫌,也就是所謂的“一刀切”方式靴庆,不同意所有權(quán)限,就不能安裝應(yīng)用如果你的設(shè)備運行Android 6.0以及6.0以上版本怒医,或者你的目標SDK是23以及23以上版本:應(yīng)用必須在Manifest中羅列出所有的權(quán)限炉抒,并且在程序運行時,它必須請求用戶授予每一個危險權(quán)限稚叹,此時用戶可以授予或者拒絕每一個權(quán)限焰薄,并且應(yīng)用程序可以繼續(xù)運行有限的功能,即使用戶拒絕了權(quán)限請求
注意:從Android 6.0開始(API 23)扒袖,用戶可以在任何時候塞茅,對任何應(yīng)用撤銷權(quán)限,即使app申明的目標SDK低于23
在6.0所有權(quán)限都需要申請季率?
曰:當然不是野瘦。只有屬于危險權(quán)限的才需要申請。危險權(quán)限看下表1-2-
那危險權(quán)限也很多啊蚀同,也要一個個申請缅刽?
曰:當然不是。你看看下面的表蠢络,都分好組了(9組)衰猛,對于同一組內(nèi)的權(quán)限,只要有一個被同意刹孔,其他的都會被同意啡省。
表1-2危險權(quán)限分組
1553134417(1).jpg
1553135023(1).jpg
Android 7.0適配
應(yīng)用間共享文件
在targetSdkVersion大于等于的24的App中娜睛,但是我們沒有去適配7.0。那么在調(diào)用安裝頁面卦睹,或修改用戶頭像操作時畦戒,就會失敗。那么就需要你去適配7.0或是將targetSdkVersion改為24以下(不推薦)结序。
Android 7.0 行為變更 通過FileProvider在應(yīng)用間共享文件這篇文章
https://blog.csdn.net/lmj623565791/article/details/72859156
Android 7.0 引入一項新的應(yīng)用簽名方案 APK Signature Scheme v2障斋,它能提供更快的應(yīng)用安裝時間和更多針對未授權(quán) APK 文件更改的保護。在默認情況下徐鹤,Android Studio 2.2 和 Android Plugin for Gradle 2.2 會使用 APK Signature Scheme v2 和傳統(tǒng)簽名方案來簽署您的應(yīng)用垃环。
1)只勾選v1簽名就是傳統(tǒng)方案簽署,但是在7.0上不會使用V2安全的驗證方式返敬。
2)只勾選V2簽名7.0以下會顯示未安裝遂庄,7.0上則會使用了V2安全的驗證方式。
3)同時勾選V1和V2則所有版本都沒問題劲赠。
3.3 org.apache不支持問題
// build.gradle里面加上這句話
defaultConfig {
useLibrary 'org.apache.http.legacy'
}
Android8.0的適配
安卓8.0中PHONE權(quán)限組新增兩個權(quán)限
ANSWER_PHONE_CALLS:允許您的應(yīng)用通過編程方式接聽呼入電話涛目。要在您的應(yīng)用中處理呼入電話,您可以使用 acceptRingingCall() 函數(shù)凛澎。
READ_PHONE_NUMBERS :權(quán)限允許您的應(yīng)用讀取設(shè)備中存儲的電話號碼霹肝。
通知適配
安卓8.0中,為了更好的管制通知的提醒预厌,不想一些不重要的通知打擾用戶阿迈,新增了通知渠道,用戶可以根據(jù)渠道來屏蔽一些不想要的通知.
兼容的代碼
/**
* 安卓8轧叽。0通知的兼容類哦,
* NotifyCompatYc yc : 是雨辰的簡寫刊棕,謝謝哦炭晒,嘿嘿 ----高貴的子信
*/
public class NotifyCompatYc {
public static final String QFMD_CHANNEL_ID = "com.oms.mingdeng";
public static final String QFMD_CHANNEL_NAME = "祈福明燈";
public static final String LJMS_DEFAULT_CHANNEL_NAME = "靈機妙算";
public static final String LJMS_CHANNEL_ID = "com.oms.mmcnotity";
public static final String XYS_CHANNEL_ID = "com.oms.xuyuanshu";
public static final String XYS_CHANNEL_NAME = "許願樹";
public static void setONotifyChannel(NotificationManager manager, NotificationCompat.Builder builder, String channeId, String channelName) {
if (TextUtils.isEmpty(channeId)||TextUtils.isEmpty(channelName)){
L.e("NotifyCompatYc: ".concat("安卓8.0的通知兼容庫中 channeId 與 channelName 不能為empty"));
}
if (Build.VERSION.SDK_INT >= 26) {
//第三個參數(shù)設(shè)置通知的優(yōu)先級別
NotificationChannel channel =
new NotificationChannel(channeId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
channel.canBypassDnd();//是否可以繞過請勿打擾模式
channel.canShowBadge();//是否可以顯示icon角標
channel.enableLights(true);//是否顯示通知閃燈
channel.enableVibration(true);//收到小時時震動提示
channel.setBypassDnd(true);//設(shè)置繞過免打擾
channel.setLockscreenVisibility(NotificationCompat.VISIBILITY_SECRET);
channel.setLightColor(Color.RED);//設(shè)置閃光燈顏色
channel.getAudioAttributes();//獲取設(shè)置鈴聲設(shè)置
channel.setVibrationPattern(new long[]{100, 200, 100});//設(shè)置震動模式
channel.shouldShowLights();//是否會閃光
if (manager != null) {
manager.createNotificationChannel(channel);
}
if (builder != null) {
builder.setChannelId(channeId);//這個id參數(shù)要與上面channel構(gòu)建的第一個參數(shù)對應(yīng)
}
}
}
public static void setONotifyChannel(NotificationManager manager, String channeId, String channelName) {
setONotifyChannel(manager,null,channeId,channelName);
}
public static Notification getNotification(Context context, String channelId) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.ic_launcher)
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
return notification;
}
}
安裝APK
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
這樣系統(tǒng)會自動詢問用戶完成授權(quán)。當然你也可以先使用 canRequestPackageInstalls()查詢是否有此權(quán)限甥角,如果沒有的話使用Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES這個action將用戶引導(dǎo)至安裝未知應(yīng)用權(quán)限界面去授權(quán)网严。
private static final int REQUEST_CODE_UNKNOWN_APP = 100;
private void installAPK(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
boolean hasInstallPermission = getPackageManager().canRequestPackageInstalls();
if (hasInstallPermission) {
//安裝應(yīng)用
} else {
//跳轉(zhuǎn)至“安裝未知應(yīng)用”權(quán)限界面,引導(dǎo)用戶開啟權(quán)限
Uri selfPackageUri = Uri.parse("package:" + this.getPackageName());
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, selfPackageUri);
startActivityForResult(intent, REQUEST_CODE_UNKNOWN_APP);
}
}else {
//安裝應(yīng)用
}
}
//接收“安裝未知應(yīng)用”權(quán)限的開啟結(jié)果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_UNKNOWN_APP) {
installAPK();
}
}
SharedPreferences閃退
SharedPreferences read = getSharedPreferences(RELEASE_POOL_DATA, MODE_WORLD_READABLE);
//MODE_WORLD_READABLE :8.0以后不能使用這個獲取嗤无,會閃退震束,修改成MODE_PRIVATE
SecurityException的閃退
問題原因:項目使用了ActiveAndroid,在 8.0 或 8.1 系統(tǒng)上使用 26 或以上的版本的 SDK 時当犯,調(diào)用 ContentResolver 的 notifyChange 方法通知數(shù)據(jù)更新垢村,或者調(diào)用 ContentResolver 的 registerContentObserver 方法監(jiān)聽數(shù)據(jù)變化時,會出現(xiàn)上述異常嚎卫。
解決方案:
(1)在清單文件配置
<provider
android:name="com.activeandroid.content.ContentProvider"
android:authorities="com.ylmf.androidclient"
android:enabled="true"
android:exported="false">
</provider>
(2)去掉這個監(jiān)聽刷新的方法嘉栓,改為廣播刷新
靜態(tài)廣播無法正常接收
問題原因: Android 8.0 引入了新的廣播接收器限制,因此您應(yīng)該移除所有為隱式廣播 Intent 注冊的廣播接收器
//setNotificationUri(cursor);
//給注銷掉
/** 通知數(shù)據(jù)庫發(fā)生變化*/
private void notifyChange () {
//mContext.getContentResolver().notifyChange(ORDER_URI, null, false);
BroadcastController.sendChangeDataBroadCast(mContext);
}
解決方案:
使用動態(tài)廣播代替靜態(tài)廣播
Caused by: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
解決方案(1):
問題原因: Android 8.0 非全屏透明頁面不允許設(shè)置方向(8.1以上谷歌就修復(fù)去掉了這個限制)
解決方案:android:windowIsTranslucent設(shè)置為false
解決方案(2):<去掉方向的設(shè)置>
解決方案(3):
使用對話框、fragmentDialog侵佃、Popwindow的代替透明的Activity麻昼。
Android9.0的適配
CLEARTEXT communication to life.115.com not permitted by network security policy
問題原因: Android P 限制了明文流量的網(wǎng)絡(luò)請求,非加密的流量請求都會被系統(tǒng)禁止掉
解決方案:
在資源文件新建xml目錄馋辈,新建文件
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
清單文件配置:
<application
android:networkSecurityConfig="@xml/network_security_config">
<!--9.0加的抚芦,哦哦-->
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
</application>