Android平台下Gps软件跑不动,要怎么修改?

xqhrs232 2011-12-01 06:05:45
Android平台下Gps软件跑不动,要怎么修改?
...全文
747 21 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
jhuang4545 2012-06-10
  • 打赏
  • 举报
回复
楼主您好,我也是2.3的GPS跑步起来。打印信息跟你的差不多。请问您是怎么解决的呢?能不能提供下具体的解决方法呀。万分感谢!
xqhrs232 2011-12-03
  • 打赏
  • 举报
回复
Android平台上GPS信号的获取和展示
http://www.linuxidc.com/Linux/2011-09/42454.htm
FrankBIBI 2011-12-02
  • 打赏
  • 举报
回复
呃。。。。LOCATION开启是读数据库中没有写入GPS。默认servicemanage系统起来的时候就会自动开启GPS这个服务,然后查看是否写入“数据库中没有写入GPS”标志。然后去初始化GPS接口。

恩 查下接口,我当时是framework中有个listern有问题,也没开启,
framework GPS部分还是有一点BUG需要修改的
qthsrs232 2011-12-02
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 lightsoure 的回复:]
GPS软件跑不动,具体描述下哦。
1,确保GPS数据采集到了,看串口
2,framework正确的开启location GPS服务
3,写个测试程序测试下
[/Quote]

应该是没开启location GPS服务
qthsrs232 2011-12-02
  • 打赏
  • 举报
回复
Android之GPS研究(资料篇)
http://blog.chinaunix.net/space.php?uid=25369701&do=blog&id=116109




最近在TI平台上调试GPS模块,收集到一些资料:

1.Android GPS架构分析-preview
2.Android GPS架构分析一
3.Android GPS架构分析二
4.Android GPS架构分析三
5.Android GPS架构分析四
6.Android GPS架构分析五
7.Android GPS架构分析(gps启动过程图)

8.Android GPS

qthsrs232 2011-12-02
  • 打赏
  • 举报
回复
Android之GPS研究(实战篇一)
http://blog.chinaunix.net/space.php?uid=25369701&do=blog&id=118662




TI平台使用SIRF GPS
1.底层驱动的实现
GPS厂商提供的库通过echo sysfs的方式控制gps的onoff和reset,这需要linux实现GPS的sysfs模型驱动,在driver文件夹中增加gps.c文件
(1)填充一个bin_attribute的结构体,驱动加载后就会在系统的/sys/module目录下创建sirf文件 static struct bin_attribute sirf_mode_attr = {

.attr = {

.name = "sirf",

.owner = THIS_MODULE,

.mode = S_IRUGO | S_IWUGO,

},

.size = 0,

.read = readcmd,

.write = writecmd,

};

(2)probe函数
static int __init gps_probe(struct platform_device *pdev)

{

int ret;

ret = sysfs_create_bin_file(&(module_kset->kobj), &sirf_mode_attr);

if (ret) {

printk(KERN_ERR "<SiRF> Failed to create sys file\n");

return -ENOMEM;

}

return 0;

}

(3)remove函数

static int __init gps_remove(struct platform_device *pdev)

{

sysfs_remove_bin_file(&(module_kset->kobj), &sirf_mode_attr);



return 0;

}

(4)平台驱动的注册

static struct platform_driver gps_driver = {

.probe = gps_probe,

.remove = gps_remove,

.driver = {

.name = "gps",

},

};



static int __init gps_init(void)

{

return platform_driver_register(&gps_driver);

}



static void __exit gps_exit(void)

{

platform_driver_unregister(&gps_driver);

}



late_initcall(gps_init);

module_exit(gps_exit);

(5)write和read函数(read暂时为空,没有用到)

static ssize_t readcmd(struct kobject *kobj,

struct bin_attribute *attr,

char *buf, loff_t off, size_t count)

{

}



static ssize_t writecmd(struct kobject *kobj,

struct bin_attribute *attr,

char *buf, loff_t off, size_t count)

{

char *tail;

int op;

op = simple_strtol(buf, &tail, 10);

switch(op) {

case 1:

case 2:

break;

case 3:

printk(KERN_BUG "<SiRF> Chip running...\n");

set_power_on();

run_mode = RUN_MODE;

break;

case 4:

printk(KERN_BUG "<SiRF> Chip stopped...\n");

set_power_off();

run_mode = STOP_MODE;

break;

case 5:

printk(KERN_BUG "<SiRF> Chip reset on high...\n");

set_reset(1);

break;

case 6:

printk(KERN_BUG "<SiRF> Chip reset on low...\n");

set_reset(0);

break;

default:

printk(KERN_BUG "<SiRF> Unknown operation %d\n", op);

break;

}

return count;

}

