- 浏览: 433485 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
yehuiyan8002:
支持中文查询
快熟查找联系人 -
lehehe:
现成的接口,免费试用,http://www.haoservic ...
天气Widget -
D.Z:
android:focusable="false&q ...
CheckBox在ListView 而导致其OnItemClickListener不会被触发 -
freecode:
碰到该问题,CheckBox的android:focusabl ...
CheckBox在ListView 而导致其OnItemClickListener不会被触发 -
echohfut:
哥们,新博客是不是在墙外啊?不能访问。还有你怎么进行博客迁移的 ...
博客 迁移
SMS管理
[功能]
1. 收信箱:显示所有收到的信息 且实时显示 即:当有新信息收到 能自动刷新显示
2. 发信箱:显示所有已发信息 同上
3. 编写新信息: 鉴于一些问题 打算不自行定义 而只通过Intent调用系统的
[原理]
1. 通过目标Uri显示收信箱 发信箱 目标Uri:content://sms/inbox content://sms/sent
2. 实时刷新:一个办法是开辟thread 定时查询目标Uri 显示之 但会带来一些效能影响 所以决定使用ContentObserve监听目标Uri 当有变动 由ContentObserve通知注册方 该Uri:content://sms
3. 注意:ContentObserve不能监听: content://sms/inbox & content://sms/sent 而只能监听content://sms
[代码 步骤]
1. 定义SMSObserver 用于监听目标 并通过Handle通知注册方
public class SMSObserver extends ContentObserver { public final static int SMS_CHANGE = 0; Handler handle; public SMSObserver(Handler h) { super(h); // TODO Auto-generated constructor stub handle = h; } public void onChange(boolean selfChange) { // TODO Auto-generated method stub super.onChange(selfChange); //notify SMSInbox & SMSSent handle.sendEmptyMessage(SMS_CHANGE); } }
2. 定义注册方:SMSInbox 鉴于SMSSent与其原理类似 故打算以SMSInbox为例
> 2.1. 显示当前所有收信箱 并与ListView适配
lv = (ListView)findViewById(R.id.list); cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null); adapter = new ItemAdapter(this); lv.setAdapter(adapter);
> 2.2. 定义Handle 用于接受变动 并注册与ContentObserve 当接到通知后 查询目标Uri 并刷新显示
handler = new Handler(){ public void handleMessage(Message msg){ if(msg.what == SMSObserver.SMS_CHANGE){ cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null); adapter.notifyDataSetChanged(); } } }; sObserver = new SMSObserver(handler); this.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, sObserver);
> 2.3. SMSInbox 仅用于显示 收信箱 故定义 SMSDetails extends Activity 用于详细显示 sms信息
- 2.3.1. 定义布局:details.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/detailsNumber" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/detailsBody" android:layout_width="fill_parent" android:layout_height="200dip" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="300dip" android:layout_height="wrap_content" > <Button android:id="@+id/detailsReply" android:layout_width="100dip" android:layout_height="wrap_content" android:layout_gravity="left" android:text="回复" /> <Button android:id="@+id/detailsOK" android:layout_width="100dip" android:layout_height="wrap_content" android:layout_gravity="right" android:text="确定" /> </LinearLayout> </LinearLayout>
- 2.3.2. 其中2个TextView 分别显示信息地址和正文 2个Button 一个用于关闭当前窗口 一个用于短信回复 且自动填充 收信人地址
public class SMSDetails extends Activity { TextView textNumber,textBody; Button btnOK,btnReply; OnClickListener cl; String address,body; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.details); textNumber = (TextView)findViewById(R.id.detailsNumber); textBody = (TextView)findViewById(R.id.detailsBody); btnReply = (Button)findViewById(R.id.detailsReply); btnOK = (Button)findViewById(R.id.detailsOK); Intent i = this.getIntent(); Bundle bundle = i.getExtras(); address = bundle.getString("address"); body = bundle.getString("body"); textNumber.setText("from:"+address); textBody.setText("message body:\n"+body); cl = new OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub switch(arg0.getId()){ case R.id.detailsReply: sendGoNativeNew(address); break; case R.id.detailsOK: sendBack(); break; } } }; btnReply.setOnClickListener(cl); btnOK.setOnClickListener(cl); } public void sendGoNativeNew(String address){ //native send sms app Intent sendIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("sms://")); //auto fill "address" sendIntent.putExtra("address", address); startActivity(sendIntent); } public void sendBack(){ Intent i = new Intent(); this.setResult(RESULT_OK, i); this.finish(); } }
- 2.3.3. 点击SMSInbox 某项 跳转到SMSDetails
lv.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub cursor.moveToPosition(arg2); String body = cursor.getString(cursor.getColumnIndexOrThrow("body")).toString(); String address = cursor.getString(cursor.getColumnIndexOrThrow("address")).toString(); Bundle b = new Bundle(); b.putString("body", body); b.putString("address", address); Intent intent = new Intent(SMSInbox.this,SMSDetails.class); intent.putExtras(b); startActivity(intent); } });
- 2.3.4. 其中 item.xml 用于定义子项布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:id="@+id/body" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/num" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" /> </LinearLayout> <TextView android:id="@+id/body" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="10dip" /> </LinearLayout>
3. 鉴于SMSSent与SMSInbox大同小异 故不再细说 仅补上代码
public class SMSSent extends Activity { ListView lv; Cursor cursor; ItemAdapter adapter; SMSObserver sObserver; Handler handler; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list); setTitle(R.string.sent); lv = (ListView)findViewById(R.id.list); cursor = getContentResolver().query(Uri.parse("content://sms/sent"), null, null, null, null); adapter = new ItemAdapter(this); lv.setAdapter(adapter); lv.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub cursor.moveToPosition(arg2); String body = cursor.getString(cursor.getColumnIndexOrThrow("body")).toString(); String address = cursor.getString(cursor.getColumnIndexOrThrow("address")).toString(); Bundle b = new Bundle(); b.putString("body", body); b.putString("address", address); Intent intent = new Intent(SMSSent.this,SMSDetails.class); intent.putExtras(b); startActivity(intent); } }); //register SMSObserve handler = new Handler(){ public void handleMessage(Message msg){ if(msg.what == SMSObserver.SMS_CHANGE){ cursor = getContentResolver().query(Uri.parse("content://sms/sent"), null, null, null, null); adapter.notifyDataSetChanged(); } } }; sObserver = new SMSObserver(handler); this.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, sObserver); } public class ItemAdapter extends BaseAdapter { Activity activity; public ItemAdapter(Activity a){ activity = a; } @Override public int getCount() { // TODO Auto-generated method stub return cursor.getCount(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return cursor.getString(arg0); } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub return composeItem(arg0); } private View composeItem(int position){ cursor.moveToPosition(position); String body = cursor.getString(cursor.getColumnIndexOrThrow("body")).toString(); String number = cursor.getString(cursor.getColumnIndexOrThrow("address")).toString(); LinearLayout item = (LinearLayout)activity.getLayoutInflater().inflate(R.layout.item, null); LinearLayout l1 = (LinearLayout)item.getChildAt(0); TextView tbody = (TextView)item.getChildAt(1); if(tbody != null){ tbody.setText(body); } TextView tnum = (TextView)l1.getChildAt(1); if(tnum != null){ tnum.setText(number); } ImageView image = (ImageView)l1.getChildAt(0); image.setImageResource(R.drawable.message); return item; } } }
4. emulator 运行截图
> 4.1. SMSInbox:
- 4.1.1. 通过telnet localhost 5554 登录emulator 通过 sms send 123 hello to 123 模拟发送短信
- 4.1.2. 短信发送记录为:
Android Console: type 'help' for a list of commands OK sms send 12 ds OK sms send 23 hi to 23 OK sms send 34 i am griddinshi OK
- 4.1.3. SMSInbox:
> 4.2. SMSSent
- 4.2.1. 已发短信记录:
- 4.2.2. SMSSent:
5. 未解决问题:
> 5.1. ContentObserver 只能监听content://sms 而不支持content://sms/inbox content://sms/sent 个人猜测是因为:android 在写sms数据库 insert(...) 没有通过ContentResolver通知content://sms/inbox content://sms/sent 所致 即:没有以下代码:
getContext().getContentResolver().notifyChange(noteUri, null);
6. 如果写的有问题的 欢迎讨论 否则 请回帖支持一些
评论
我也是使用contentObserver来监听 content://sms
但是每次收到短信,onchange()方法都会被调用两次,是为什么?楼主遇到过吗?
群发?抱歉 因为我没有真机做测试 而emulator又不支持
不过那要看我怎么做了吧
发表评论
-
滑动抽屉 另一种解决办法
2010-07-09 17:43 0滑动抽屉 -
Spinner 定制化 增强版
2010-07-09 14:34 2608Spinner 作为下拉选 ... -
ListView 内容之分批显示
2010-06-25 20:38 5923ListView 内容循环显示 大家试想 假如 ... -
MediaScanner 研究
2010-06-23 15:21 3169MediaScanner 之所以拿MediaSc ... -
CheckBox在ListView 而导致其OnItemClickListener不会被触发
2010-06-22 20:55 19013CheckBox在ListView 而导致其OnItemCli ... -
获取Launcher 启动列表
2010-06-22 10:09 3138获取Launcher 启动列表 即 列出所有Launc ... -
PreferenceActivity 全接触
2010-06-19 12:53 9438PreferenceActivity 为了引入 ... -
android src 下载 编译 安装 全接触
2010-06-12 14:44 0android src - download install ... -
Intent.createChooser() 妙用
2010-06-12 11:14 5955Intent.createChooser(ntent targ ... -
求 android 手机 帮忙测试sms服务系统 谢谢
2010-06-05 08:25 1449Hi guys, 最近一段时间没有更新blog 因为一 ... -
流媒体 播放 理论篇
2010-05-28 14:42 2221流媒体播放 之所以为理论篇 因为该篇仅实现了播放功能 ... -
NDK 搭建与HelloWorld
2010-05-19 09:48 3224NDK [前提] 1. Cygwin 用于安装 ... -
自定义字体
2010-05-15 10:49 1220自定义字体: []代码 步骤] 1 ... -
模糊查找 再深入
2010-05-15 09:41 3157模糊查找 再深入 应某位大哥要求 再次对 SQLite ... -
快捷方式Bar + ViewGroup - 自定义
2010-05-09 09:20 2469TabActivity - 自定义 其实 这篇感觉极鸡 ... -
View 拖动&插入 研究
2010-05-09 07:14 3982View 拖动&插入 即: ... -
带图标 快捷键 Menu - 终极版
2010-05-04 20:23 1837Menu 改头换面 扩展如下: 1. 图标化文字 2 ... -
*.gif 解码 - 实践
2010-05-02 18:58 1733*.gif decode 前面已经说过 今天不打算再说了 ... -
*.gif 解码 - 理论
2010-05-01 21:11 1521我们知道Android 默认是不支持*.gif 的 但是 ... -
shortcut+livefolder
2010-04-19 13:08 1493shortcut+livefolder Live ...
相关推荐
默认的 `Auth` 提供者已经包含了邮箱验证,但要添加 SMS 验证,我们需要扩展这个功能。 2. **安装 SMS 提供商的 SDK** 首先,选择一个 SMS 提供商(如阿里云、腾讯云或 Twilio),并获取其 SDK。通过 Composer ...
《客户信息管理系统详解》 客户信息管理系统是一种针对企业或组织管理其客户数据的重要工具,它旨在提高服务效率,提升客户满意度,并为企业决策提供有力的数据支持。"sms.zip_客户管理系统"是一个实现登录、验证、...
1. **创建和发送短信与彩信**:用户可以直接在Outlook中编写新的短信和彩信,无需离开邮件或日历界面。 2. **项目转发**:用户可以将电子邮件、会议邀请和联系人等信息以短信或彩信的形式转发至移动设备。 3. **双向...
获取短信数据时,可以使用ContentResolver查询`Telephony.Sms`表,获取短信内容、发件人、接收时间等信息。 至于定位信息,Android提供了`Location`框架,允许开发者访问GPS和网络定位服务。使用`...
标题中的“用于部分随身wifi刷了Debian后的短信Email转发,通过监听dbus实时获取新接收的短信并转发至邮箱”表明这是一个项目,其目的是在安装了Debian操作系统的便携式Wi-Fi设备上实现短信到电子邮件的自动转发功能...
创建一个新的Java类,导入必要的Twilio库,并使用以下代码示例发送短信: ```java import com.twilio.Twilio; import com.twilio.rest.api.v2010.account.Message; import com.twilio.type.PhoneNumber; ...
在Android系统中,"给自己发假短信"实际上是一种模拟短信收发的过程,它不涉及到真正的网络通信,而是通过操作系统的内部机制,利用短信Content Provider来向短信数据库添加数据,从而在短信应用中显示出一条新的...
c#编写的短信猫(WAVECOM)发送短信程序dll,没有任何功能限制,在你的程序中引用SIMSMS.dll就可以了。帮助文档就不写了,在程序中有注释,在测试的winform中也有简单应用的示例。看看就明白了! 如果感觉功能不够,...
2. **编写 LotusScript 代码**:在代理中,你需要编写一段代码,该代码每隔五分钟运行一次,检查收件箱是否有新的未读邮件。如果发现新邮件,它会提取邮件的标题,并触发一个通知发送到你的手机。以下是一个简单的 ...
查询通常包括短信的收件人、发件人、时间、内容等信息。 3. **Gmail API**:Google提供了Gmail API,用于访问和管理Gmail账户的邮件。在Android应用中,可以使用Google Play Services库来集成Gmail API,进行邮件的...
在这个应用中,开发者创建了一个BroadcastReceiver来监听SMS_RECEIVED广播,当手机接收到新的短信时,BroadcastReceiver会被触发。 2. **SMS权限**: 在AndroidManifest.xml文件中,开发者需要声明读取短信的权限...
在这个案例中,可能是当旧邮箱收到新邮件时,通过IFTTT触发发送SMS的通知。 标签包括“home automation”(家庭自动化)、“mailbox”(邮箱)、“sms”(短信)和“wifi”(Wi-Fi)。这表明项目不仅限于简单的电子...
3. **IMAP(Internet Message Access Protocol)**:虽然主要涉及接收邮件,但在某些情况下,可能需要使用IMAP来验证用户邮箱信息或获取手机的电子邮件地址。 4. **电子邮件格式**:理解如何构建符合标准的电子邮件...
ESP32gsm-示例:SMS邮件MQTT网关是一种基于ESP32微控制器的集成解决方案,用于通过GSM模块(如SIM800系列)实现短信、电子邮件和MQTT消息的通信功能。这个项目的目标是创建一个智能网关,能够通过多种通信方式与远程...
标题“JAVA我的短消息也可改成邮箱”提示我们这个项目或者教程是关于在Java环境中实现一个功能,将传统的短消息服务(SMS)转化为电子邮件服务。在BS(Browser/Server,浏览器/服务器)架构下,这样的系统通常由前端...
一方面,电子邮件的使用越来越频繁,...该软件对指定邮件服务器的邮箱进行监控,可以实现邮件到达通知、直接用邮件发送短信息、发送邮件的同时发送短消息、短信群发等功能,将信息的传递从桌面上延伸到移动通讯设备上。