android发送短信、会话列表、短信详情

源码下载  点击打开链接

首先看第一个会话列表界面

activity_main.xml 里面只有一个ListView控件,用来为ListView填充会话列表内容



    


在看ListView的每一个item布局





    


    



MainActivity

package com.example.mysmsthreads;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.PhoneLookup;
import android.app.Activity;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

/**
 * AsyncQueryHandler 异步数据库查询 CursorAdapter 就是数据库的特有的适配器 获取短信的url
 * 
 * @author wyf
 * 
 */
public class MainActivity extends Activity {
	private static final String TAG = "MainActivity";
	ListView mListView;
	private CursorAdapter mAdapter;
	private MyAsyncQueryHandler asyncQueryHandler;
	private String[] projection = new String[] { "sms.thread_id AS _id",
			"sms.body AS snippet", "groups.msg_count AS msg_count",
			"sms.address AS address", "sms.date AS date" };

	private String[] contentProjection = new String[] { PhoneLookup._ID,
			PhoneLookup.DISPLAY_NAME };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mListView = (ListView) findViewById(R.id.mListView);
		mAdapter = new MyAdatper(this, null);

		// 获取数据库数据
		mListView.setAdapter(mAdapter);
		asyncQueryHandler = new MyAsyncQueryHandler(getContentResolver());
		asyncQueryHandler.startQuery(0, null,
				Uri.parse("content://sms/conversations/"), projection, null,
				null, " date desc");
	}

	class MyAsyncQueryHandler extends AsyncQueryHandler {

		public MyAsyncQueryHandler(ContentResolver cr) {
			super(cr);
			// TODO Auto-generated constructor stub
		}

		@Override
		protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
			super.onQueryComplete(token, cookie, cursor);
			Log.i(TAG, "onQueryComplete" + (cursor == null));
			mAdapter.changeCursor(cursor);
		}
	}

	class MyAdatper extends CursorAdapter {

		private ViewHolder mHolder;

		public MyAdatper(Context context, Cursor c) {
			super(context, c);
			// TODO Auto-generated constructor stub
		}

		/**
		 * 
		 "sms.thread_id AS _id", "sms.body AS snippet",
		 * "groups.msg_count AS msg_count", "sms.address AS address",
		 * "sms.date AS date"
		 * 
		 * 	private String[] projection = new String[] { "_id", "address", "person",
			"body", "type", "date" };
		 */
		@Override
		public void bindView(View view, Context arg1, Cursor cursor) {
			if (view != null) {
				mHolder = (ViewHolder) view.getTag();
				TextView nameTv = mHolder.name;
				TextView contentTv = mHolder.content;

				final String thread_id = cursor.getString(0);
				String content = cursor.getString(1);
				int count = cursor.getInt(2);
				final String address = cursor.getString(3);
				long date = cursor.getLong(4);
				// 短信内容
				if (content != null && content.length() > 10) {
					contentTv.setText(content.substring(0, 10));
				} else {
					contentTv.setText(content);

				}
				// 次数--时间--java基础知识,获取时间的
				Calendar calendar = Calendar.getInstance();
				calendar.setTimeInMillis(date);

				SimpleDateFormat format = new SimpleDateFormat(
						"yyyy-MM-dd HH:mm:ss");
				String formatTime = format.format(calendar.getTime());

				/**
				 * 定义成局部变量,不要定义成成员变量
				 */
				String phoneName = null;
				Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
						Uri.encode(address));
				Cursor concatCursor = getContentResolver().query(uri,
						contentProjection, null, null, null);
				if (concatCursor.moveToFirst()) {
					// 查询到了联系人
					phoneName = concatCursor.getString(1);
				}
				concatCursor.close();

				if (phoneName != null) {
					nameTv.setText(phoneName + "(" + count + ")" + formatTime);
					Log.i(TAG, "phoneName:" + phoneName);
				} else {
					nameTv.setText(address + "(" + count + ")" + formatTime);
					Log.i(TAG, "address:" + address);
				}

				
				view.setOnClickListener(new View.OnClickListener() {
					
					@Override
					public void onClick(View v) {
						Intent intent = new Intent(MainActivity.this, ThreadDetailActivity.class);
						intent.putExtra("thread_id",thread_id);
						intent.putExtra("phone", address);
						startActivity(intent);
					}
				});
			}

		}

		@Override
		public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
			View view = null;
			if (view == null) {
				mHolder = new ViewHolder();
				view = View.inflate(getApplicationContext(), R.layout.item,
						null);
			}

			mHolder.name = (TextView) view.findViewById(R.id.name);
			mHolder.content = (TextView) view.findViewById(R.id.content);

			view.setTag(mHolder);
			return view;

		}

	}

	class ViewHolder {
		TextView name;
		TextView content;
	}
}


然后看第二个页面就是短信详情页面

