android发送短信、会话列表、短信详情
2016-03-16 13:14
681 查看
源码下载 点击打开链接
首先看第一个会话列表界面
activity_main.xml 里面只有一个ListView控件,用来为ListView填充会话列表内容
在看ListView的每一个item布局
MainActivity
然后看第二个页面就是短信详情页面
hei_item.xml
me_item.xml
ThreadDetailActivity
MyThreadDetailAdapter适配器
ThreadDetailBean
首先看第一个会话列表界面
activity_main.xml 里面只有一个ListView控件,用来为ListView填充会话列表内容
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <ListView android:id="@+id/mListView" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout>
在看ListView的每一个item布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFB5C5" android:orientation="vertical" > <TextView android:id="@+id/name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="傻Bddddddddddd" android:textSize="18sp" /> <TextView android:id="@+id/content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="最后一条短信内容ffffffffffffffffffff" android:textSize="15sp" /> </LinearLayout>
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; } }
然后看第二个页面就是短信详情页面
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/mThreadListView" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" > </ListView> <EditText android:id="@+id/sms_content" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/send_sms" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="发送短信" /> </LinearLayout>
hei_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="name" /> <TextView android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="content" /> </LinearLayout>
me_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="right" android:text="name" /> <TextView android:gravity="right" android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="content" /> </LinearLayout>
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<ThreadDetailBean> 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<ThreadDetailBean>(); 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<String> 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<ThreadDetailBean> mDatas; public MyThreadDetailAdapter(Context mContext, ArrayList<ThreadDetailBean> 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:Android官方培训课程中文版(v0.9.4)
- android教程之textview解析带图片的html示例
- Android 5.x 权限问题解决方法
- Android View的测量
- Android 数据上传(上传图片的时候同时上传图片名,拍照时间之类的)
- android---Activity间消息互传
- Android setContentView方法解析(二)
- cordova开发介绍(android平台)
- android开发之路08(ListView&Adapter)
- android studio 中R文件丢失报错问题
- Android------打招呼
- Android SDK下载和更新失败 Android SDK Manager更新失败
- android 上传文件到服务器
- Android常用工具类DateUtils(二)
- android中的消息
- Android 自定义View修炼-仿360手机卫士波浪球进度的实现
- android学习记录
- android中handler的使用
- Android自定义控件--圆形进度条(中间有图diao)
- 0116android错误总结