危险权限需要动态申请:下面是一些危险权限列举:
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
点击查看上面权限的具体代表含义参考文章地址
动态申请权限可以使用:github源码(项目必须是Androidx项目,Android support项目不能引用)
引用
api 'com.bintray.library:snowpermission:1.0.0'
使用:
RequestPermissions.with(this)
.permissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE})
.onGranted(new ActionCallBack() {
@Override
public void callBack(List strings) {
Log.e("qq", "======获取权限成功");
}
})
.onDenied(new ActionCallBack() {
@Override
public void callBack(List strings) {
Log.e("qq", "======获取权限失败====");
}
})
.start();
1、文件访问权限:
1.1、首先要在Manifest中注册provider:
1.2、android:resource的值是自定义的一个xml文件,里面指定了可以访问的目录,例如:
这里说明下paths的配置:
代表的根目录: Context.getFilesDir()
代表的根目录: Environment.getExternalStorageDirectory()
代表的根目录: getCacheDir()
path的值可以指定为根目录或指定的子目录。
2、PopupWindow在Android7.0系统中显示位置错误:
(解决方法:在自定义popwindow中重写showAsDropDown方法,添加如下代码)
public class MyPopupWindow extends PopupWindow {
....代码省略....
@Override
public void showAsDropDown(View anchor) {
if (Build.VERSION.SDK_INT >= 24) {
Rect rect = new Rect();
anchor.getGlobalVisibleRect(rect);
int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom;
setHeight(h);
}
super.showAsDropDown(anchor);
}
....代码省略....
}
3、APK signature scheme V2(建议打包V1和V2都勾选)
Android 7.0 引入一项新的应用签名方案 APK Signature Scheme V2,它能提供更快的应用安装时间和更多针对未授权 APK 文件更改的保护。在默认情况下,Android Studio 2.2 和 Android Plugin for Gradle 2.2 会使用 APK Signature Scheme v2 和传统签名方案来签署您的应用。
1)只勾选V1签名就是传统方案签署,但是在7.0上不会使用V2安全的验证方式。
2)只勾选V2签名7.0以下会显示未安装,7.0上则会使用了V2安全的验证方式。
3)同时勾选V1和V2则所有版本都没问题。
1、需要添加权限:
注意:只有添加此权限,应用才会在安装未知来源应用列表中出现,安装才会出现安装提示,否则即使打开安装未知来源应用也没用
2、通知栏显示(android 8.0以后必须设置通知渠道id否则通知无法显示)
1、初始化通知的数据
private void initNotifaction() {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//ChannelId为"1",ChannelName为"Channel1"
if (Build.VERSION.SDK_INT >= 26) {
builder = new Notification.Builder(this, "1"); //与channelId对应
NotificationChannel channel = new NotificationChannel("1","Channel1", NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(false); //是否在桌面icon右上角展示小红点=====无效
channel.setLightColor(Color.GREEN); //小红点颜色=====无效
channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知=====无效
notificationManager.createNotificationChannel(channel);
} else {
builder = new Notification.Builder(this); //与channelId对应
}
}
2、显示通知栏
设置等级也没有效果
builder.setOnlyAlertOnce(true);//设置通知栏只响一次
private void addNotifaction(int progress) {
//自定义通知栏
builder.setSmallIcon(R.mipmap.desktop_logo);
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_layout);
notification.contentView = remoteViews;
remoteViews.setTextViewText(R.id.tv_app_name,
getString(R.string.app_name));
remoteViews.setProgressBar(R.id.pBar, 100, progress, false);
remoteViews.setTextViewText(R.id.tv_progress, progress + "%");
//普通通知栏
// builder.setSmallIcon(android.R.drawable.stat_notify_chat)
// .setContentTitle("通知")
// .setContentText("xxx")
// .setNumber(3); //久按桌面图标时允许的此条通知的数量
notificationManager.notify(notificationId, notification);//notificationId是通知栏ID不要和channelId混淆了
}
3、关闭对应渠道的通知栏(从状态栏移除===慎用)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//关闭通知通道
notificationManager.deleteNotificationChannel("1");//1为渠道ID
}
3、8.0系统activity及设置透明主题又设置方向会导致应用崩溃:
错误示例:
解决方法:取消透明主题的设置或者不要限制activity的方向
Android9.0不能加载http的url;
解决方法:
解决方法:添加属性android:usesCleartextTraffic="true" 如下:
或者:
在res/xml/network_security_config.xml文件的代码:
1、Android10.0不能获取到设备的IMEI,对于之前一些应用用IMEI作为设备唯一标示的赶紧进行修改吧。
那用什么作为设备的唯一标示呢?
1.1、当首次安装应用时生成一个UUID,将此uuid存到手机存储中,而不是使用SharedPreferences存储,将此uuid上传至服务器进行存储。(缺点:用户手动删除此存储、重置手机那就唯一标识失效了)
1.2、使用ANDROID_ID标识(Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);)
缺点:重置手机失效,Android厂商特制系统不同设备拥有相同ANDROID_ID,或者获取ANDROID_ID为空;
1.3、使用极光推送、阿里推送等推送sdk获取它们的DeviceId作为设备唯一标识;