android发送短信、会话列表、短信详情_第1张图片




    
    

    

    

hei_item.xml




    

    



me_item.xml




    

    



ThreadDetailActivity

package com.example.mysmsthreads;

import java.util.ArrayList;

import android.R.array;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Contacts.Intents.UI;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.gsm.SmsManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
/**
 * 同志们回去总结下
 * 发送短信的2种方法
 * 发送广播、对方受到广播
 * 监听数据库变化的广播,以及内容观察着
 * 推荐 http://www.itnose.net/detail/6132802.html
 * @author wyf
 *
 */
public class ThreadDetailActivity extends Activity implements OnClickListener {
	private static final String TAG = "ThreadDetailActivity";
	ListView mListView;
	private String thread_id;
	private String phone;
	private MyThreadDetailAdapter mThreadDetailAdapter;
	private ArrayList mDatas;
	private Uri uri = Uri.parse("content://sms/");
	private String[] projection = new String[]{ "_id", "address", "person",
			"body", "type", "date" };
	private String[] contactProjection = new String[]{PhoneLookup._ID,PhoneLookup.DISPLAY_NAME};
	
	EditText sms_content;
	Button send_sms;
	
	MySendBr sendBr = new MySendBr();
	MyDeliverBr deliverBr = new MyDeliverBr();
	private mySmsContentObserver observer = new mySmsContentObserver(new Handler());
	class mySmsContentObserver extends ContentObserver{

		public mySmsContentObserver(Handler handler) {
			super(handler);
			// TODO Auto-generated constructor stub
		}
		@Override
		public void onChange(boolean selfChange) {
			// TODO Auto-generated method stub
			super.onChange(selfChange);
			init();
		}
	}
	class MySendBr extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			if (getResultCode() == Activity.RESULT_OK) {
				Log.e(TAG, "mysend_sms");
				Toast.makeText(context, "send ok", 0).show();
				//刷新页面而已 TODO
				init();
				
			}
			/**
			 * 加上这个判断会打印不出来??  大家回去查查吧
			 */
			if (intent!=null && intent.equals("SENT_SMS_ACTION")) {
				
			}
		}
		
	}
	
	class MyDeliverBr extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			if (intent != null && intent.getAction().equals("DELIVERED_SMS_ACTION")) {
				Toast.makeText(context, "deliverd ok", 0).show();
				Log.e(TAG, "myDeliverd");
			}
		}
		
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.thread_detail);
		//动态注册2个广播--发送成功,对方接收成功
		registerReceiver(sendBr, new IntentFilter("SENT_SMS_ACTION"));
		registerReceiver(deliverBr, new IntentFilter("DELIVERED_SMS_ACTION"));
		//受到系统的短信 注册短信数据库变化通知的。。
		getContentResolver().registerContentObserver(uri, true, observer);
		
		init();
	}
	private void init() {
		Intent intent = getIntent();
		if (intent!=null) {
			thread_id = intent.getStringExtra("thread_id");
			phone = intent.getStringExtra("phone");
			Log.i(TAG, "thread_id"+thread_id+",phone::"+phone);
		}
		sms_content = (EditText) findViewById(R.id.sms_content);
		send_sms = (Button) findViewById(R.id.send_sms);
		send_sms.setOnClickListener(this);
		mListView = (ListView) findViewById(R.id.mThreadListView);
		//data--数据库中获取!!!!
		Cursor threadDetailCursor = getContentResolver().query(uri, projection, "thread_id=?",new String[]{thread_id} , "date desc");
		praseThreadDetailCursor(threadDetailCursor);
		//适配器
		mThreadDetailAdapter = new MyThreadDetailAdapter(this,mDatas);
		//设置适配器
		mListView.setAdapter(mThreadDetailAdapter);
	}
	private void praseThreadDetailCursor(Cursor threadDetailCursor) {
		mDatas = new ArrayList();
		if (threadDetailCursor!=null && threadDetailCursor.getCount()>0) {
			while (threadDetailCursor.moveToNext()) {
				String address = threadDetailCursor.getString(threadDetailCursor.getColumnIndex("address"));
				String body = threadDetailCursor.getString(threadDetailCursor.getColumnIndex("body"));
				String type = threadDetailCursor.getString(threadDetailCursor.getColumnIndex("type"));
				String date = threadDetailCursor.getString(threadDetailCursor.getColumnIndex("date"));
				
				//type為1是对方的item,为2是自己的itme
				//通过电话获取联系人的姓名
				String contactName = null;
				Uri contactNameUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address));
				Cursor contactNameCursor = getContentResolver().query(contactNameUri, contactProjection, null, null, null);
				if (contactNameCursor!=null&& contactNameCursor.moveToFirst()) {
					contactName = contactNameCursor.getString(1);
				}
				Log.i(TAG, "address"+address+",body"+body+",type"+type+",date"+date+",contactName"+contactName);
				if (type.equals("1")) {
					//对方
					ThreadDetailBean heiBean = null;
					if (contactName!=null) {
						heiBean = new ThreadDetailBean(contactName, date, body, R.layout.hei_item);
					}else {
						heiBean = new ThreadDetailBean(address, date, body, R.layout.hei_item);
					}
					mDatas.add(heiBean);
				}else {
					//自己
					ThreadDetailBean mBean = new ThreadDetailBean(null, date, body, R.layout.me_item);
					mDatas.add(mBean);
					
				}
			}
			
			Log.i(TAG, "mDatas.size()>>>>"+mDatas.size());
		}
	}
	@SuppressWarnings("deprecation")
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.send_sms:
			String smsContent = sms_content.getText().toString().trim();
			if (smsContent.equals("")) {
				return ;
			}
			/**
			 * 发送系统短信需要一个类-smsManager
			 * 1、短信发送成功对方接受到的话,自己会受到广播
			 * 2、发送成功也将会受到广播
			 * 区别:deliveryIntent  对方受到短信然后对方给移动。。回馈,然后移动。。在回馈给自己
			 * sentIntent 说明自己发送给移动。。的通讯商了
			 */
			
			SmsManager manager = SmsManager.getDefault();
			Intent mySendIntent = new Intent("SENT_SMS_ACTION");
			Intent myDeliverIntent = new Intent("DELIVERED_SMS_ACTION");
			PendingIntent sentIntent = PendingIntent.getBroadcast(ThreadDetailActivity.this, 0, mySendIntent, 0);
			PendingIntent deliveryIntent = PendingIntent.getBroadcast(ThreadDetailActivity.this, 0, myDeliverIntent, 0);
			if (smsContent.length()>70) {
				ArrayList divideMessage = manager.divideMessage(smsContent);
				for (int i = 0; i < divideMessage.size(); i++) {
					manager.sendTextMessage(phone, null, divideMessage.get(i), sentIntent, deliveryIntent);
				}
			}else {
				manager.sendTextMessage(phone, null, smsContent, sentIntent, deliveryIntent);
			}
			
			ContentValues values = new ContentValues();
			values.put("address", phone); // 发送地址
			values.put("body", smsContent); // 消息内容
			values.put("date", System.currentTimeMillis()); // 创建时间
			values.put("read", 0); // 0:未读; 1:已读
			values.put("type", 2); // 1:接收; 2:发送
			getContentResolver().insert(Uri.parse("content://sms/sent"), values); // 插入数据

			break;

		default:
			break;
		}
	}

}

