核心代码:
//保存图片到相册 fileName文件名 PixelMap 图片数据
private void saveImageToLibrary(String fileName, PixelMap pixelMap) {
try {
ValuesBucket valuesBucket = new ValuesBucket();
//文件名
valuesBucket.putString(AVStorage.Images.Media.DISPLAY_NAME, fileName);
//相对路径
valuesBucket.putString("relative_path", "DCIM/");
//文件格式,类型要一定要注意要是JPEG,PNG类型不支持
valuesBucket.putString(AVStorage.Images.Media.MIME_TYPE, "image/JPEG");
//应用独占:is_pending设置为1时表示只有该应用能访问此图片,其他应用无法发现该图片,当图片处理操作完成后再吧is_pending设置为0,解除独占,让其他应用可见
valuesBucket.putInteger("is_pending", 1);
//鸿蒙的helper.insert方法和安卓的contentResolver.insert方法有所不同,安卓方法直接返回一个uri,我们就可以拿来直接操作,而鸿蒙方法返回官方描述是Returns the index of the inserted data record(返回插入的数据记录的索引),这个index我的理解就是id,因此,我们需要自己在后面拼出文件的uri再进行操作
DataAbilityHelper helper = DataAbilityHelper.creator(this);
int index = helper.insert(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, valuesBucket);
Uri uri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(index));
//获取到uri后,安卓通过contentResolver.openOutputStream(uri)就能获取到输出流来写文件,而鸿蒙没有提供这样的方法,我们就只能通过uri获取FileDescriptor,再通过FileDescriptor生成输出流打包编码成新的图片文件,这里helper.openFile方法一定要有“w”写模式,不然会报FileNotFound的错误。
FileDescriptor fd = helper.openFile(uri, "w");
ImagePacker imagePacker = ImagePacker.create();
ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
OutputStream outputStream = new FileOutputStream(fd);
packingOptions.format = "image/jpeg";
packingOptions.quality = 90;
boolean result = imagePacker.initializePacking(outputStream, packingOptions);
if (result) {
result = imagePacker.addImage(pixelMap);
if (result) {
long dataSize = imagePacker.finalizePacking();
}
}
outputStream.flush();
outputStream.close();
valuesBucket.clear();
//解除独占
valuesBucket.putInteger("is_pending", 0);
helper.update(uri, valuesBucket, null);
} catch (Exception e) {
e.printStackTrace();
}
}