【IT168技术】 随着手机集成度和性能的提高,现在越来越多的智能手机提供了GPS功能,而各种各样的位置相关的应用(LBS – Location Based Services)也在手机上流行起来,常见的位置应用包括:
- 在地图上显示你当前的位置
- 搜索你当前位置周边的设施,如果饭馆,电影院,商场,加油站等
- 查询你的亲友所在的位置 (隐私设置,需对方同意)
- 驾车导航去一个你从来没去过的地方
- 父母可以跟踪孩子的位置
另外OPhone OS不仅仅支持了GPS,还支持A-GPS(Assisted GPS),A-GPS比GPS有更快的首次定位时间(TTFF – Time to First Fix)和更精准的首次定位精度,并可以在卫星信号相对较弱的环境下获得位置。目前已经有多家导航厂商的产品可以支持OPhone OS,包括:泰维,灵图(天行者), 凯立德,图吧。


如何编写一个LBS应用
1、设置
在OPhone OS上使用位置服务,首先需要在”设置”->”我的位置”里选中GPS或A-GPS (A-GPS需要GPRS网络连接)。

如果没有打开设置,应用程序会受到下面的回调,可以按参考代码实现。
{
Log.i(TAG, "listener onProviderDisabled");
/*
* 弹出对话框,提示用户当前GPS/A-GPS没有使能
*/
AlertDialog dialog = new AlertDialog.Builder(GpsAPITest.this)
.setTitle("Provider " + provider + " is disabled...")
.setMessage("In order to use this tool, you need to turn on the provider " + provider +
" Receiver of your device.\n\n" + "Click Ok to go to the system-settings, or Cancel to leave.\n\n" +
"After that please restart this tool")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/*
* 转到设置界面
*/
Intent fireAlarm = new Intent("android.settings.LOCATION_SOURCE_SETTINGS");
fireAlarm.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(fireAlarm);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
finish();
}
})
.create();
dialog.show();
}
2、在AndroidManifest.xml文件里面加上以下的权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
3、通过LocationListener来获得位置
LocationManager是整个Location Services的核心类,通过getSystemService(Context.LOCATION_SERVICE)来获得LocationManager的对象。
private LocationManager mService;
private LocationListener mListener = new LocationListener()
{
// 底层获得的位置会通过这个接口上报给应用
public void onLocationChanged(Location location)
{
}
// 如果GPS/A-GPS没有使能会通过这个接口通知应用
public void onProviderDisabled(String provider)
{
}
// GPS/A-GPS使能的时候应用也会得到通知
public void onProviderEnabled(String provider)
{
}
// 位置服务状态的变化通过这个接口上报
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
// LocationManager是一个系统服务,必须通过getSystemService来获得
mService = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
try {
// 请求使用GPS,应用需要处理抛出的以下异常
mService.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mListener);
} catch (SecurityException ex1) {
} catch (IllegalArgumentException ex2) {
} catch (RuntimeException ex3) {
}
...
try {
// 使用完毕需要remove
mService.removeUpdates(mListener);
} catch (IllegalArgumentException ex) {
}
如果使用A-GPS,只需要在requestLocationUpdates的时候指明使用LocationManager.AGPS_PROVIDER即可。
4、显示位置信息以及卫星信息
当底层获得位置的时候,会通过LocationListener的onLocationChanged来通知上层的应用。应用可以获得当前位置的经纬度,高度,速度,方位已经卫星信息。
// 经度
mLongitude = String.valueOf(mLoc.getLongitude());
// 纬度
mLatitude = String.valueOf(mLoc.getLatitude());
// 高度
mAltitude = String.valueOf(mLoc.getAltitude());
// 速度
mSpeed = String.valueOf(mLoc.getSpeed());
// 方位 0 - 360度
mBearing = String.valueOf(mLoc.getBearing());
// 世界戳 从1970/1/1起始,单位: 毫秒
mTime = String.valueOf(mLoc.getTime());
// 定位经度,单位: 米
if (mLoc.hasAccuracy())
mAccuracy = String.valueOf(mLoc.getAccuracy());
else
mAccuracy = "no accuracy";
Bundle bundle = mLoc.getExtras();
if (null != bundle)
{
// 首次定位时间 TTFF = Time to First Fix,单位: 秒
int ttff = bundle.getInt("TTFF", 0);
mTTFF = String.valueOf(ttff);
// 参与定位的卫星个数
int numSatellite = bundle.getInt("NumSatellite", 0);
mNumSatellite = String.valueOf(numSatellite);
if (numSatellite != 0) {
mSatelliteInfo = "";
for (int m = 0; m < numSatellite; m++) {
// 卫星的ID
mSatelliteInfo += String.valueOf(m + 1) + ": " + "ID " + String.valueOf(bundle.getInt("SatelliteID" + m, 0)) + ", ";
// 卫星的信号强度 C/NO
mSatelliteInfo += "Strength: " + String.valueOf(bundle.getInt("SignalStrength" + m, 0)) + ", ";
// 方位角
mSatelliteInfo += "Azimuth: " + String.valueOf(bundle.getInt("Azimuth" + m, 0)) + ", ";
// 标高
mSatelliteInfo += "ElevationAngle: " + String.valueOf(bundle.getInt("ElevationAngle" + m, 0)) + "\n";
}
}
}
}
如果底层在一定时间内无法获得位置,则会通过LocationListener的onStatusChanged接口通知上层应用,应用程序可以通知用户进行相应的处理。
5、使用NMEA接口
在OPhone OS上除了Locaiton的接口,还提供了NMEA的接口,这样很多已有的导航应用可以更方便的porting到OPhone OS上。
import android.location.NmeaListener.java;
private LocationManager mService;
private NmeaListener mListener = new NmeaListener() {
// 底层上报的NMEA语句通过此接口通知应用
void onNmeaChanged(String nmea) {
}
// 同LocationListener
void onStatusChanged(String provider, int status, Bundle extras) {
}
// 同LocationListener
void onProviderEnabled(String provider) {
}
// 同LocationListener
void onProviderDisabled(String provider) {
}
}
try {
// 请求NMEA
mService.requestNmeaUpdates(LocationManager.GPS_PROVIDER, 0, 0, mListener);
} catch (SecurityException ex1) {
} catch (IllegalArgumentException ex2) {
} catch (RuntimeException ex3) {
}
...
try {
// 关闭NMEA
mService.removeNmeaUpdates(mListener);
} catch (IllegalArgumentException ex) {
}
结束语
OPhone OS上的位置服务,目标就是提供简单,统一的接口给第三方应用开发者,帮助他们方便的使用位置服务,接口仍在完善当中。(作者:周安乐)