您的位置:首页 > 移动开发 > Android开发

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

2016-03-16 13:14 681 查看
源码下载 点击打开链接

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

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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: