Android通讯录管理三之短息获取和发送短息

前两篇博客并分别讲了获取联系人和通话记录的知识,这篇主要介绍短信获取知识,短信在通讯管理中应该说是一个难点,因为短信涉及到短息会话和短信详情两个部分,并且短信的数据量比较大,可以采用AsyncQueryHandler框架来查询,同时采用CursorAdapter来绑定数据

其中短信中可以来获取联系人的头像和姓名。这个在代码工具类中有实现,如果联系人存在,则显示姓名,否则显示号码,如果联系人头像存在则显示头像,否则显示默认头像,如图片所示。这两部分功能在联系人和通话记录中均可以实现,有兴趣的童鞋可以修改。

查询框架

package cn.zxw.contact.utils;

import android.content.AsyncQueryHandler;

import android.content.ContentResolver;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
/**
 * QueryHandler框架
 * @author zhan
 *
 */

public class QueryHandler extends AsyncQueryHandler {

	private static final String TAG = "QueryHandler";

	public QueryHandler(ContentResolver cr) {
		super(cr);
	}

	@Override
	protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
		super.onQueryComplete(token, cookie, cursor);

		String names[] = cursor.getColumnNames();
		for (String name : names) {
			Log.i(TAG, name);
		}
		// 查询完成
		//
		if (cookie != null && cookie instanceof CursorAdapter) {
			// 把查询出来的cursor结果设置给adapter
			CursorAdapter adapter = (CursorAdapter) cookie;
			adapter.changeCursor(cursor);
		}
	}
}

短信会话获取

package cn.zxw.contact;

import cn.zxw.contact.utils.ContactsUtils;
import cn.zxw.contact.utils.QueryHandler;
import cn.zxw.contact.utils.TimeUtils;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.widget.CursorAdapter;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

/**
 * 短信列表
 * 点击短息列表中的条目会进入条目对应的短信详情页面
 * @author zhan
 *
 */
public class MsgActivity extends Activity implements OnItemClickListener {

	private ListView lv;
	public MyCursorAdapter adapter;
	// 查询的结果集
	private String[] projection = new String[] { "snippet",
			"sms.thread_id as _id", "msg_count", "sms.address as address",
			"sms.date as date" };
	private final static int SINPPET_COLUMN_INDEX = 0;
	private final static int THREAD_ID_COLUMN_INDEX = 1;
	private final static int MSG_COUNT_COLUMN_INDEX = 2;
	private final static int ADDRESS_COLUMN_INDEX = 3;
	private final static int DATE_COLUMN_INDEX = 4;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_contacts_msg_calllog);
		lv = (ListView) findViewById(R.id.lv);

		adapter=new MyCursorAdapter(this, null);//初始化Adapter
		lv.setAdapter(adapter);
		startQuery();
		lv.setOnItemClickListener(this);
	}

	/**
	 * 执行查询
	 */
	private void startQuery() {
		QueryHandler mQueryHandler = new QueryHandler(getContentResolver());
		// 执行查询
		/**
		 * token唯一标识 cookie可以用来传递数据 上面的参数会传递给一个方法 onQueryComplete
		 */
		Uri uri = Uri.parse("content://sms/conversations");
		// mQueryHandler.startQuery(0, null, uri, projection, null,
		// null,"date desc");
		mQueryHandler.startQuery(0, adapter, uri, projection, null, null,
				"date desc");

	}

	// 自定义CursorAdapter
	private class MyCursorAdapter extends CursorAdapter {

		private LayoutInflater mInflater;

		public MyCursorAdapter(Context context, Cursor c) {
			super(context, c);
			mInflater = LayoutInflater.from(context);
		}

		// 创建条目
		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			View view = mInflater.inflate(R.layout.activity_msg_list_item,
					null);
			return view;
		}

		// 绑定条目
		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			// 1.获取条目
			// 2.获取数据
			// 3.绑定数据
			ImageView iv_header = (ImageView) view.findViewById(R.id.iv_header);
			TextView tv_number = (TextView) view.findViewById(R.id.tv_number);
			TextView tv_body = (TextView) view.findViewById(R.id.tv_body);
			TextView tv_date = (TextView) view.findViewById(R.id.tv_date);
			// 由于Listview的数据显示是通过适配器来控制的,所以到bindView方法中来控制checkbox 的显示
			// 获取数据
			int id = cursor.getInt(THREAD_ID_COLUMN_INDEX);
			String address = cursor.getString(ADDRESS_COLUMN_INDEX);
			int msg_count = cursor.getInt(MSG_COUNT_COLUMN_INDEX);
			long date = cursor.getLong(DATE_COLUMN_INDEX);
			String body = cursor.getString(SINPPET_COLUMN_INDEX);
			System.out.println(address);
			// 绑定数据
			String displayName = ContactsUtils.getContactNameByAddress(
					getApplicationContext(), address);
			if (TextUtils.isEmpty(displayName)) {
				// 未知联系人
				iv_header.setImageResource(R.drawable.ic_launcher);
				tv_number.setText(address + "(" + msg_count + ")");
			} else {
				// 已知联系人
				tv_number.setText(displayName + "(" + msg_count + ")");
				Bitmap bitmap = ContactsUtils.getContactPhotoByAddress(
						getApplicationContext(), address);
				if (bitmap == null) {
					iv_header.setImageResource(R.drawable.ic_launcher);
				} else {
					iv_header.setImageBitmap(bitmap);
				}
			}
			tv_body.setText(body);
			String dataStr = TimeUtils
					.formatDate(getApplicationContext(), date);
			tv_date.setText(dataStr);
		}

	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		//传递数据
		Cursor cursor = (Cursor) adapter.getItem(position);
		int _id = cursor.getInt(THREAD_ID_COLUMN_INDEX);
		String address=cursor.getString(ADDRESS_COLUMN_INDEX);
		String displayName=ContactsUtils.getContactNameByAddress(getApplicationContext(), address);
		//进入列表详情页面
		Intent intent=new Intent(this, MsgDetailActivity.class);
		intent.putExtra("_id", _id);
		intent.putExtra("address", address);
		intent.putExtra("displayName", displayName);

		startActivity(intent);
	}

}

短信详情页面,可以实现发送短息

package cn.zxw.contact;

import cn.zxw.contact.utils.Constants;
import cn.zxw.contact.utils.ContactsMsgUtils;
import cn.zxw.contact.utils.QueryHandler;
import cn.zxw.contact.utils.TimeUtils;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.widget.CursorAdapter;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MsgDetailActivity extends Activity implements OnClickListener {
	private Button bt_back;
	private TextView tv_number;
	private ListView lv;
	private EditText et_msg_content;
	private Button bt_send;
	private int _id;
	private String address;
	private MyCursorAdapter adapter;
	private String[] projection=new String[]{
			"_id","type","body","date"
	};
	private final static int ID_COLUMN_INDEX=0;
	private final static int TYPE_COLUMN_INDEX=1;
	private final static int BODY_COLUMN_INDEX=2;
	private final static int DATE_COLUMN_INDEX=3;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_msg_list_detail);
		initView();
		startQuery();
	}

	public void initView() {
		bt_back = (Button) findViewById(R.id.bt_back);
		tv_number = (TextView) findViewById(R.id.tv_number);
		lv = (ListView) findViewById(R.id.lv);
		et_msg_content = (EditText) findViewById(R.id.et_msg_content);
		bt_send = (Button) findViewById(R.id.bt_send);
		bt_back.setOnClickListener(this);
		bt_send.setOnClickListener(this);
		Intent intent=getIntent();
		_id = intent.getIntExtra("_id", 0);
		address = intent.getStringExtra("address");
		String displayName=intent.getStringExtra("displayName");
		if (TextUtils.isEmpty(displayName)) {
			tv_number.setText(address);
		}else{
			tv_number.setText(displayName);
		}
		adapter = new MyCursorAdapter(this, null);
		lv.setAdapter(adapter);

	}

	public void startQuery() {
		//查询
		QueryHandler mHandler=new QueryHandler(getContentResolver());
		//查询指定会话id里面的所有短信
		String selection="thread_id=?";
		String[] selectionArgs=new String[]{_id+""};
		mHandler.startQuery(0, adapter, Constants.SMS_URI, projection, selection, selectionArgs, "date asc");
	}

	private class MyCursorAdapter extends CursorAdapter{

		public MyCursorAdapter(Context context, Cursor c) {
			super(context, c);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
			View view=getLayoutInflater().inflate(R.layout.activity_msg_detial_item, null);
			return view;
		}
		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			TextView tv_date=(TextView) view.findViewById(R.id.tv_date);
			TextView tv_send=(TextView) view.findViewById(R.id.tv_send);
			TextView tv_receive=(TextView) view.findViewById(R.id.tv_receive);

			long date=cursor.getLong(DATE_COLUMN_INDEX);
			String body=cursor.getString(BODY_COLUMN_INDEX);
			int type=cursor.getInt(TYPE_COLUMN_INDEX);
			String str=TimeUtils.formatDate(getApplicationContext(), date);
			tv_date.setText(str);
			if (type==Constants.RECEIVE_TYPE) {
				//1表示接收
				tv_date.setVisibility(View.VISIBLE);
				tv_receive.setText(body);
				tv_send.setVisibility(View.GONE);
			}else if (type==Constants.SEND_TYPE) {
				//2表示发送
				tv_date.setVisibility(View.VISIBLE);
				tv_send.setVisibility(View.VISIBLE);
				tv_send.setText(body);
				tv_receive.setVisibility(View.GONE);
			}
		}
		/**
		 * 该方法一定会被系统调用
		 */
		@Override
		public void notifyDataSetChanged() {
			super.notifyDataSetChanged();
			//让Listview滚动到最后面
			lv.setSelection(adapter.getCount()-1);
		}

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.bt_back:
			finish();//关闭当前activity
			break;
		case R.id.bt_send:
			// 获取短息内容
			String content=et_msg_content.getText().toString().trim();
			if (TextUtils.isEmpty(content)) {
				//发送内容为空
				Toast.makeText(getApplicationContext(), "短信为空", 0).show();
			}else{
				ContactsMsgUtils.sendMsg(getApplicationContext(), address, content);
				//清空
				et_msg_content.setText("");
				//短息发送成功后自动滚动到最后
			}
			break;

		default:
			break;
		}
	}

}

短信发送方法:

	/**
	 * 发送短信
	 * @param address
	 * @param content
	 */
	public static void sendMsg(Context context,String address,String content){
		SmsManager smsManager=SmsManager.getDefault();//如果短信太长,拆分短信
		ArrayList<String> parts=smsManager.divideMessage(content);
		smsManager.sendMultipartTextMessage(address, null, parts, null, null);
		//手动存储短信
		ContentResolver resolver=context.getContentResolver();
		Uri uri=Constants.SMS_URI;
		ContentValues values=new ContentValues();
		values.put("address", address);
		values.put("body", content);
		values.put("type", Constants.SEND_TYPE);
		values.put("date", System.currentTimeMillis());

		resolver.insert(uri, values);
	}

关于AsyncQueryHandler和CursorAdapter可以参考http://blog.csdn.net/yuzhiboyi/article/details/8093408http://blog.csdn.net/yuzhiboyi/article/details/7654840来学习

时间: 2024-07-31 09:54:49

Android通讯录管理三之短息获取和发送短息的相关文章

Android通讯录管理二之通话记录获取

上一篇博客讲的是获取联系人信息,这篇是获取通话记录 同样你可以在这里下载http://download.csdn.net/detail/waniu123/8554533 package cn.zxw.contact.domain; /** * 通话记录 * @author zhan * */ public class CallLogInfo { public String number; public long date; public int type; public CallLogInfo(

Android通讯录管理(获取联系人、通话记录、短信消息)(二)

