2020年4月20–2020年4月26
日常经验整理,有问题请留言。或者加Q:3131713955
关于我
2020年4月15日
https://www.jianshu.com/p/30cf2478182d
简述:里面是作者根据自己的开发经验集锦的链接大全,应该是他认为写的好的:里面包括了:OkHttp3-拦截器、retrofit2.0使用、抓包工具Fiddler、微信小程序控件等,满满的干货。唯一的缺点就是在介绍:性能优化文章 时候,链接过长。避免看起来冗长,建议给文字设置超链接。
2020年4月16日
http://www.cocoachina.com/articles/29242里面有种方法比较适用。
为什么要适配网络请求:在9.0中默认情况下启用网络传输层安全协议 (TLS),默认情况下已停用明文支持。也就是不允许使用http请求,要求使用https。
AndroidManifest.xml中的application添加:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config">
...
</application>
</manifest>
为了安全灵活,我们可以指定支持的http域名:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!-- Android 9.0 上部分域名时使用 http -->
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">secure.example.com</domain>
<domain includeSubdomains="true">cdn.example1.com</domain>
</domain-config>
</network-security-config>
2020年4月20日
参考资料
应用更新适配android9.0
android动态权限获取
首先应该知道android9.0包括自身以及以上的版本都需要做权限适配。对于用户来说提高了安全,对于程序员来说,增加了不少的工作量。
1、适配android9.0,当时我的任务是应用更新版本的时候进行适配。如果没有适配的话,无法安装应用,有时候下载也会失败。
步骤:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
第一个权限必须加上,至于第二个,根据需要,假如项目中有webView控件的时候,使用这个权限不会出现加载错误的问题
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<root-path
name = "root_path"
path = "."/>
<external-cache-path name="cache_download" path="download"/>
</paths>
可以根据需要酌情设置,也可以按照这个配置,万能的。
然后就是最重要的一步。
自动安装应用的工具类 autoInstallApk.class
例如,我的项目是在下载文件完成之后进入安装界面。
@Override
public void onSuccess(File result) {
AppUtil.autoInstallApk(context, result);
dismiss();
}
下载成功的回调方法,在这里调用跳转安装界面。
public class AppUtil {
/*
* 适配android 9.0 自动安装apk
* */
public static void autoInstallApk( Context context, File file ) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri contentUri = getUriForFile(context, file);
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// 声明需要的临时的权限
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
context.startActivity(intent);
}
/**
* 将文件转换成uri(支持7.0)
*
* @param mContext
* @param file
* @return
*/
public static Uri getUriForFile(Context mContext, File file) {
Uri fileUri = null;
if (Build.VERSION.SDK_INT >= 24) {
fileUri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".fileprovider", file);
} else {
fileUri = Uri.fromFile(file);
}
return fileUri;
}
}
已经做了适配,直接调用就行。
上面我遇到一个坑,就是运行时权限,getUriForFile(),这个方法在android.v4也有直接调用接口,getUriForFile(mContext, authorities,file),意思是还需要加上android:authorities的值,就是之前随便定义的。我直接将“${applicationId}.fileprovider”写上去,同样报错,无法安装。看来是在java文件中无法直接使用这种获取值方法。
(做个大标题,比较显眼)
<application
...
android:usesCleartextTraffic="true">
</application>
这是比较强制的使用,也可以添加
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
但是上面的都必须设置targetSdkVersion26以上才生效。
Build.gradle
添加依赖库
//4,permissionsdispatcher权限
implementation'com.github.hotchemi:permissionsdispatcher:3.3.1'
annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:3.3.1'
然后在你需要动态注册的地方,追溯到Activity层,比如,你是在一个更新下载窗口UpdateApplicationDialog.class需要动态获取权限,那你这就需要找到最终调用他的activity。因为动态获取权限在非view层,比如工具类、窗口类,是不能动态权限注册的。(理解就行,不影响后面的操作,只要知道在你的activity进行下面操作就行)
@RuntimePermissions
public class MainActivity_App extends BaseFragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_app);
MainActivity_AppPermissionsDispatcher.onResumeWithPermissionCheck(this);
}
@Override
@NeedsPermission({Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.REQUEST_INSTALL_PACKAGES})
protected void onResume() {
super.onResume();
//在这里获取动态权限(入口),进去之后就是窗口类(这个只是使用例子,调用入口根据实际情况使用)
URL.CheckUpdate(this, getResources().getString(R.string.app_down_id), true);
}
@SuppressLint ("NeedOnRequestPermissionsResult")
@Override
public void onRequestPermissionsResult( int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// 代理权限处理到自动生成的方法
MainActivity_AppPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
}
这样就可以了。