- 浏览: 114565 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
liubang201010:
可看看此文:http://www.goodu.info/gc/ ...
基于Android手机开发平台的移动数字图书馆服务系统研究 -
chenhaodejia:
hbxflihua 写道你好,在加载xml的时候能不能像htm ...
android自定义Spinner下拉菜单样式并获得选项的值 -
chenhaodejia:
心灵花园2010 写道你好,问下服务端该怎么去搭建?
什么意思 ...
基于Android手机开发平台的移动数字图书馆服务系统研究 -
心灵花园2010:
你好,问下服务端该怎么去搭建?
基于Android手机开发平台的移动数字图书馆服务系统研究 -
hbxflihua:
你好,在加载xml的时候能不能像html页面的select标签 ...
android自定义Spinner下拉菜单样式并获得选项的值
在本教程中,我们将创建一个叫做PhoneFinder的应用。本应用将演示如何发送和接收短信。当你的手机丢了或者被偷,你可以使用别人的手机,接收你手机所处位置的GPS坐标,从而找到你的手机,这正是本应用的创意来源。本应用需要一个Activity让用户输入密码,还需要一个IntentReceiver来过滤接收到的短信。
译者注:本文完全按照原文翻译,如果说明文字中的代码行号和实际显示的代码行号有出入,请按代码执行的功能理解
密码输入
如下所示,我们使用一个简单的对话框来帮助用户输入密码。一旦密码被正确输入,我们将把密码的MD5置入应用包的 SharedPreferences中。Preferences是一个存储少量持久数据的好地方,包中的其他类也可以访问Preferences。之所以存储密码的MD5,是因为即使密码被读取,它也不会泄露密码的明文,除非这密码本身非常弱。
上图所示的对话框对应的layout文件,main.xml如下所示:
〈?xml version="1.0" encoding="utf-8"?〉
〈LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
androidrientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
〉
〈TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/password_label"
/〉
〈EditText id="@+id/password"
android:maxLines="1"
android:layout_marginTop="2dip"
android:layout_width="wrap_content"
android:ems="25"
android:layout_height="wrap_content"
android:autoText="true"
android:scrollHorizontally="true"
android:password="true" /〉
〈TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/password_confirm_label"
/〉
〈EditText id="@+id/password_confirm"
android:maxLines="1"
android:layout_marginTop="2dip"
android:layout_width="wrap_content"
android:ems="25"
android:layout_height="wrap_content"
android:autoText="true"
android:scrollHorizontally="true"
android:password="true" /〉
〈Button id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="@string/button_ok" /〉
〈TextView id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/〉
〈/LinearLayout〉
如你所见,这是一个相当简单的Layout,2个TextView,2个输入框,1个button,另外还有一个TextView用来显示提示信息。Layout中所涉及到的字符串在strings.xml中定义,以便提供更好的国际化支持。
这个Activity对应的代码也是简单的。它所完成的任务就是确保输入的密码在6个字符以上并且密码的2次输入必须匹配。一旦所有条件满足,我们所要做的就是把用户输入的密码所对应的MD5保存在应用的SharedPreferences里。PhoneFinder Activity的代码如下所示:
public class PhoneFinder extends Activity {
public static final String PASSWORD_PREF_KEY = "passwd";
private TextView messages;
private EditText pass1;
private EditText pass2;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
messages = (TextView) findViewById(R.id.text1);
pass1 = (EditText) findViewById(R.id.password);
pass2 = (EditText) findViewById(R.id.password_confirm);
Button button = (Button) findViewById(R.id.ok);
button.setOnClickListener(clickListener);
}
private OnClickListener clickListener = new OnClickListener() {
public void onClick(View v) {
String p1 = pass1.getText().toString();
String p2 = pass2.getText().toString();
if (p1.equals(p2)) {
if (p1.length() 〉= 6 || p2.length() 〉= 6) {
Editor passwdfile = getSharedPreferences(PhoneFinder.PASSWORD_PREF_KEY, 0).edit();
String md5hash = getMd5Hash(p1);
passwdfile.putString(PhoneFinder.PASSWORD_PREF_KEY,
md5hash);
passwdfile.commit();
messages.setText("assword updated!");
} else
messages.setText("asswords must be at least 6 characters");
} else {
pass1.setText("");
pass2.setText("");
messages.setText("asswords do not match");
}
}
};
}
在onCreate()方法中,我们初始化了将要在layout中使用的各种View,然后,我们创建了ok按钮的OnClickListener对象。当ok按钮被点击,位于第40行的onClick()方法将会被调用。
在 onClick()方法中,我们确保密码的最少长度要求被满足,而且2个输入框中输入的密码字串一致。如果所有的条件满足,我们在第48行创建一个 SharedPreferences.Editor对象,通过该对象,我们可以编辑该应用的shared preferences。之所以把此类 preferences称为“共享”(shared),因为它是一个应用程序范围内的参数。如果你想把数据的可见性局限在调用的Activity对象内,你可以使用Activity.getPreferences(int),这是Activity级别的数据存储方式。
在第48行,我们调用成员函数getMd5Hash(String),它返回字符串形式的MD5,然后我们把它存储在preferences里面。以下就是getMd5Hash(String)函数:
public static String getMd5Hash(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(input.getBytes());
BigInteger number = new BigInteger(1,messageDigest);
String md5 = number.toString(16);
while (md5.length() 〈 32)
md5 = "0" + md5;
return md5;
} catch(NoSuchAlgorithmException e) {
Log.e("MD5", e.getMessage());
return null;
}
}
我们使用android.security.MessageDigest对象来表达我们想要使用的算法。digest()函数的输入参数为字符串所对应的字节数组,输出参数也是一个字节数组。输出的字节数组可以转化成一个BigInteger对象,进而利用该对象的toString(16)方法转变成16进制的字符串。因为把字节数组转化成一个BigInteger的时候,前端的0会被删掉,所以我们在 MD5字串前面补上足够的0,使它的长度达到32个字符。
处理短消息
现在,用户可以在应用的preferences中保存输入的密码了,接下来,我们将要检查手机接收到的短信,并且对我们感兴趣的短信做出响应。这种短信的格式为:
SMSLOCATE:〈password〉
因此,如果某条短信以“SMSLOCATE:”开头,并且紧跟‘:’字符后面的密码的MD5和我们先前存储的匹配,我们将回复一条包含手机当前位置信息的短信。为了实现这一目的,我们需要建立一个IntentReceiver,响应类型为 “android.provider.Telephony.SMS_RECEIVED”的Action。该IntentReceiver必须在 AndroidManifest.xml 文件中声明,以下是AndroidManifest.xml 文件:
〈?xml version="1.0" encoding="utf-8"?〉
〈manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.helloandroid.android.phonefinder"〉
〈uses-permission id="android.permission.RECEIVE_SMS" /〉
〈application android:icon="@drawable/icon"〉
〈activity class=".PhoneFinder" android:label="@string/app_name"〉
〈intent-filter〉
〈action android:value="android.intent.action.MAIN" /〉
〈category android:value="android.intent.category.LAUNCHER" /〉
〈/intent-filter〉
〈/activity〉
〈receiver class=".FinderReceiver"〉
〈intent-filter〉
〈action android:value="android.provider.Telephony.SMS_RECEIVED" /〉
〈/intent-filter〉
〈/receiver〉
〈/application〉
〈/manifest〉
在第4行,通过〈uses-permission〉标签,我们请求接收短信的权限。在第 13行,我们指定我们的FinderReceiver作为一个receiver,同时声明了intent-filter,以此来过滤被广播的所有 intent。你可以看到,我们只对“android.provider.Telephony.SMS_RECEIVED”这类action感兴趣。
现在,系统知道了对于这类action,该调用何种receiver。接下来我们来创建名为FinderReceiver的IntentReceiver。
public class FinderReceiver extends IntentReceiver {
@Override
public void onReceiveIntent(Context context, Intent intent) {
SharedPreferences passwdfile = context.getSharedPreferences(
PhoneFinder.PASSWORD_PREF_KEY, 0);
String correctMd5 = passwdfile.getString(PhoneFinder.PASSWORD_PREF_KEY,
null);
if (correctMd5 != null) {
SmsMessage[] messages = Telephony.Sms.Intents
.getMessagesFromIntent(intent);
for (SmsMessage msg : messages) {
if (msg.getMessageBody().contains("SMSLOCATE:")) {
String[] tokens = msg.getMessageBody().split(":");
if (tokens.length 〉= 2) {
String md5hash = PhoneFinder.getMd5Hash(tokens[1]);
if (md5hash.equals(correctMd5)) {
String to = msg.getOriginatingAddress();
LocationManager lm =
(LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
SmsManager sm = SmsManager.getDefault();
sm.sendTextMessage(to, null, lm.getCurrentLocation("gps").toString(),
null, null, null);
NotificationManager nm =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notifyWithText(R.layout.main,
context.getText(R.string.notify_text) + " " + msg.getDisplayOriginatingAddress(),
NotificationManager.LENGTH_LONG, null);
}
}
}
}
}
}
}
首先,我们从SharedPreferences取出密码的MD5(18-21行),如果我们取到了,我们就用它来检查我们接收到的所有的短信。
我们使用Telphony.Sms.Intents.getMessageFromInent(intent)来获取SmsMessages数组,我们将遍历该数组,查看每条短信消息体中是否包含“SMSLOCATE:”标记,如果找到符合条件的短消息,我们会获取‘:’字符后的密码,计算其MD5,和手机里存储的MD5进行比较。
如果密码匹配,系统会执行第36行处的代码块。接下来我们将回复该短信,现在我们只需要一个代表短信目的地的字符串,以及代表手机位置信息的字符串。我们创建一个LocationManager,使用其getCurrentLocation("gps").toString()方法来获取位置信息。该信息由GPS位置服务提供者提供。然后,我们使用一个SmsManager对象发送短信。短信发送完毕后,我们还会显示一个通知。
注意:有一个可能更好做法是,在密码输入对话框中加入一个可选项来控制是否显示通知。如果手机被偷,最好把通知隐藏起来,否则小偷会意识到自己被跟踪,从而把手机关掉。
测试
现在,万事俱备。在新版的android SDK中,给模拟器打电话或者发短信都很容易。这些操作都可以通过Eclipse中的模拟器控制面板视图来完成。你可以通过“"Window -> Show View -> Other”,选择android部分的“Emulator Control”项来增加这个视图。 译者注:如果你的android Eclipse插件为ADT0.3.1,请务必升级到ADT0.3.3,升级步骤见http://code.google.com/android/intro/upgrading.html 测试的第一步是激活主Activity,设置密码。例如,我使用“123456”作为密码,接下来,你可以发送一条内容为“SMSLOCATE:123456”的短信,如下图所示:
当你发送完短信后,你会看到一条类似下图的通知。
好了,一切OK。我想,这是一个很好的例子。通过它,你会发现在android平台上开发一个有用的应用是多么的容易。我们通过2个基本的对象就完成了一件非常有用的任务。
注:博客涉及的源码请在千寻资源库:www.qxzyk.com 下载获取,谢谢支持。
发表评论
-
我今天打算推荐一下近期自己制作的一款app-吃惑
2016-07-13 17:12 460你是否有这样的习惯 ... -
android listview优化几种写法详细介绍
2015-02-18 14:58 747这篇文章只是总结下getView里面优化视图的几种写法,就像 ... -
利用convertView优化ListView性能
2015-02-18 14:26 683这里提到的ListView只是作为一个典型代表 其实在A ... -
Android之ListView原理学习与优化总结
2015-02-05 15:50 715在整理前几篇文章的时候有朋友提出写一下ListView的性 ... -
sleep()和wait()有什么区别
2015-02-04 09:38 773sleep就是正在执行的线程主动让出cpu,cp ... -
线程与进程的区别
2015-01-27 20:12 684线程是指进程内的一个执行单元,也是进程内的可调度实体.与进程 ... -
线程同步的几种方式(转)
2015-01-27 19:58 860进程中线程同步的四种常用方式: 1、 临界区(CCrit ... -
Eclipse提示No java virtual machine
2014-12-15 16:22 1008当你启动eclipse时出现... No java v ... -
解决客户端向服务器端传输中文乱码问题
2014-10-24 09:59 953客户端加码 Java code? ... -
重要通告
2012-02-05 11:36 900博客涉及到的所有源码,包括网站源码、Android源码等均在千 ... -
关于Android发送邮件
2011-09-11 08:40 3336Google 在发表 Android 手机平台时,强调的是超强 ... -
ImageButton点击背景切换事件
2011-08-23 14:30 2495问题:imagebutton初始显示图片1,当单击该image ... -
Android中ImageButton的运用详解
2011-08-23 14:13 2298ImageButton在Android的运用非常灵活,既可以在 ... -
Android拍照、录像、录音代码范例
2011-08-19 09:17 1251package com.cons.dcg.collect; i ... -
Android的Menu状态动态设置方法onPrepareOptionsMenu(Menu menu)
2011-08-12 11:49 2042覆盖onPrepareOptionsMenu(Menu men ... -
ArrayAdapter和BaseAdapter的区别是什么
2011-08-11 18:10 2137近期很多Android开发者来函表示对ArrayAdapt ... -
有关代码结构的优化若干
2011-08-11 18:08 1006避免建立对象 世界上没有免费的对象。虽然GC为每个线程都建立 ... -
ArrayAdapter和List的关系
2011-08-11 18:00 21551、使用ArrayAdapter(数组适配器)顾名思义,需要把 ... -
Manifest权限大全
2011-08-09 17:38 1040<uses-permission android:nam ... -
Android中创建自己的ContentProvider
2011-08-09 17:37 1364Android是如何实现应用程序之间数据共享的?我们以 ...
相关推荐
综上所述,这个资源包提供了一个全面的示例,涵盖了Android应用中常见的GPS定位、位置距离计算、短信发送和时间处理功能,对于学习和开发Android应用来说极具参考价值。开发者可以根据自己的需求,参考这些代码实现...
Android系统中GPS定位监护系统的设计是一篇关于基于Android平台的GPS定位监护系统设计的论文。该系统的目的是为了让家长及时获悉儿童所处的位置,防止儿童走失,系统采用GPS模块设计实现了定位跟踪,用于实时汇报...
也有分析认为,谷歌并不想做一个简单的手机终端制造商或者软件平台开发商,而意在一统传统互联网和 移 动互联网。----------------------------------- Android 编程基础 4 Android Android Android Android 手机新...
该应用的核心是基于Java编程语言开发的,Java作为一款跨平台的编程语言,具有良好的可移植性和丰富的库支持,使得开发者能够轻松地构建出能在多种设备上运行的应用程序。Java的面向对象特性也使得代码结构清晰,易于...
因此,对Android感兴趣的开发人员都把Google在2008年发布Android这一举措作为移动技术发展史上的一个非常令人期待的重大事件。 由于Android构建在开源代码的框架之上,而且提供了强大的SDK库和开放的理念,所以它...
《基于Android的校园报警平台设计与实现》 在当今信息化社会,安全问题一直是...同时,这一平台的开发也为Android应用开发提供了实例,对于学习和实践Android客户端应用开发的专业人士来说,是一份宝贵的参考资料。
在安卓应用程序开发中,实现蓝牙发送消息、NFC(近场通信)传输数据、GPS定位以及短信功能是构建强大移动应用的重要组成部分。这些技术的整合可以让应用具备丰富的交互性和实用性,提升用户体验。以下是对这些技术的...
* android.permission.ACCESS_FINE_LOCATION:获取精确的位置信息,通过GPS芯片接收卫星的定位信息,定位精度达10米以内。 * android.permission.ACCESS_LOCATION_EXTRA_COMMANDS:访问额外的定位提供者指令。 * ...
以上列举了Android应用开发中常用的几类权限,包括网络、存储、摄像头、音频、短信以及GPS定位等。这些权限是应用程序正常运行和提供服务所必需的。开发者在设计应用时应根据实际需求合理申请权限,并向用户清晰地...
与粗略定位相反,此权限允许应用通过GPS等技术获取更为精确的位置信息(精确度大约在10米左右),适合需要精确地理位置的服务,例如地图导航应用。 #### android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 此权限...
在Android平台上,手机防盗软件是一种重要的安全应用,它旨在保护用户的设备和数据安全。本项目“android手机防盗软件源代码”提供了一个学习和研究的宝贵资源,帮助开发者深入理解如何构建此类应用程序。以下是对该...
7. **访问Surface Flinger(android.permission.ACCESS_SURFACE_FLINGER)**:这是Android平台上底层的图形显示支持权限,主要用于游戏或照相机预览界面以及底层模式的屏幕截图等。 8. **获取WiFi状态(android....
3. **android.permission.ACCESS_FINE_LOCATION**:此权限提供更精确的定位信息,通过GPS卫星定位,精度可以达到10米以内。对于地图导航、天气预报等需要精确地理位置的应用来说至关重要。 4. **android.permission...
在Android平台上开发此类应用,首先需要理解和掌握以下几个关键知识点: 1. **短信监听和服务**:Android系统提供了BroadcastReceiver类,可以用来监听接收到的短信。我们需要创建一个自定义的短信接收器,注册它以...
- 位置信息:获取和报告设备的位置信息,如GPS和基站定位。 2. **C语言编程**: Android的RIL实现通常使用C语言,因为基带处理器的通信协议栈多为低级协议,适合使用C这样的系统级语言。C语言的高效性和底层控制...
在Android平台上,实现通过短信进行远程位置追踪的技术主要涉及到三个关键组件:短信监听、位置获取以及与第三方地图服务(如百度地图)的集成。以下将详细介绍这些知识点: 1. **短信监听(SmsReceiver)** 在...
LocationManager负责管理和选择合适的定位服务,如GPS或网络定位。开发者注册监听器后,LocationManager会定期或在位置变化时发送Location对象,包含经纬度等信息。理解如何有效地使用Location服务,既能优化用户...
5. **多平台兼容性**:虽然这里提到的是VC++,但考虑到手机定位可能涉及不同类型的设备,开发者需要考虑代码的跨平台兼容性,如iOS或Android。 6. **安全性**:短信数据的传输和存储都需要考虑安全措施,避免信息被...