最近在写一个项目,需要获取照片的地理位置信息,一般来说,手机在拍照的时候,如果相机打开了保存地理位置的开关,那么拍摄出来的照片就会带有手机当时所在地的地理位置信息。
在Android开发中,需要获取图片位置信息的需求~~emmm,还是挺少见的。
最开始,我是通过ContentProvider读取本地媒体数据库来获得位置信息的。具体代码如下:
private void getPhotoLocation() {
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, SELECTIMAGES, null, null, null);
int i =0;
if (cursor !=null) {
while (cursor.moveToNext()) {
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
File file =new File(path);
if (!file.exists() || !file.canRead())continue;
float latitude = cursor.getFloat(cursor.getColumnIndex(MediaStore.Images.Media.LATITUDE));
float longitude = cursor.getFloat(cursor.getColumnIndex(MediaStore.Images.Media.LONGITUDE));
i++;
Log.d(TAG + i, "latitude:---" + latitude +" " +"longitude:--" + longitude);
}
}
}
然后,发现在Android10手机上就获取不到经纬度了,全部是0。
最后发现是因为Android10以后,本地媒体数据库中的数据文件中已经没有latitude和longitude这两列了。
最后我的解决办法是,不通过本地媒体数据库拿经纬度数据,而是直接读取图片文件的exif信息。
核心代码如下:
ExifInterface exif =null;
try {
exif =new ExifInterface(path);
String TAG_GPS_LATITUDE = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
String TAG_GPS_LONGITUDE = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
}catch (IOException e) {
e.printStackTrace();
}
然后,你会发现获取到的TAG_GPS_LATITUDE和TAG_GPS_LONGITUDE的值是类似于这样的:27/1,36/1,311508/10000。
其实这是经纬度坐标的另一种表达格式,而我们常用的经纬度格式就是一个小数,例如:27.608653。
这里有篇文章解释了经纬度的格式:https://blog.csdn.net/lhl161123/article/details/73470012
看完文章就知道我们要把上面那串字符转换成正常的小数形式就要做如下计算:
27/1 + (36/1)/60 +(311508/10000)/3600 =27+36/60+31.1508/3600 = 27.608653。
最终的代码如下:
private void getPhotoLocation() {
private static final String[] SELECTIMAGES = {
MediaStore.Images.Media.DATA,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.TITLE,
MediaStore.Images.Media.DATE_ADDED,
MediaStore.Images.Media.DATE_MODIFIED,
MediaStore.Images.Media.LATITUDE,
MediaStore.Images.Media.LONGITUDE,
MediaStore.Images.Media.SIZE
};
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, SELECTIMAGES, null, null, null);
int i =0;
if (cursor !=null) {
while (cursor.moveToNext()) {
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
File file =new File(path);
if (!file.exists() || !file.canRead())continue;
float latitude = cursor.getFloat(cursor.getColumnIndex(MediaStore.Images.Media.LATITUDE));
float longitude = cursor.getFloat(cursor.getColumnIndex(MediaStore.Images.Media.LONGITUDE));
if (latitude ==0 && longitude ==0) {
ExifInterface exif =null;
try {
exif =new ExifInterface(path);
String TAG_GPS_LATITUDE = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
String TAG_GPS_LONGITUDE = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
if (!TextUtils.isEmpty(TAG_GPS_LATITUDE) && !TextUtils.isEmpty(TAG_GPS_LONGITUDE)) {
TAG_GPS_LATITUDE = TAG_GPS_LATITUDE.replace("/", ",");
TAG_GPS_LONGITUDE = TAG_GPS_LONGITUDE.replace("/", ",");
String[] lat = TAG_GPS_LATITUDE.split(",");
String[] lng = TAG_GPS_LONGITUDE.split(",");
Float latD =0f;
Float latM =0f;
Float latS =0f;
Float lngD =0f;
Float lngM =0f;
Float lngS =0f;
if (lat.length >=2) {
latD = Float.parseFloat(lat[0]) / Float.parseFloat(lat[1]);
}
if (lat.length >=4) {
latM = Float.parseFloat(lat[2]) / Float.parseFloat(lat[3]);
}
if (lat.length >=6) {
latS = Float.parseFloat(lat[4]) / Float.parseFloat(lat[5]);
}
if (lng.length >=1) {
lngD = Float.parseFloat(lng[0]) / Float.parseFloat(lng[1]);
}
if (lng.length >=2) {
lngM = Float.parseFloat(lng[2]) / Float.parseFloat(lng[3]);
}
if (lng.length >=3) {
lngS = Float.parseFloat(lng[4]) / Float.parseFloat(lng[5]);
}
latitude = latD + latM /60 + latS /3600;
longitude = lngD + lngM /60 + lngS /3600;
}
}catch (IOException e) {
e.printStackTrace();
}
}
i++;
Log.d(TAG + i, "latitude:---" + latitude +" " +"longitude:--" + longitude);
}
}
}
先是将字符串中的/转换成,,然后通过,分割字符串获得一个长度为6的数组,最后通过这六个数计算出经纬度值。