精品相机中使用GPS和网络定位获取用户拍照时的地理位置.docx
- 文档编号:26234630
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:12
- 大小:232.26KB
精品相机中使用GPS和网络定位获取用户拍照时的地理位置.docx
《精品相机中使用GPS和网络定位获取用户拍照时的地理位置.docx》由会员分享,可在线阅读,更多相关《精品相机中使用GPS和网络定位获取用户拍照时的地理位置.docx(12页珍藏版)》请在冰豆网上搜索。
精品相机中使用GPS和网络定位获取用户拍照时的地理位置
相机中使用GPS和网络定位获取用户拍照时的地理位置
相机中使用定位服务获取拍照时的地理位置
M厂产品软件部邹建敏
一、基础知识
现代智能手机的一个重要功能就是定位,当用户在使用相机拍照时如果能够记录当前照片拍摄时的地理位置信息,并且按照不同的地理位置把照片分成不同的文件夹,对于喜欢旅游和拍照的用户来说这是一个很好的体验。
在Android手机中通过定位获取地理位置一般有以下几种方式:
1、GPS或AGPS:
使用GPS定位需要在室外使用,在室内是接受不到GPS卫星信号,也当然不能定位。
GPS使用一个卫星群将地点和时间数据从太空直接发送到你的手机上。
如果手机接收来自3个卫星的信号,那么它可以显示你在地图上的方位,如果手机可以接收4个卫星的信号,它还可以显示出你的海拔。
在室内由于接受不到GPS卫星信号,可以使用AGPS(辅助GPS)定位,它的原理和GPS定位的不同点在于AGPS是通过使用数据网络(GPRS、3G等)或者Wi-Fi向GPS卫星发送定位数据,所以使用AGPS需要网络支持,而GPS不需要网络。
2、基站定位:
由于运营商的每个基站都有确定的编号和位置,运营商可以根据用户当前使用的基站与周围基站的距离来确定用户的当前的位置,所以基站定位在基站分布密集的城市定位更精确。
3、Wi-Fi定位:
原理与基站定位相同,主要区别在于Wi-Fi定位使用的是用户当前接入点的位置,由于Wi-Fi的覆盖区域更小,所以它的精确度更高。
后两种定位方式由于需要网络的支持,所以在AndroidSDK中统一为基于网络的定位即网络定位。
二、如何使用定位服务获取地理位置
在Android手机的应用中使用定位服务,一般有以下几个步骤:
下面结合11071项目相机中GPS定位和网络定位来了解在手机应用中怎么获取当前的地理位置。
1、获取定位服务的LocationManager
//定义LocationManager对象
privateLocationManagermLocationManager=null;
//通过getSystemService()方法获取LocationManager
if(null==mLocationManager){
mLocationManager=(LocationManager)getSystemService(
Context.LOCATION_SERVICE);
}
2、实现监听器的接口(android.location.LocationListener),其中有些重要的变量和函数如下:
//实现接口的内部类变量
LocationmLastLocation;//定义Location对象
StringmProvider;//获取Location的Provider
booleanmValid=false;//标志获取的Location是否有效
//内部类的构造函数,需要参数provider,provider一般有两种:
LocationManager.GPS_PROVIDER和LocationManager.NETWORK_PROVIDER
publicLocationListener(Stringprovider){
mProvider=provider;//设置provider(定位方式)
mLastLocation=newLocation(mProvider);//创建Location对象
}
//当获取到新位置或者位置发生变化时调用,
publicvoidonLocationChanged(LocationnewLocation){
//判断获取到的位置是否合法
if(newLocation.getLatitude()==0.0&&
newLocation.getLongitude()==0.0){
return;
}
//当获取到的位置合法时,通过Location的set()方法更新位置
mLastLocation.set(newLocation);
mValid=true;
}
//获取当前最新的位置对象,首先判断当前的Location是否合法,如果合法则返回Location对象,否则返回Null
//定义LocationListener对象
3、开启位置服务监听,使用方法startReceivingLocationUpdates(),如下所示:
protectedvoidstartReceivingLocationUpdates(){
CameraLog.v(TAG,"startReceivingLocationUpdates()");
if(null==mLocationManager){
return;
}
//判断是否打开GPS开关
if(mLocationManager.isProviderEnabled(
LocationManager.GPS_PROVIDER)){
try{
//开始要求更新位置信息,使用GPS定位方式
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
5000,
0F,
mLocationListeners[0]);
}catch(java.lang.SecurityExceptionex){
CameraLog.v(TAG,"Failtorequestlocationupdate,ignore.",ex);
}catch(IllegalArgumentExceptionex){
CameraLog.v(TAG,"GPSproviderdoesnotexist."+ex.getMessage());
}
}
//检测当前手机网络是否可用
if(checkInternet()){
//判断使用网络方式获取位置的开关是否打开
if(mLocationManager.isProviderEnabled(
LocationManager.NETWORK_PROVIDER)){
try{
//开始要求更新位置信息,使用网络定位方式
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
5000,
0F,
mLocationListeners[1]);
}catch(java.lang.SecurityExceptionex){
CameraLog.v(TAG,"Failtorequestlocationupdate,ignore.",ex);
}catch(IllegalArgumentExceptionex){
CameraLog.v(TAG,"Networkproviderdoesnotexist."+ex.getMessage());
}
}
}
}
在上面的代码中使用到一个重要的函数来更新位置:
LocationManager.requestLocationUpdates(Stringprovider,longminTime,floatminDistance,LocationListenerlistener),该方法的作用是通过给定的provider名称,并将其绑定指定的LocationListener监听器,周期性的更新位置信息,其中第一个参数是provider名称即定位的方式,一般为GPS和NetWork两种,第二个参数是更新位置的时间,单位是毫秒,第三个是更新的距离,单位是米,第四个参数是位置服务的监听。
4、获取和使用最新的位置信息,主要工作是如何把已经获取到的位置信息(经度和纬度)设置到照片中和保存到数据库中
(1)获取最新的位置信息,主要方法是getCurrentLocation(),改方法返回一个Location对象。
protectedLocationgetCurrentLocation(){
CameraLog.v(TAG,"getCurrentLocation()");
Locationl=null;
for(inti=0;i //获取LocationListener中最新更新的位置信息 l=mLocationListeners[i].current(); //判断是否已经获取到合法的位置信息 if(null! =l){ break;//退出循环 } } returnl; } (2)使用获取的位置信息 a、在拍照时把位置信息设置到照片中,在11071的相机中主要有以下步骤: 1)在onSnap()方法中获取当前的位置信息,通过调用getCurrentLocation() Locationloc=getCurrentLocation(); 2)在在onSnap()方法中调用CameraDevice的setPictureInfo()方法把位置信息添加到照片中 mCameraDevice.setPictureInfo(rotation,loc);//设置照片信息 以下是该方法的详解: publicvoidsetPictureInfo(intlastOrientation,Locationloc){ CameraLog.v(TAG,"setPictureInfo()"); //判断当前的Camera是否为打开状态 if(mCameraStatus==CAMERA_DEVICE_STATUS_CLOSED){ CameraLog.v(TAG,CAMERA_DEVICE_NOT_OPENED); return; } //设置照片的方向 mParameters.setRotation(lastOrientation); //清楚照片参数中已有的GPS数据 mParameters.removeGpsData(); //设置照片的GPS时间戳 mParameters.setGpsTimestamp(System.currentTimeMillis()/1000); //设置照片的位置信息 //判断获取的位置信息是否为空,为空说明在拍照时还没有获取到用户当前的位置信息 if(null! =loc){ doublelat=loc.getLatitude();//获取纬度 doublelon=loc.getLongitude();//获取经度 //判断经度和纬度是否有效 booleanhasLatLon=(lat! =0.0d)||(lon! =0.0d); if(hasLatLon){ mParameters.setGpsLatitude(lat);//设置照片的纬度信息 mParameters.setGpsLongitude(lon);//设置照片的经度信息 mParameters.setGpsProcessingMethod(loc.getProvider().toUpperCase());//设置获取位置的provider即定位的方式 //设置高度获取海拔 if(loc.hasAltitude()){ mParameters.setGpsAltitude(loc.getAltitude()); }else{ mParameters.setGpsAltitude(0); } } } mCamera.setParameters(mParameters);//更新参数 } b、把位置信息保存到数据库中,在保存照片时调用getCurrentLocation()方法获取位置信息,并调用ImageManager.addImage()保存照片信息到数据库中。 1)在BaseCameraActivity.java的storeImage()方法中调用getCurrentLocation()获取位置信息: mImageCapture.storeImage(jpegData,BaseCameraActivity.this, getCurrentLocation(),storeDir,mCameraEntryType==CAMERA_ENTRY_FROM_OTHER_APP,mCameraId); 2)在ImageCapture.java的storeImage()方法中调用ImageManager的addImage()方法保存照片信息到数据库中: mLastContentUri=ImageManager.addImage( context.getContentResolver(), title,dateTaken,loc, storeDir,filename,data,degree); 3)在ImageManager.java的addImage()方法中把经度和纬度数据保存到数据库中: //判断位置信息是否为空 if(null! =location){ //写入纬度数据 values.put(Images.Media.LATITUDE,location.getLatitude()); //写入经度数据 values.put(Images.Media.LONGITUDE,location.getLongitude()); } //通过ContentResolver的insert()方法把数据保存到数据库中 uri=cr.insert(Images.Media.EXTERNAL_CONTENT_URI,values); 5、结束位置服务的监听,在stopReceivingLocationUpdates()方法中通过调用LocationManager.removeUpdates()方法来结束监听: protectedvoidstopReceivingLocationUpdates(){ if(null==mLocationManager){ return; } for(inti=0;i try{ //结束监听,去除LocationManager的LocationListener mLocationManager.removeUpdates(mLocationListeners[i]); }catch(Exceptionex){ CameraLog.v(TAG,"failtoremovelocationlistners,ignore",ex); } } } 6、在完成以上步骤后,要在Android应用中使用位置服务还需要很重要的一步: AndroidManifest.xml中使用注册服务的权限 在相机中已经把拍照时的经度和纬度设置到照片中并保存至数据库中,那么怎么把经度和纬度转反向编码换成具体的地理位置,这一步在11071项目中由相册完成,主要通过Geocoder的publiclist 下面是在相册中显示照片地理位置界面,要想把经度和纬度转换成具体的地理位置,前提是手机需要连上网络。 三、问题及总结 在11071的相机中使用定位服务时碰到这样几个问题: 1、在设置—个人安全—我的位置—使用无线网络开关打开,连上无线网络,但是也获取不到地理位置,后来通过与定位服务组找到原因是网络定位的权限文件(/system/etc/permissions/com.android.location.provider.xml)没有移植,这个文件是Google提供的使用网络定位服务的权限文件,没有的话通过网络方式定位不到地理位置;2、在相机中开启定位后,有时会导致相机中拍照后缩略图更新错乱问题即缩略图更新的都是同一张,查找原因得知在数据库中有一张照片的属性(datetaken)值比其他照片的都大很多,所以在更新缩略图时读取的都是这张照片的缩略图,导致缩略图错乱。 那么为什么这张照片的(datetaken)属性值会这么大呢? 后来通过查找得知在拍照时如果有位置信息,会通过Location.getTime()方法获取GPS时间戳设置到照片的Exif信息中,在拍完照后扫描服务会扫描该照片,通过Exif.getGpsDateTime()方法读取照片Exif信息中GPS时间戳,如果时间戳不等于-1则会把时间戳更新到数据库中覆盖照片的datetaken属性值,具体代码如下:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 精品 相机 使用 GPS 网络 定位 获取 用户 拍照 地理位置