写点什么

Android10 填坑适配指南,实际经验代码,拒绝翻译,android 开发书籍 pdf 下载

用户头像
Android架构
关注
发布于: 2021 年 11 月 05 日

} else {canvas.clipPath(path, Region.Op.XOR);// REPLACE、UNION 等}


但我们一定需要一些高级逻辑运算效果怎么办?如小说的仿真翻页阅读效果,解决方案如下,用 Path.op 代替,先运算 Path,再给 canvas.clipPath:


if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){Path mPathXOR = new Path();mPathXOR.moveTo(0,0);mPathXOR.lineTo(getWidth(),0);mPathXOR.lineTo(getWidth(),getHeight());mPathXOR.lineTo(0,getHeight());mPathXOR.close();//以上根据实际的 Canvas 或 View 的大小,画出相同大小的 Path 即可 mPathXOR.op(mPath0, Path.Op.XOR);canvas.clipPath(mPathXOR);}else {canvas.clipPath(mPath0, Region.Op.XOR);}

2.明文 HTTP 限制

当?targetSdkVersion >=?Build.VERSION_CODES.P 时,默认限制了 HTTP 请求,并出现相关日志:


java.net.UnknownServiceException: CLEARTEXT communication to xxx not permitted by network security policy


第一种解决方案:在 AndroidManifest.xml 中 Application 添加如下节点代码


<application android:usesCleartextTraffic="true">


第二种解决方案:在 res 目录新建 xml 目录,已建的跳过 在 xml 目录新建一个 xml 文件 network_security_config.xml,然后在 AndroidManifest.xml 中 Application 添加如下节点代码


android:networkSecurityConfig="@xml/network_config"


名字随机,内容如下:


<?xml version="1.0" encoding="utf-8"?><network-security-config><base-config cleartextTrafficPermitted="true" /></network-security-config>

3.Android Q 中的媒体资源读写

1、扫描系统相册、视频等,图片、视频选择器都是通过


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ContentResolver 来提供,主要代码如下:


private static final String[] IMAGE_PROJECTION = {MediaStore.Images.Media.DATA,MediaStore.Images.Media.DISPLAY_NAME,MediaStore.Images.Media._ID,MediaStore.Images.Media.BUCKET_ID,MediaStore.Images.Media.BUCKET_DISPLAY_NAME};


Cursor imageCursor = mContext.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,IMAGE_PROJECTION, null, null, IMAGE_PROJECTION[0] + " DESC");


String path = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[0]));String name = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[1]));int id = imageCursor.getInt(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[2]));String folderPath = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[3]));String folderName = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[4]));


//Android Q 公有目录只能通过 Content Uri + id 的方式访问,以前的 File 路径全部无效,如果是 Video,记得换成 MediaStore.Videosif(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){path = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).build().toString();}


2、判断公有目录文件是否存在,自 Android Q 开始,公有目录 File API 都失效,不能直接通过 new File(path).exists();判断公有目录文件是否存在,正确方式如下:


public static boolean isAndroidQFileExists(Context context, String path){AssetFileDescriptor afd = null;ContentResolver cr = context.getContentResolver();try {Uri uri = Uri.parse(path);afd = cr.openAssetFileDescriptor(uri, "r");if (afd == null) {return false;} else {close(afd);}} catch (FileNotFoundException e) {return false;}finally {close(afd);}return true;}


3、copy 或者下载文件到公有目录,保存 Bitmap 同理,如 Download,MIME_TYPE 类型可以自行参考对应的文件类型,这里只对 APK 作出说明,从私有目录 copy 到公有目录 demo 如下(远程下载同理,只要拿到 OutputStream 即可,亦可下载到私有目录再 copy 到公有目录):


public static void copyToDownloadAndroidQ(Context context, String sourcePath, String fileName, String saveDirName){ContentValues values = new ContentValues();values.put(MediaStore.Downloads.DISPLAY_NAME, fileName);values.put(MediaStore.Downloads.MIME_TYPE, "application/vnd.android.package-archive");values.put(MediaStore.Downloads.RELATIVE_PATH, "Download/" + saveDirName.replaceAll("/","") + "/");


Uri external = MediaStore.Downloads.EXTERNAL_CONTENT_URI;ContentResolver resolver = context.getContentResolver();


Uri insertUri = resolver.insert(external, values);if(insertUri == null) {return;}


String mFilePath = insertUri.toString();


InputStream is = null;OutputStream os = null;try {os = resolver.openOutputStream(insertUri);if(os == null){return;}int read;File sourceFile = new File(sourcePath);if (sourceFile.exists()) { // 文件存在时 is = new FileInputStream(sourceFile); // 读入原文件 byte[] buffer = new byte[1444];while ((read = is.read(buffer)) != -1) {os.write(buffer, 0, read);}}} catch (Exception e) {e.printStackTrace();}finally {close(is,os);}


}


4、保存图片相关


/**


  • 通过 MediaStore 保存,兼容 AndroidQ,保存成功自动添加到相册数据库,无需再发送广播告诉系统插入相册

  • @param context context

  • @param sourceFile 源文件

  • @param saveFileName 保存的文件名

  • @param saveDirName picture 子目录

  • @return 成功或者失败*/public static boolean saveImageWithAndroidQ(Context context,File sourceFile,String saveFileName,String saveDirName) {String extension = BitmapUtil.getExtension(sourceFile.getAbsolutePath());


ContentValues values = new ContentValues();values.put(MediaStore.Images.Media.DESCRIPTION, "This is an image");values.put(MediaStore.Images.Media.DISPLAY_NAME, saveFileName);values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");values.put(MediaStore.Images.Media.TITLE, "Image.png");values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + saveDirName);

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android10填坑适配指南,实际经验代码,拒绝翻译,android开发书籍pdf下载