MyThreadDetailAdapter适配器

package com.example.mysmsthreads;

import java.util.ArrayList;

import android.content.Context;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.TextView;

public class MyThreadDetailAdapter extends BaseAdapter{

	private Context mContext;
	private ArrayList mDatas;
	public MyThreadDetailAdapter(Context mContext,
			ArrayList mDatas) {
		this.mContext = mContext;
		this.mDatas = mDatas;
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return mDatas.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return mDatas.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public int getItemViewType(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		
		ThreadDetailBean threadDetailBean = mDatas.get(position);
		int layoutId = threadDetailBean.getLayoutId();
		if (layoutId==R.layout.hei_item) {
			//type 1 对方
			convertView = View.inflate(mContext, R.layout.hei_item, null);
		}else if (layoutId==R.layout.me_item) {
			//type 2 自己
			convertView = View.inflate(mContext, R.layout.me_item, null);
		}
		TextView  name = (TextView) convertView.findViewById(R.id.name);
		TextView  content = (TextView) convertView.findViewById(R.id.content);
		
		name.setText(threadDetailBean.getPhone()+":"+threadDetailBean.getDate());
		content.setText(threadDetailBean.getContent());
		
		
		return convertView;
		
	}

	/**
	 * 这里如果填写2的话 ,滑动屏幕就会崩溃??为什么呢??? 我也不知道,
	 * 查查资料??
	 */
	@Override
	public int getViewTypeCount() {
		// TODO Auto-generated method stub
		return mDatas.size();
	}


	

}

ThreadDetailBean

package com.example.mysmsthreads;

public class ThreadDetailBean {
	private String phone;
	private String date;
	private String content;
	private int layoutId;

	public ThreadDetailBean() {
		super();
		// TODO Auto-generated constructor stub
	}

	public ThreadDetailBean(String phone, String date, String content,
			int layoutId) {
		super();
		this.phone = phone;
		this.date = date;
		this.content = content;
		this.layoutId = layoutId;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public int getLayoutId() {
		return layoutId;
	}

	public void setLayoutId(int layoutId) {
		this.layoutId = layoutId;
	}

}



你可能感兴趣的:(Android基础)