现在通过echo number > /sys/module/sirf就能控制GPS的power on/off和reset。




FrankBIBI 2011-12-02
  • 打赏
  • 举报
回复
GPS软件跑不动,具体描述下哦。
1,确保GPS数据采集到了,看串口
2,framework正确的开启location GPS服务
3,写个测试程序测试下
xqhrs232 2011-12-02
  • 打赏
  • 举报
回复
Android Gps

http://blog.chinaunix.net/link.php?url=http://xxw8393.blog.163.com%2Fblog%2Fstatic%2F3725683420107424543609%2F




几个主要的文件及目录:

frameworks/base/location/* (client部分)

frameworks/base/core/jni/android_location_GpsLocationProvider.cpp (JNI 部分)

frameworks/base/services/java/com/android/serverLocationManagerService.java(server 部分)

hardware/libhardware_legacy/gps/* (hardware 接口部分)





一是:控制通道,也就是由app层发起的比如enable或disable的控制命令。

example代码调用LocationManager.java ,再通过IPC来实现真正的调用。LocationManager.java 主要负责通信。具体的实现在LocationManagerService.java中。

接口文件是ILocationManager.aidl。在service中根据provider来创建了一个GpsLocationProvider.java,并通过JNI调 android_location_GpsLocationProvider.cpp,该文件再通过GPSInterface来调用硬件的具体实现代码。

二是: enable后的Location数据和状态上报。对于数据的上报过程,主要就是关注几个callback函数。主要代码分析如下:

在 GpsLocationProvider.java文件中enable()一个GpsLocationProvider时,会启动一个 GpsEventThread,该线程主要就是调用了native_wait_for_event();通过JNI调用到了 anroid_location_GpsLocationProvider.cpp中的 android_location_GpsLocationProvider_wait_for_event();而该event的触发是由来自硬件驱动 Location数据包的上报,底层的硬件驱动程序会把raw gps data通过pipe或其他的方式,送出来,这个要看gps驱动的实现了,我们通过自己实现的GpsInterface 来解析raw gps data并调用loaction_callback()来触发event并copy Location数据,等待到event后再调用GpsLocationProvider.java中的reportLocation()上报Location.



除了框架代码外,我们自己需要实现的代码也分为两块,一个是app层的代码,app层我也提供一个简单的代码例子,请参考以下代码:

public class LocationSample extends Activity implements LocationListener {



private LocationManager lm;



public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);



lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);



lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,1l,1l,this);

}



public void onLocationChanged(Location location) {

// TODO Auto-generated method stub

Log.d(TAG,"location: ");

}



public void onProviderDisabled(String provider) {

// TODO Auto-generated method stub

Log.d(TAG,"provider disable");

}



public void onProviderEnabled(String provider) {

// TODO Auto-generated method stub

Log.d(TAG,"provider enable");

}

public void onStatusChanged(String provider, int status, Bundle extras) {

// TODO Auto-generated method stub

Log.d(TAG,"status changed");

}

}

另外一部分就是hardware/libhardware_legacy/gps 部分的实现,这个主要就是实现一个gps.h里面的几个数据结构:

typedef struct {

gps_location_callback location_cb;

gps_status_callback status_cb;

gps_sv_status_callback sv_status_cb;

} GpsCallbacks;



typedef struct {

int (*init)( GpsCallbacks* callbacks );

int (*start)( void );

int (*stop)( void );

void (*set_fix_frequency)( int frequency );

void (*cleanup)( void );

int (*inject_time)(GpsUtcTime time, int64_t timeReference,

int uncertainty);

void (*delete_aiding_data)(GpsAidingData flags);

int (*set_position_mode)(GpsPositionMode mode, int fix_frequency);

const void* (*get_extension)(const char* name);

} GpsInterface;



typedef struct {

uint16_t flags;

double latitude;

double longitude;

double altitude;

float speed;

float bearing;

float accuracy;

GpsUtcTime timestamp;

} GpsLocation;

在GpsInterface->init()的时候要把上层的GpsCallbacks传进来,然后start后,从驱动那里poll获得gps raw data,并对raw data进行解析并填充GpsLocation数据结构,然后调用location_cb 上报location 数据。



//初始化的时候,得到GpsInterface,调用init,



static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)

{

if (!sGpsInterface)

sGpsInterface = gps_get_interface();

return (sGpsInterface && sGpsInterface->init(&sGpsCallbacks) == 0);

}





GpsCallbacks sGpsCallbacks = {

location_callback,

status_callback,

sv_status_callback,

};



//并且打开串口,注册sGpsCallbacks

qemu_gps_init(GpsCallbacks* callbacks)

----> GpsState* s = _gps_state;

----> gps_state_init(s);

----> s->callbacks = *callbacks;



//打开串口,创建线程

gps_state_init( GpsState* state )

-----> state->fd = qemu_channel_open_gps

-----> pthread_create( &state->thread, NULL, gps_state_thread, state )



static void location_callback(GpsLocation* location)

{

pthread_mutex_lock(&sEventMutex);



sPendingCallbacks |= kLocation;

memcpy(&sGpsLocation, location, sizeof(sGpsLocation));



pthread_cond_signal(&sEventCond); //同步西面的函数

pthread_mutex_unlock(&sEventMutex);

}





//下面这个函数就是由上层的 java调用的,并且等待底层的硬件发送数据,其中由EventCond同步

static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, jobject obj)

{

pthread_mutex_lock(&sEventMutex);

pthread_cond_wait(&sEventCond, &sEventMutex);



// copy and clear the callback flags

int pendingCallbacks = sPendingCallbacks;

sPendingCallbacks = 0;



// copy everything and unlock the mutex before calling into Java code to avoid the possibility

// of timeouts in the GPS engine.

memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy));

memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy));

memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy));

pthread_mutex_unlock(&sEventMutex);



if (pendingCallbacks & kLocation) {

env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags,

(jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude,

(jdouble)sGpsLocationCopy.altitude,

(jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing,

(jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp);

}

if (pendingCallbacks & kStatus) {

env->CallVoidMethod(obj, method_reportStatus, sGpsStatusCopy.status);

}

if (pendingCallbacks & kSvStatus) {

env->CallVoidMethod(obj, method_reportSvStatus);

}

if (pendingCallbacks & kXtraDownloadRequest) {

env->CallVoidMethod(obj, method_xtraDownloadRequest);

}

if (pendingCallbacks & kDisableRequest) {

// don't need to do anything - we are just poking so wait_for_event will return.

}

}



//hardware 那部分有个线程gps_state_thread 一直在读串口的内容并进行解析,最后解析到location的信息

由cpp文件的GpsCallbacks sGpsCallbacks = { location_callback....}同步上层的线程



gps_state_thread

----->nmea_reader_addc

----->nmea_reader_parse

------> location_callback

------->数据上报


FrankBIBI 2011-12-02
  • 打赏
  • 举报
回复
恩 恭喜!嘿嘿ie
xqhrs232 2011-12-02
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 lightsoure 的回复:]
2.3与2.2差不多,但是区别也有点大。你现在停再哪?
追下代码 应该可以pass 的
[/Quote]
我的导航软件总算可以跑起来了,下一步就看能不能收星什么的!
FrankBIBI 2011-12-02
  • 打赏
  • 举报
回复
2.3与2.2差不多,但是区别也有点大。你现在停再哪?
追下代码 应该可以pass 的
FrankBIBI 2011-12-02
  • 打赏
  • 举报
回复
我是2.3的
xqhrs232 2011-12-02
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 lightsoure 的回复:]
呃。。。。LOCATION开启是读数据库中没有写入GPS。默认servicemanage系统起来的时候就会自动开启GPS这个服务,然后查看是否写入“数据库中没有写入GPS”标志。然后去初始化GPS接口。

恩 查下接口,我当时是framework中有个listern有问题,也没开启,
framework GPS部分还是有一点BUG需要修改的
[/Quote]

你的Android是那个版本?我的是2.3,2.2的整个框架已经有了几乎不需要调试,但2.3框架还没搭好,估计还要自己去完善这个框架!
xqhrs232 2011-12-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qthsrs232 的回复:]
Android之GPS研究(实战篇二)
http://blog.chinaunix.net/space.php?uid=25369701&do=blog&id=125329
[/Quote]




TI平台使用SIRF GPS

2.Android HAL的实现
(1)制作libgps.so库
google提供的方法
http://source.android.com/porting/gps.html

Android.mk:
LOCAL_SRC_FILES:= main.c //指定库的源码
LOCAL_MODULE := libgps //指定库的名称
include $(BUILD_SHARED_LIBRARY) //指定编译成.so库

(2)修改BoardConfig.mk
添加BOARD_GPS_LIBRARIES := libgps

由于hardware/libhardware_legacy/gps/Android.mk中指定LOCAL_SHARED_LIBRARIES
ifneq ($(BOARD_GPS_LIBRARIES),)
LOCAL_CFLAGS += -DHAVE_GPS_HARDWARE
LOCAL_SHARED_LIBRARIES += $(BOARD_GPS_LIBRARIES)
endif

(3)修改hardware/libhardware_legacy/gps/gps.cpp
static void

gps_find_hardware( void )

{

sGpsInterface = gps_get_hardware_interface();

if (!sGpsInterface)

LOGD("no GPS hardware on this device\n");

}

gps_get_hardware_interface()在libgps.so源码中实现

(4)实现libgps.so源码main.c
(可参考hardware/libhardware_legacy/gps/gps_qemu.c)

static const GpsInterface sirfGpsInterface = {

sirf_gps_init,

sirf_gps_start,

sirf_gps_stop,

sirf_gps_cleanup,

sirf_gps_inject_time,

sirf_gps_inject_location,

sirf_gps_delete_aiding_data,

sirf_gps_set_position_mode,

sirf_gps_get_extension,

};

const GpsInterface* gps_get_hardware_interface()

{

return &sirfGpsInterface;

}

下面将介绍下需要修改的函数,其他函数都可以仿照gps_qemu.c

sirf_gps_start()函数中添加SiRF_Start();

sirf_gps_stop()函数中添加SiRF_Stop();

sirf_gps_init()函数中调用gps_state_init,作用是创建socket通信和gps_state_thread线程;

gps_state_init()函数中需要根据具体的GPS模块实现state->fd = channel_open();

gps_state_thread()函数中去掉两句nmea_reader_set_callback调用;

nmea_reader_parse()函数添加callbacks.nmea_cb和callbacks.location_cb:

if (r->pos < 9) {

D("Too short. discarded.");

return;

}

{

struct timeval tv;

gettimeofday(&tv, NULL);

_gps_state->callbacks.nmea_cb(tv.tv_sec*1000+tv.tv_usec/1000, r->in, r->pos);

}

nmea_tokenizer_init(tzer, r->in, r->in + r->pos);
if (_gps_state->callbacks.location_cb) {

_gps_state->callbacks.location_cb( &r->fix );

r->fix.flags = 0;

}

else {

D("no callback, keeping data until needed !");

}

(5)NMEA数据上报

Android本身的GPS读取NMEA信息机制是调用read函数读取串口信息并解析上报,但SIRF提供了SiRF_Output函数用于底层与应用层的数据上报,GPS工作后会有线程不停调用SiRF_Output,因此只要在SiRF_Output函数中添加:

NmeaReader reader[1];

nmea_reader_init( reader );



for (nn = 0; nn < sizeof(buf); nn++)

nmea_reader_addc( reader, buf[nn] );

现在GPS可以上报GGA、GSA、RMC等数据(GSA数据需添加nmea_reader_parse函数中关于GSA数据解析)



后面还会继续研究GSA等数据的解析上报...期待o ^-^



xqhrs232 2011-12-01
  • 打赏
  • 举报
回复
Android GPS架构分析(五)
http://www.eoeandroid.com/thread-71032-1-1.html
qthsrs232 2011-12-01
  • 打赏
  • 举报
回复
qthsrs232 2011-12-01
  • 打赏
  • 举报
回复
GPS在Android的使用经验

http://itstarting.iteye.com/blog/1233166



GPS的开发、使用,有两个关键点:

1. 选择并激活合适的Provider;

2. 建立合理刷新机制。



下面是通用的方法,以“选择并激活合适的Provider”:



Java代码
protected void getAndTraceLocation(){
//geocoder = new Geocoder(this, Locale.getDefault());;
geocoder = new Geocoder(this, Locale.ENGLISH);;
// Acquire a reference to the system Location Manager
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);

String provider = locationManager.getBestProvider(criteria, true);
if(provider!=null){
Log.i(TAG, "GPS provider is enabled:" + provider.toString());
// Get the location
latestLocation = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(latestLocation);

// Register the listener with the Location Manager to receive location
locationManager.requestLocationUpdates(provider, 1000, 5, locationListener);
}else{
Log.i(TAG, "No GPS provider found!");
updateWithNewLocation(null);
}
}

protected void getAndTraceLocation(){
//geocoder = new Geocoder(this, Locale.getDefault());;
geocoder = new Geocoder(this, Locale.ENGLISH);;
// Acquire a reference to the system Location Manager
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);

String provider = locationManager.getBestProvider(criteria, true);
if(provider!=null){
Log.i(TAG, "GPS provider is enabled:" + provider.toString());
// Get the location
latestLocation = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(latestLocation);

// Register the listener with the Location Manager to receive location
locationManager.requestLocationUpdates(provider, 1000, 5, locationListener);
}else{
Log.i(TAG, "No GPS provider found!");
updateWithNewLocation(null);
}
}Java代码
protected final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.i(TAG, "location changed to: " + location);
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};

protected final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.i(TAG, "location changed to: " + location);
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};

需要注意的是:

这里的locationManager.getBestProvider(criteria, true) 之后,必须进行是否为null的判断,否则在终端禁用GPS和网络以后会出现NPE异常。



注意这里回调了一个通用的updateWithNewLocation(latestLocation)方法,用户只要实现这个方法,即可实现第二个关键点,即“建立合理刷新机制”。



下面是最简单的例子:



Java代码
@Override
protected void updateWithNewLocation(Location location) {
super.updateWithNewLocation(location);

String location_msg = context.getString(R.string.msg_no_gps);
if (location != null) {
location_msg = location.getLatitude() + "," + location.getLongitude();
Log.i(TAG, location_msg);
} else {
Log.i(TAG, location_msg);
}

location_msg = String.format(_location_msg, location_msg);
_location.setText(location_msg);
}

@Override
protected void updateWithNewLocation(Location location) {
super.updateWithNewLocation(location);

String location_msg = context.getString(R.string.msg_no_gps);
if (location != null) {
location_msg = location.getLatitude() + "," + location.getLongitude();
Log.i(TAG, location_msg);
} else {
Log.i(TAG, location_msg);
}

location_msg = String.format(_location_msg, location_msg);
_location.setText(location_msg);
}
完毕!





xqhrs232 2011-12-01
  • 打赏
  • 举报
回复
xqhrs232 2011-12-01
  • 打赏
  • 举报
回复
听说有一个什么回调机制没有实现

public void requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener, Looper looper) Since: API Level 1
Registers the current activity to be notified periodically by the named provider. Periodically, the supplied LocationListener will be called with the current Location or with status updates.

It may take a while to receive the most recent location. If an immediate location is required, applications may use the getLastKnownLocation(String) method.

In case the provider is disabled by the user, updates will stop, and the onProviderDisabled(String) method will be called. As soon as the provider is enabled again, the onProviderEnabled(String) method will be called and location updates will start again.

The frequency of notification may be controlled using the minTime and minDistance parameters. If minTime is greater than 0, the LocationManager could potentially rest for minTime milliseconds between location updates to conserve power. If minDistance is greater than 0, a location will only be broadcasted if the device moves by minDistance meters. To obtain notifications as frequently as possible, set both parameters to 0.

Background services should be careful about setting a sufficiently high minTime so that the device doesn't consume too much power by keeping the GPS or wireless radios on all the time. In particular, values under 60000ms are not recommended.

The supplied Looper is used to implement the callback mechanism.

Parameters
provider the name of the provider with which to register
minTime the minimum time interval for notifications, in milliseconds. This field is only used as a hint to conserve power, and actual time between location updates may be greater or lesser than this value.
minDistance the minimum distance interval for notifications, in meters
listener a {#link LocationListener} whose onLocationChanged(Location) method will be called for each location update
looper a Looper object whose message queue will be used to implement the callback mechanism. If looper is null then the callbacks will be called on the main thread.

Throws
IllegalArgumentException if provider is null or doesn't exist
IllegalArgumentException if listener is null
SecurityException if no suitable permission is present for the provider.




加载更多回复(1)

80,471

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