http://blog.csdn.net/wwj_748/article/details/19970271 Android通讯录管理(获取联系人.通话记录.短信消息)(二) 2014-02-26 11:40 9076人阅读 评论(11) 收藏 举报  分类: [Android通讯录模块开发](10)  版权声明:本文为博主原创文章,未经博主允许不得转载. Android通讯录管理(获取联系人.通话记录.短信消息)(二) 前言:上一篇博客介绍的是获取联系人的实现,本篇博客将介绍通话记录的实现. 同

Android通讯录管理一之联系人获取

正如我们知道的一样,Android的通讯录和短信管理是通过contentprovider来向开发者来开发接口的.必须从ContentResolver入手去解决.其中通讯录操作涉及到系统源码api的使用,特别是在表的uri上面容易弄混.在接下来的几篇文章中蜗牛将陆续为大家推出Android通讯管理相关知识的文章.其中包括联系人获取.通话记录获取.短信获取.短信详情获取发送短信.废话不多说先上图 先看看联系人的表的结构 其中对于开发这来说主要关注以上三个表,其中要用到联合查询,关于三张表的设计可以百

java攻城师之路(Android篇)--搭建开发环境、拨打电话、发送短信、布局例子

一.搭建开发环境 1.所需资源 JDK6以上 Eclipse3.6以上 SDK17, 2.3.3 ADT17 2.安装注意事项 不要使用中文路径 如果模拟器默认路径包含中文, 可以设置android_sdk_home环境变量解决.效果如下: 二.拨打电话 1.步骤 在Button节点中添加onClick属性, 指定一个方法名 在Activity中定义一个public void 方法名 (View view) 获取文本框中的号码 创建意图, 设置动作, 设置数据 使用意图开启Activity 2.

金笛短信盒子MN1702 发送短信速度达到1.5条/秒

短信猫的发送速度一般在500~600条/小时,平均要6秒/条,金笛智能短信盒子MN1702实测可达5400条/小时,平均1.5条/秒.一个短信盒子相当于9~10台短信猫的发送速度.智能短信盒子之所以有这样的能力,主要因为它有一颗8核2.0G主频的CPU,处理能力十分强.除此之外,还有一些优势是短信猫不能比的: 一.可靠性好.短信盒子可以设置失败重发次数,保证短信100%发送成功. 二.信号强.短信盒子支持更多频段,高频纯净,干扰少,在地下室只要手机有一格信号,短信盒子就可以正常发送. 三.部署更

点击发送短信按钮跳转到手机短信界面实现发送短信

新建一个singleView代码如下: #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {     [super viewDidLoad];     NSLog(@"%@",NSHomeDirectory());     UIButton *button = [UIButton buttonW

Android获取最新发送短信的基本信息,没有之一

注册: getContentResolver().registerContentObserver(                Uri.parse("content://sms"), true,                new SmsObserver(this, new Handler())); 监听: //用于检测发出的短信    public class SmsObserver extends ContentObserver {        private Context

Android接收和发送短信

每一部手机都具有短信接收和发送功能,下面我们通过代码来实现接收和发送短信功能. 一.接收短信 1.创建内部广播接收器类,接收系统发出的短信广播 2.从获得的内容中解析出短信发送者和短信内容 3.在Activity中注册广播 4.添加接收短信权限 下面放上具体的代码 activity_main.xml文件用于显示短信发送者号码和显示短信内容 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout

Android通讯录数据库介绍与基本操作(增删改查)

Android通讯录数据库介绍与基本操作(增删改查) 2014年2月21日 Android通讯录管理总结 这几天导师安排我一个任务就是研究一下Android通讯录获取联系人.通话记录.短信的方法,还有看看不同Android版本之间的异同是否能做到兼容之类的事情.Android通讯录这一块,我个人感觉是挺乱的,网上一堆关于查询本地数据库获取联系人的方法,但似乎都没有仔细说明数据有哪些重要的表,它们之间有什么联系.下面是本人查询资料总结的一下知识点,方便童鞋们以后用到. http://xys2891