GPS
GPS用户驱动程序允许您的应用程序通过Android 定位服务 发布设备的物理位置更新。 .
GPS模块是仅接收设备,用于对来自远程卫星的信号进行三角测量,以确定准确的物理位置。一旦GPS模块收集足够的卫星数据来计算准确的位置,它就具有可以报告的有效位置(修复)。
GPS模块通常通过 UART 连接到主机系统,但可以使用其他形式的外设 I/O。例如,它们可能包含额外的 GPIO 引脚来控制电源管理,或者在模块获得或丢失修复时报告。
创建驱动程序
驱动程序实现负责与连接的GPS硬件进行通信,监控有效的位置变化,并向框架报告这些更改。要创建驱动程序:
GpsDriver
实例:用 UserDriverManager
注册驱动程序:
import com.google.android.things.userdriver.GpsDriver;
import com.google.android.things.userdriver.UserDriverManager;
...
public class GpsDriverService extends Service {
private GpsDriver mDriver;
@Override
public void onCreate() {
super.onCreate();
// Create a new driver implementation
mDriver = new GpsDriver();
// Register with the framework
UserDriverManager manager = UserDriverManager.getManager();
manager.registerGpsDriver(mDriver);
}
}
不再需要位置事件时,请注销驱动程序。
public class GpsDriverService extends Service {
...
@Override
protected void onDestroy() {
super.onDestroy();
UserDriverManager manager = UserDriverManager.getManager();
manager.unregisterGpsDriver(mDriver);
}
}
报告位置
使用 reportLocation()
方法向Android框架报告每个新的位置修复。此方法接受一个 Location 对象,该对象包含要报告的更新内容。将每个报告的 Location
的提供程序设置为 LocationManager.GPS_PROVIDER
。
import android.location.Location;
...
public class GpsDriverService extends Service {
private GpsDriver mDriver;
...
private Location parseLocationFromString(String gpsData) {
Location result = new Location(LocationManager.GPS_PROVIDER);
// ...parse raw GPS information...
return result;
}
public void handleLocationUpdate(String rawGpsData) {
// Convert raw data into a location object
Location location = parseLocationFromString(rawGpsData);
// Send the location update to the framework
mDriver.reportLocation(location);
}
}
下表描述了GPS驱动程序可以向框架报告的位置属性。必须包含标记为必需的属性,否则框架将拒绝位置更新:
必需属性 | 可选属性 |
---|---|
Accuracy Timestamp Latitude Longitude |
Altitude Bearing Speed |
将GPS数据转换为位置对象
GPS硬件通常以 NMEA 标准格式 的ASCII字符串报告位置信息。每行数据都是以逗号分隔的数据值列表,称为句子。虽然每个GPS模块可以选择报告NMEA协议的不同部分,但是大多数设备发送以下一个或多个句子:
例如,GPRMC
句子采用以下格式:
$GPRMC,<Time>,<Status>,<Latitude>,<Longitude>,<Speed>,<Angle>,<Date>,<Variation>,<Integrity>,<Checksum>
使用实际的数据值,这里是一个示例GPRMC
,纬度,经度和速度部分以粗体突出显示:
$GPRMC,172934.975,V,3554.931,N,07402.499,W,16.4,3.35,300816,,E*41
以下代码示例将 GPRMC
字符串格式解析为“Location ”实例:
// Convert latitude from DMS to decimal format
private float parseLatitude(String latString, String hemisphere) {
float lat = Float.parseFloat(latString.substring(2))/60.0f;
lat += Float.parseFloat(latString.substring(0, 2));
if (hemisphere.contains("S")) {
lat *= -1;
}
return lat;
}
// Convert longitude from DMS to decimal format
private float parseLongitude(String longString, String hemisphere) {
float lat = Float.parseFloat(longString.substring(3))/60.0f;
lat += Float.parseFloat(longString.substring(0, 3));
if (hemisphere.contains("W")) {
lat *= -1;
}
return lat;
}
// Return a location from an NMEA GPRMC string
public Location parseLocationFromString(String rawGpsData) {
// Tokenize the string input
String[] nmea = rawGpsData.split(",");
Location result = new Location(LocationManager.GPS_PROVIDER);
// Create timestamp from the date + time tokens
SimpleDateFormat format = new SimpleDateFormat("ddMMyyhhmmss.ss");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date date = format.parse(nmea[9] + nmea[1]);
result.setTime(date.getTime());
} catch (ParseException e) {
return null;
}
// Parse the fix information tokens
result.setLatitude(parseLatitude(nmea[3], nmea[4]));
result.setLongitude(parseLongitude(nmea[5], nmea[6]));
result.setSpeed(Float.parseFloat(nmea[7]));
return result;
}