android 版本号适配 9.0网络请求方法

预览

    • 河马过河
    • [android 版本号适配 9.0网络请求方法](http://www.cocoachina.com/articles/29242)
    • 版本更新适配android9.0
    • 动态权限获取

2020年4月20–2020年4月26
日常经验整理,有问题请留言。或者加Q:3131713955

关于我

2020年4月15日

河马过河

https://www.jianshu.com/p/30cf2478182d
简述:里面是作者根据自己的开发经验集锦的链接大全,应该是他认为写的好的:里面包括了:OkHttp3-拦截器、retrofit2.0使用、抓包工具Fiddler、微信小程序控件等,满满的干货。唯一的缺点就是在介绍:性能优化文章 时候,链接过长。避免看起来冗长,建议给文字设置超链接。

2020年4月16日

android 版本号适配 9.0网络请求方法

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

首先应该知道android9.0包括自身以及以上的版本都需要做权限适配。对于用户来说提高了安全,对于程序员来说,增加了不少的工作量。
1、适配android9.0,当时我的任务是应用更新版本的时候进行适配。如果没有适配的话,无法安装应用,有时候下载也会失败。
步骤:

  • AndroidManifest.xml
<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>
  • 1、其中,假如你的项目是androidx的那么android:name就改成androidx
  • 2、至于 android:authorities,可以任意给定,相当于布局文件的控件的name,一般是"包名.fileprovider",我这里的${applicationId}就是指的包名。
  • 3、至于android:resource,在res文件夹下面新建xml文件,并创建file_paths.xml.

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进行下面操作就行)

  • MainActivity_App.class
 @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);
		}
}

这样就可以了。

你可能感兴趣的:(android进阶,总结篇)