android扫描手机里的图片位置信息和exif信息

手机拍照的照片有一个叫Exif的东西,记录着图片拍摄时候的一些信息。正因为如此,很多人的隐私会暴露。

图片位置信息哪里来的呢

新手机在打开摄像头app的时候会提示,拍的照片是否要记录位置信息,一般的人在有了新手机后迫不及待自拍的都会选择是。后面拍照都会记录位置信息到照片中,这就很危险了,一些app获取这些位置信息就可以知道你的活动范围在哪里。。。

exif里面有什么信息呢

常用的Exif支持的tag有:
TAG_APERTURE:光圈值
TAG_DATETIME:拍摄时间
TAG_EXPOSURE_TIME:曝光时间
TAG_FLASH:闪光灯
TAG_FOCAL_LENGTH:焦距
TAG_IMAGE_LENGTH:图片高度
TAG_IMAGE_WIDTH:图片宽度
TAG_ISO:ISO
TAG_MAKE:设备
TAG_MODEL:设备型号
TAG_ORIENTATION:旋转角度

android如何读取exif

老规则,开源库走起,github找了一会,发现有轻量的,有重的,从中选择了一个轻量的,如下

https://github.com/sephiroth74/Android-Exif-Extended

其实google有提供了exif类,全部的tag这一个文件

https://android.googlesource.com/platform/packages/apps/Camera2/+/master/src/com/android/camera/exif/ExifInterface.java

实战一下,获取拍照路径下面的图片,进行遍历获取exif信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
fun Context.getPicExifInfo(startTime: Long = 0, endTime: Long = TimeUtils.getNowMills()): List<PicExifInfo> {
val list = mutableListOf<PicExifInfo>()
val cursor = contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, "${MediaStore.Images.Media.DATE_ADDED} > ? and ${MediaStore.Images.Media.DATE_ADDED} <= ?",
arrayOf((startTime / 1000).toString(), (endTime / 1000).toString()),
MediaStore.Images.Media.DATE_ADDED
)
cursor?.let {
while (cursor.moveToNext()) {
val path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
val title = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.TITLE))
val width = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.WIDTH))
val height = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.HEIGHT))
val exif = ExifInterface()
try {
exif.readExif(path, ExifInterface.Options.OPTION_ALL)
val latLon = exif.latLongAsDoubles
if (latLon != null && latLon.size > 1) {
val latitude = String.format("%.6f", latLon[0])
val longitude = String.format("%.6f", latLon[1])
}
val model = exif.getTag(ExifInterface.TAG_MODEL)?.valueAsString?.trim(0.toChar()) ?: ""
val make = exif.getTag(ExifInterface.TAG_MAKE)?.valueAsString?.trim(0.toChar()) ?: ""
val temp = exif.getTag(ExifInterface.TAG_DATE_TIME)?.valueAsString?.trim(0.toChar())
val time = temp?.let { TimeUtils.string2Millis(it, "yyyy:MM:dd HH:mm:ss").toString() } ?: ""
val exifInfo = PicExifInfo(title, width, height, latitude, longitude, make, model, time)
list.add(exifInfo)
} catch (e: IOException) {
e.printStackTrace()
}
}
}
cursor?.close()
return list
}

还有一个要注意的

kotlin里面如果byte数据后面全是0,转换成string要显示,要这样处理

1
string?.trim(0.toChar())

ps:

是不是可以做一个显示自己什么时候去过哪里的app,加上现在有各种存储云,无论多久以前的照片都会在会端拉回到手机。是不是很可怕的app。权限只需要读存储权限。