- 浏览: 538083 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
landerson:
明显就有要求的嘛
ANDROID轻量级JSON序列化和反序列化[转] -
jimode2013:
很不错,就是需要这个方法
多个UIViewController使用addSubView,第二个 UIViewController 不响应旋转[转] -
w11h22j33:
...
[转]NSMutableArray中的自动释放对象让我郁闷了一整天 -
w11h22j33:
UILabel* label = [[UILabel a ...
Iphone开发 -
w11h22j33:
http://mobile.51cto.com/iphone- ...
获得通讯录中联系人的所有属性[转]
手机应用中最酷的可能就是位置服务相关的了,如何读取GPS信息,在官方文档上有相当详细的说明,后面如果有机会,我也会专门写例子来介绍(教程已完成,请参见:教程:实现Android的不同精度的定位(基于网络和GPS))。但今天,我们先来看下如何以编程的方式来开启或关闭GPS。
官方的API中,android.provider.Settings.Secure类有2个静态方法:
public static final void setLocationProviderEnabled (ContentResolver cr, String provider, boolean enabled)
和
public static final boolean isLocationProviderEnabled (ContentResolver cr, String provider)
不过遗憾的是,这2个方法都注明了从API Level 8(即Android 2.2)才开始提供,那么在2.2之前又该如何编程实现GPS的开关呢?
山重水复疑无路
首先,我们要知道,Android系统的设置画面中就可以进行GPS的开关,那么它是如何实现的呢?
由于我的机器上的android source是2.3版本的,所以直接启动了一个2.1的模拟器,用adb pull将Settings.apk抓下来,反编译之后,在SecuritySettings类中找到如下代码:
package,com.android.settings.SecuritySettings.java
1 2 3 4 5 6 7 8 |
CheckBoxPreference localCheckBoxPreference3 = this.mGps; if (paramPreference == localCheckBoxPreference3) { ContentResolver localContentResolver3 = getContentResolver(); boolean bool6 = this.mGps.isChecked(); Settings.Secure.setLocationProviderEnabled(localContentResolver3, "gps", bool6); continue; } |
可以看到2.1系统中已经存在有Settings.Secure.setLocationProviderEnabled方法了,只是该方法没有开放而已,事实上读过Android源码的人都对/*hide*/很反感吧,看得到,摸不到!
既然Setting画面中的用法,我们不能使用,那么再换1种方法,我们去看一下Settings.Secure.setLocationProviderEnabled的写法,然后直接套用。
这次,我们直接去看Android 2.3的源码,找到Setting.java之后,找到相关的方法,代码如下:
core, android.provider.Setting.java
1 2 3 4 5 6 7 8 9 10 11 12 |
public static final void setLocationProviderEnabled(ContentResolver cr, String provider, boolean enabled) { // to ensure thread safety, we write the provider name with a '+' or '-' // and let the SettingsProvider handle it rather than reading and modifying // the list of enabled providers. if (enabled) { provider = "+" + provider; } else { provider = "-" + provider; } putString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider); } |
原来这个方法只是1个包装,事实上调用的还是Settings.Secure中的putString方法,我们直接借用过来:
在自己的onClick事件中写上
Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, “network,gps”);
然后执行,WOW,发生了什么,需要android.permission.WRITE_SETTINGS权限?在Manifest文件中加上,再运行,还是出错,不过这次需要的是android.permission.WRITE_SECURE_SETTINGS,再次加上。
满怀希望的再次运行,结果还是一样的问题:
java.lang.SecurityException: Permission denial: writing to secure settings requires android.permission.WRITE_SECURE_SETTINGS
看来,Google封死了直接调用Settings的路了,事实上我又试着使用反射来直接调用setLocationProviderEnabled方法,结果也是一样的告诉我需要权限。
柳暗花明又一村
难道没有别的办法了吗?那些2.1中可以运行的App Widget是如何做到的呢?
再次检视2.1的Settings.apk中的代码,发现有1个widget包,里面有1个类叫SettingsAppWidgetProvider,这就是用来提供App Widget的类,继续研究这里的代码,发现构造RemoteView的代码中用到如下方法:
1 2 3 4 5 6 7 8 9 |
private static PendingIntent getLaunchPendingIntent(Context paramContext, int paramInt1, int paramInt2) { Intent localIntent1 = new Intent(); Intent localIntent2 = localIntent1.setClass(paramContext, SettingsAppWidgetProvider.class); Intent localIntent3 = localIntent1.addCategory("android.intent.category.ALTERNATIVE"); Uri localUri = Uri.parse("custom:" + paramInt2); Intent localIntent4 = localIntent1.setData(localUri); return PendingIntent.getBroadcast(paramContext, 0, localIntent1, 0); } |
由于这是反编译的结果,略微有点混乱,但还是可以看出思路,目的是通过PendingIntent来扔出1个Intent,接受者是SettingsAppWidgetProvider.class,接受的参数有2个,1个是Category:SettingsAppWidgetProvider.class(正是这个类自身),另1个是Data:Uri.parse(“custom:” + paramInt2),这个paramInt2是Widget中的图标按钮的序号。所有的序号在类的首部都有定义:
1 2 3 4 5 |
private static final int BUTTON_BLUETOOTH = 4; private static final int BUTTON_BRIGHTNESS = 1; private static final int BUTTON_GPS = 3; private static final int BUTTON_SYNC = 2; private static final int BUTTON_WIFI = 0; |
那么我们只要送出custom:3的Uri给SettingsAppWidgetProvider.class,就应该可以由SettingsAppWidgetProvider类来帮我们调用Settings.Secure.setLocationProviderEnabled方法了。
说到做到,在Activity中添加如下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
private void toggleGPS() { Intent gpsIntent = new Intent(); gpsIntent.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); gpsIntent.addCategory("android.intent.category.ALTERNATIVE"); gpsIntent.setData(Uri.parse("custom:3")); try { PendingIntent.getBroadcast(this, 0, gpsIntent, 0).send(); } catch (CanceledException e) { e.printStackTrace(); } } |
这个方法是1个纯开关,如果当前是开启的,那么就会关闭它,反之亦然。
检查GPS开关状态
那么,如何查看当前的GPS开关状态呢?可以用上面提到的反射方式调用isLocationProviderEnabled,代码片断如下:
1 2 3 4 5 |
secureClass = cl.loadClass("android.provider.Settings$Secure"); isMethod = secureClass.getMethod("isLocationProviderEnabled", ContentResolver.class, String.class); Boolean ret = (Boolean) isMethod.invoke(secureClass, this .getContentResolver(), "gps"); |
也可以直接用下面的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
private void isGPSEnable() { /* 用Setting.System来读取也可以,只是这是更旧的用法 String str = Settings.System.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); */ String str = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); Log.v("GPS", str); if (str != null) { return str.contains("gps"); } else{ return false; } } |
这2种方法的原理都是一样的,方法2其实也就是isLocationProviderEnabled实际调用的代码,只是Google未对读取操作进行权限限制。
总结
如果目标手机是运行Android 2.2的话,那么最好还是使用2.2开放的Settings.Secure类中的2个方法来操作。但如果目标手机运行的版本是2.1或以下的话,那么就只能使用变通的方法来实现了。这1方法在Android官方的Wiki上已经有人提出了,详情请见:Issue 7890。但可能是2.1版本已经古旧不再维护的原因,官方并未进行任何的Fix。
发表评论
-
干掉你程序中的僵尸代码【转】
2012-12-22 11:05 967随着万圣节越来越流行,我感觉有必要跟大家讨论一下一个 ... -
一个文本框搞定信用卡相关信息的输入[转]
2012-12-22 11:03 1141http://beforweb.com/node/134 ... -
android 开源 OCR 项目 及手写识别[转]
2012-12-11 18:21 57721)一个为Android平台,将识别由手机的相机拍摄的图 ... -
Android通过共享用户ID来实现多Activity进程共享【转】
2012-12-10 14:33 1111http://mypyg.iteye.com/blog/720 ... -
Android应用程序组件Content Provider的启动过程源代码分析【转】
2012-12-05 18:31 1149通过前面的学习,我们知道在Android系统中,Cont ... -
理解android上的安全性【转】
2012-12-03 18:08 919开发 Android 应用程序时,必须处理很多与安全性相关的方 ... -
Android 安全机制概述 Permission【转】
2012-12-03 18:07 11761 Android 安全机制概述 Android 是一个权限分 ... -
Android学习笔记之一谁动了我的接口附checkPermission流程(Dean)[转]
2012-12-03 18:06 18127前段时间接到一个有趣的需求!我们实现的某某功能的手机对外提供了 ... -
(JAVA) 使用异或进行简单的密码加密(JAVA实现)[转]
2012-11-12 16:44 1220http://blog.sina.com.cn/s/bl ... -
SL4A 之实现原理解析【转】
2012-10-23 23:52 1286关于SL4A的简介和在Android系统的安装及使用,请参 ... -
百度地图API之根据经纬度查询地址信息(Android)[转]
2012-06-16 00:15 19804http://blog.csdn.net/lyq8479/ar ... -
百度地图的手动定位和自动定位[转]
2012-06-15 23:24 3459http://aokunsang.iteye.com/b ... -
Android软键盘的隐藏显示研究[转]
2012-05-25 16:30 1445Android是一个针对触摸屏专门设计的操作系统,当点 ... -
15 个变量和方法命名的最佳实践[转]
2012-02-27 11:44 103215 个变量和方法命名的最佳实践 在每个代码范围内使用足够短 ... -
iPhone Android Web开发(概要)
2012-01-19 15:15 1071一、 前端使用技术 JavaScript、 jQuer ... -
移动 电信 联通 APN cmwap cmnet ctwap ctnet 3gwap uniwap 3gnet uninet设置[转]
2011-11-23 14:35 2781APN(Access Point Name),即“接入 ... -
Android Http CMWAP联网获取实例【转】
2011-10-24 13:24 1403上午的时候原本想通过改变切入点的方式来实现cmwap,但是我们 ... -
监听ListView滚动到最底部【转】
2011-09-13 10:27 5885监听ListView的滚动可以用两个东西: ListV ... -
Android蓝牙开发浅谈【转】
2011-09-07 14:20 1576转自:http://www.eoeandroid.co ... -
修改Android模拟器的HOST
2011-06-03 11:08 4224C:\WINDOWS\system32\drivers ...
相关推荐
这包括打开、读取、关闭文件。例如,你可能需要读取包含GPS数据的日志文件,然后将这些数据存储到结构或类中。 3. **字符串处理**:NMEA数据通常是ASCII字符串,需要使用字符串函数进行处理,如`std::getline()`来...
在本文中,我们将深入探讨如何使用VC++编程来实现GPS数据的串口接收。串口通信是计算机与外部设备之间进行数据交换的一种常见方法,尤其在GPS设备等嵌入式系统中广泛使用。通过串口,我们可以从GPS接收器获取定位、...
本文将深入探讨如何通过串口编程来读取GPS(全球定位系统)的信息。首先,我们来理解串口通信的基本概念,然后详细介绍GPS数据格式,最后通过分析提供的代码文件来学习如何实现这个过程。 串口通信,也称为UART...
6. **事件处理**:处理用户触发的开启、关闭GPS,以及获取位置信息的请求。 7. **异步处理**:考虑到GPS定位可能需要一段时间,源代码可能会使用线程或者AsyncTask来避免阻塞主线程。 在实际运行这个项目时,你需要...
### Java实现GPS全球定位系统定位数据的提取 #### 引言 全球定位系统(Global Positioning System,简称GPS)是一种重要的导航技术,广泛应用于车辆跟踪、个人定位、地图绘制等领域。GPS系统主要由三大部分组成:...
Android监听手机GPS打开状态实现代码是指在Android应用程序中,通过编程的方式检测用户的手机是否已经打开了GPS功能,以便对应用程序的行为进行相应的调整。在Android系统中,GPS状态的改变会通过广播机制通知其他...
在本文档中,我们探讨了如何使用VC++6.0编程来实现GPS数据的串口接收。这个过程涉及创建一个基于对话框的工程,并通过串口通信与GPS设备交互。以下是一些关键知识点: 1. **创建工程和界面设计**: - 首先,我们...
本示例“GPS打开及获取数据 demo”是一个实用的编程演示,它展示了如何在Android平台上开启GPS服务并获取实时的位置数据。由于涉及到系统级别的权限,所以这个demo需要申请并使用到system权限。 首先,我们要理解...
在Android系统中,飞行模式(Airplane Mode)是一种特殊的设备设置,它允许用户快速禁用所有无线通信功能,包括蜂窝数据、Wi-Fi、蓝牙和GPS等,以便在飞机上或要求关闭无线设备的地方使用。从Android 4.2版本开始,...
在电池供电的设备中,STM32可以通过控制GPIO来开启或关闭GPS模块,实现节能。同时,GPS模块通常有省电模式,比如PWR_ON和PWR_OFF状态,可以根据应用需求调整。 5. **定位精度优化** 为了提高定位精度,可以使用...
在Android平台上,GPS轨迹记录器通常允许用户开启或关闭GPS服务,设置记录间隔,保存轨迹点,并可能提供地图视图来显示行进路线。 GPS技术的核心是通过接收卫星信号来确定地理位置。在Android设备上,GPS轨迹记录器...
5. **串口编程**:这是在程序中控制串口设备的技术,包括打开、关闭串口,设置通信参数,以及读写数据。在C++或.NET框架中,这通常通过`CreateFile`、`SetCommState`、`ReadFile`和`WriteFile`等API函数实现。 6. *...
这个压缩包可能包含一个或多个源代码文件,用于演示或实现如何在.NET平台上操作GPS功能。让我们深入探讨一下这个主题。 GPS(Global Positioning System)是一种全球导航卫星系统,它通过接收来自多颗卫星的信号来...
- 打开/关闭串口:调用`Open`方法打开串口,`Close`方法关闭串口。 - 读取数据:使用`ReadFile`或`Read`方法读取串口接收到的数据。 - 写入数据:通过`WriteFile`或`Write`方法向串口发送命令或数据。 - 错误...
3. **编程实现**: 在提供的文件列表中,有三个C源文件:`gps.c`、`rs232.c`和`ttytest.c`,它们很可能包含了实现串口通信和解析GPS数据的代码。`gps.c`可能是主程序,负责初始化串口,设置波特率、校验位等,并...
6. **UI设计**:用户界面元素,如按钮用于开启/关闭GPS,显示当前位置,或者开始/结束轨迹记录。 在开发这样的应用时,开发者还需要考虑电池效率和用户体验,例如通过设置合适的定位间隔和精度来平衡定位准确性和...
然而,由于隐私和安全原因,通常不建议或不允许应用程序直接控制硬件层面的GPS开启。因此,描述中提到的是通过跳转到系统设置页面让用户手动开启GPS,而非通过代码直接操作。在用户开启GPS后,应用可以通过GPS服务来...
综上所述,PDA与GPS的数据通信技术涉及硬件选型、串口通信协议、数据解析等多个方面,其核心是通过编程实现PDA与GPS设备间的高效、稳定通信,从而为野外作业提供实时、准确的位置信息。这一技术对于地质勘探、测绘、...
在VB2010中,可以使用`Microsoft.VisualBasic.Devices.SerialPort`类来进行串口操作,包括打开、关闭、读取和写入数据。 2. **GPS协议**:GPS模块通常遵循NMEA(National Marine Electronics Association)协议发送...
因此,编写高效、节能的GPS代码是至关重要的,可能需要采用周期性开启/关闭GPS、智能预测定位需求等方式降低功耗。 总的来说,GPS收发程序设计涵盖硬件接口编程、协议解析、定位算法理解和应用集成等多个方面。掌握...