Android短信会话(查看会话记录以及会话详情界面)---短信管家3

看一下上一篇,其实是有缺陷的,我们在载入联系人的时候是放在主线程中做的(比较耗时),所以界面会卡住。推荐使用异步查询来解决

这一篇我们谈短信会话:

首先看一下效果图


这个是所有会话的列表(区分有头像和没有头像的,联系人没有头像的就暂时不显示图片,有头像则显示头像)


点击一个会话则进入详细会话页面:



这两个页面开发,主要是通过查找android的 mmssms.db这个数据库的结果

看看android底层数据的实现,了解下原理吧。

这个数据库的路径是在:/data/data下的  com.android.provider.telephony目录下

打开数据库:


里面有21张表,我们不需要所有表,这里我们需要使用到的表是:  canonical_addresses   threads   sms这三张表。

多表查询比较麻烦,这里我就直接贴上来了:

我们查询的时候首先通过电话号码可以从表canonical_addresses拿到_id,这个id和threads表中的 _id是一样的 ,我们到threads中可以查到相关会话信息(也就是第一个页面所需要的信息)

跟据这个id也可以到sms表中拿到所有的与该电话关联的所有会话记录(就是第二个页面)//这里我们为什么不直接用电话号码去拿。细心的朋友会发现同一个联系人电话号码有的是 13512345678 有的是 +8613512345678,所以操作起来会比较麻烦


哦了,原理我们就先理解到这里了,然后该做啥了呢。关于这些信息,系统都封装成了内容提供者来供我们调用了,所以,就好弄了哦。

下面看一下具体实现吧:

老规矩,先把页面给大家哦:

第一个页面:

<LinearLayout 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" android:orientation="vertical"android:background="@drawable/bg"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:gravity="center"android:background="@color/title"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/title_conversation"android:textColor="#ffffff"android:textSize="25dp"/></LinearLayout><ListView android:id="@+id/lv_conversation"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>

然后是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="@drawable/home_item_selector"android:gravity="center_vertical"android:orientation="horizontal" ><ImageViewandroid:id="@+id/iv_conversation_item_img"android:layout_width="50dp"android:layout_height="50dp"android:layout_marginTop="3dp"android:layout_marginBottom="3dp"android:src="@drawable/ic_launcher"/><LinearLayout android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"android:layout_marginLeft="5dp"android:layout_weight="3"><LinearLayout        android:layout_width="wrap_content"android:layout_height="wrap_content"><TextViewandroid:id="@+id/tv_conversation_item_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="18sp"android:textColor="#FFFFFF"android:text="傻Bdddddddddddddddddddddddddddddddddddd"/> <!-- <TextViewandroid:id="@+id/tv_conversation_item_number"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="18sp"android:textColor="#FFFFFF"android:text="(88)"/>  	   -->            	</LinearLayout>    <TextViewandroid:id="@+id/tv_conversation_item_content"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="15sp"android:textColor="#FFFFFF"android:text="最后一条短信内容fffffffffffffffffffffffffffffffffffffffffffffff"/></LinearLayout> <TextView android:id="@+id/tv_conversation_item_place"android:layout_width="90dp"android:layout_height="wrap_content"android:textSize="15sp"android:textColor="#FFFFFF"android:text="2013-12-12"/></LinearLayout>


第二个详细会话页面的实现

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><LinearLayoutandroid:id="@+id/ll_talk_title_nouse"android:layout_width="match_parent"android:layout_height="50dp"android:background="@color/title"android:layout_alignParentTop="true"android:gravity="center" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/title_talk"android:textColor="#ffffff"android:textSize="20dp" /></LinearLayout><ListViewandroid:id="@+id/list"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_below="@id/ll_talk_title_nouse"android:layout_above="@+id/ll_bottom_talk_nouse"/><RelativeLayoutandroid:id="@+id/ll_bottom_talk_nouse"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:background="@color/title" ><EditTextandroid:id="@+id/et_intext"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_toLeftOf="@+id/bt_talk_send"android:hint="请输入短信内容"/><Buttonandroid:id="@+id/bt_talk_send"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:text="发送" /></RelativeLayout></RelativeLayout>
这里需要稍微注意下:我发的消息用蓝色气泡背景显示在右边,别人发过来的信息用白色背景气泡显示在左边(实现这样的效果要根据表中查出来的一个叫 TYPE的字段来区分,type为1的是对方发过来的,type为2的则是我发的)

这样的话毋庸置疑,item也需要使用两种不同的了。至于气泡背景可以随处找一下,csdn中类似实现的博客和资源也有很多,我也是参考了某个博客的,感谢下博主,不过把地址没有留下来,深感抱歉

我发的消息的item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_marginLeft="10px"android:gravity="right"android:orientation="horizontal" ><LinearLayoutandroid:id="@+id/layout_bj"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/outgoing"android:layout_marginBottom="3dp"android:orientation="vertical" ><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="22dip"android:orientation="horizontal" ><TextViewandroid:id="@+id/messagedetail_row_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingTop="2px"android:textColor="#000000"android:textSize="14dip" /><TextViewandroid:id="@+id/messagedetail_row_date"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="60dip"android:paddingTop="2px"android:textColor="#000000"android:textSize="14dip" /></LinearLayout><TextViewandroid:id="@+id/messagedetail_row_text"android:layout_width="fill_parent"android:layout_height="wrap_content"android:paddingLeft="2px"android:textColor="#0000DD"android:textSize="18dip" /></LinearLayout></LinearLayout>

发过来的item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><LinearLayoutandroid:id="@+id/layout_bj"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/incoming"android:layout_marginBottom="3dp"android:orientation="vertical" ><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="22dip"android:orientation="horizontal" ><TextViewandroid:id="@+id/messagedetail_row_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingTop="2px"android:textColor="#000000"android:textSize="14dip" /><TextViewandroid:id="@+id/messagedetail_row_date"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="60dip"android:paddingTop="2px"android:textColor="#000000"android:textSize="14dip" /></LinearLayout><TextViewandroid:id="@+id/messagedetail_row_text"android:layout_width="fill_parent"android:layout_height="wrap_content"android:paddingLeft="2px"android:textColor="#0000DD"android:textSize="18dip" /></LinearLayout></LinearLayout>

哦了,到上面,界面的框架是搭建出来了。

然后我们来做代码的实现,会话列表界面的activity

package com.xiaoxu.message;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.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.PhoneLookup;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;import com.xiaoxu.message.util.GetHeadImg;public class ConversationActivity extends Activity {	private ListView listview;private QueryHandler queryHandler;private ConversationAdapter adapter;private static final int ID_COLUMN_INDEX = 0;private static final int SNIPPET_COLUMN_INDEX = 1;private static final int MSG_COUNT_COLUMN_INDEX = 2;private static final int ADDRESS_COLUMN_INDEX = 3;private static final int DATE_COLUMN_INDEX = 4;//联系人查询的字段信息private static final String[] CONCAT_PROJECTION = new String[]{PhoneLookup._ID,PhoneLookup.DISPLAY_NAME};private static final int DISPLAY_NAME_COLUMN_INDEX = 1;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_conversation);listview = (ListView) findViewById(R.id.lv_conversation);adapter = new ConversationAdapter(this, null);listview.setAdapter(adapter);
//        listview.setOnItemClickListener(new OnItemClickListener() {
//			@Override
//			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
//				Intent intent = new Intent(ConversationActivity.this,TalkingActivity.class);
//				intent.putExtra("number", "xxxxx");
//				startActivity(intent);			
//			}
//		});queryHandler = new QueryHandler(getContentResolver());startQuery();}private static final String[] PROJECTION = new String[]{//cursor 查询 需要_id"sms.thread_id AS _id","sms.body AS snippet","groups.msg_count AS msg_count","sms.address AS address","sms.date AS date"};//查询短信数据private void startQuery() {/*** 查询会话数据* token Sql id 查询结果的唯一标识  _ID * cookie  用来传递数据  通常VIEW* uri 	指定查询数据的地址* projection	相当于SQL查询中 select 中的字段  * selection 	相当于SQL查询中 where id = ? * selectionArgs ?* orderBy 		排序*/Uri uri = Uri.parse("content://sms/conversations/");queryHandler.startQuery(0, null, uri, PROJECTION, null, null, " date DESC");}//异步查询框架 AsyncQueryHandlerprivate class QueryHandler extends AsyncQueryHandler{public QueryHandler(ContentResolver cr) {super(cr);}@Overrideprotected void onQueryComplete(int token, Object cookie, Cursor cursor) {super.onQueryComplete(token, cookie, cursor);			//更新数据(adapter 完成数据更新)adapter.changeCursor(cursor);			}}    private class ConversationAdapter extends CursorAdapter{private ViewHolder holder;private long fristSecondOfToday;private GetHeadImg gethead;public ConversationAdapter(Context context, Cursor c) {super(context, c);//今天时间00:00:00Time time = new Time();time.setToNow();time.hour = 0;time.minute = 0;time.second = 0;//精准的时间 false		精准的日期  truefristSecondOfToday = time.toMillis(false);gethead = new GetHeadImg(context);}//在adapter第一次适配的时候调用, 加载布局,找到控件@Overridepublic View newView(Context context, Cursor cursor, ViewGroup parent) {View view = View.inflate(getApplicationContext(), R.layout.conversation_item, null);holder = new ViewHolder();holder.header = (ImageView) view.findViewById(R.id.iv_conversation_item_img);holder.tv_address = (TextView) view.findViewById(R.id.tv_conversation_item_name);holder.tv_body = (TextView) view.findViewById(R.id.tv_conversation_item_content);holder.tv_date = (TextView) view.findViewById(R.id.tv_conversation_item_place);view.setTag(holder);return view;}//将数据适配到控件上@Overridepublic void bindView(View view, Context context, Cursor cursor) {//找到控件holder = (ViewHolder) view.getTag();ImageView header = holder.header;TextView tv_address = holder.tv_address;TextView tv_body = holder.tv_body;TextView tv_date = holder.tv_date;//找到数据/**"sms.thread_id AS thread_id","sms.body AS snippet","groups.msg_count AS msg_count","sms.address AS address","sms.date AS date"*/final String idStr = cursor.getString(ID_COLUMN_INDEX);String body = cursor.getString(SNIPPET_COLUMN_INDEX);int msg_count = cursor.getInt(MSG_COUNT_COLUMN_INDEX);final String address = cursor.getString(ADDRESS_COLUMN_INDEX);long date = cursor.getLong(DATE_COLUMN_INDEX);			//根据电话号码 查询出联系人的信息(名称)String name = null;Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address));Cursor concatCursor = getContentResolver().query(uri, CONCAT_PROJECTION, null, null, null);if(concatCursor.moveToFirst()){//查询到了联系人name = concatCursor.getString(DISPLAY_NAME_COLUMN_INDEX);}concatCursor.close();			//处理短息时间String dateStr = null;if((date - fristSecondOfToday) > 0 && (date - fristSecondOfToday) < DateUtils.DAY_IN_MILLIS){//今天的信息	时间dateStr = DateFormat.getTimeFormat(getApplicationContext()).format(date);				} else {//日期dateStr = DateFormat.getDateFormat(getApplicationContext()).format(date);}//----------------------------------------//将数据适配到控件上			//适配联系人名称、短信的数量if(name != null){//查询到了联系人Bitmap bitmap= gethead.getHeadImage(address);if(bitmap != null ){header.setVisibility(View.VISIBLE);header.setImageBitmap(bitmap);			}else{
//					header.setImageResource(R.drawable.ic_headdefault);		header.setVisibility(View.INVISIBLE);}if(msg_count > 1){tv_address.setText(name + "("+ msg_count +")");} else {tv_address.setText(name);}			} else {//没有查询到header.setVisibility(View.INVISIBLE);if(msg_count > 1){tv_address.setText(address + "("+ msg_count +")");} else {tv_address.setText(address);}}			//设置日期\内容tv_date.setText(dateStr);			if(body.length()>8){body = body.substring(0, 8)+"...";}tv_body.setText(body);view.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(ConversationActivity.this,TalkingActivity.class);intent.putExtra("number", address);intent.putExtra("thread_id", idStr);startActivity(intent);	}});}}private static class ViewHolder {ImageView header;TextView tv_address;TextView tv_body;TextView tv_date;}}

这个使用的是异步查询,如果没有使用过的没有需要花点时间理解一下,使用过的话就简单啦

其中数据库表中是没有联系人的名字的,都是电话号码,那我们需要拿着这个电话号码去联系人数据库查询是否有这个联系人,如果有这个联系人,我们就显示把名字拿过来显示,如果没有就还是显示电话号码。

另外一个就是时间,数据库存储的时间是long类型的,我们拿到数据后需要转化成我们需要的时间,如果是当天发送过来的,那我们是要显示  几时几分就行了,但是如果是昨天发过来的,那我们要显示几月几号。一个小算法,在代码里可以自己看一下哦,其他没有什么难点了。



接下来就是详细页面的开发了,我们点击item的时候把id和电话号码(可带可不带,过去后根据id查询数据库也是可以拿到的)都带到下一个activity中。

看看下一个页面的activity的代码吧

package com.xiaoxu.message;import java.util.ArrayList;
import java.util.List;import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.WindowManager;
import android.widget.ListView;import com.xiaoxu.message.adapter.DetailAdapter;
import com.xiaoxu.message.bean.DetailEntity;public class TalkingActivity extends Activity
{private ListView talkView;private List<DetailEntity> list = null;public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);setContentView(R.layout.activity_talk);listInit();}public void listInit(){talkView = (ListView) findViewById(R.id.list);list = new ArrayList<DetailEntity>();//		DetailEntity d1 = new DetailEntity("私念", "2010-11-11", "你好!",
//				R.layout.list_say_me_item);
//		list.add(d1);//获取到电话号码Intent intent = getIntent();		String number = intent.getStringExtra("number");String thread_id = intent.getStringExtra("thread_id");getSmsAndSendBack(thread_id);talkView.setAdapter(new DetailAdapter(TalkingActivity.this, list));// 去掉分割线talkView.setDivider(null);}public String getSmsAndSendBack(String thread_id) { String[] projection = new String[] { "_id", "address", "person", "body", "type","date"}; StringBuilder str=new StringBuilder(); try{ Cursor myCursor = managedQuery(Uri.parse("content://sms"), projection, "thread_id=?", new String[]{thread_id} , "date desc"); str.append(processResults(myCursor));   } catch (SQLiteException ex) { ex.printStackTrace();} return str.toString(); } private StringBuilder processResults(Cursor cur) { StringBuilder sb=new StringBuilder(); if (cur.moveToFirst()) {   	 String name;  String phoneNumber;        String sms; int type; int nameColumn = cur.getColumnIndex("person"); int phoneColumn = cur.getColumnIndex("address"); int smsColumn = cur.getColumnIndex("body"); int typeColum = cur.getColumnIndex("type"); long date = cur.getLong(5);String dateStr = DateFormat.getDateFormat(getApplicationContext()).format(date);do { // Get the field values  name = cur.getString(nameColumn);              phoneNumber = cur.getString(phoneColumn); sms = cur.getString(smsColumn); type = cur.getInt(typeColum); if(type == 1){DetailEntity d1 = new DetailEntity(name, dateStr, sms,R.layout.list_say_he_item);list.add(d1);	            	 }else{DetailEntity d1 = new DetailEntity(name, dateStr, sms,R.layout.list_say_me_item);list.add(d1);	      	 }System.out.println("name="+name+"type="+type+"phoneNumber="+phoneNumber+"sms="+sms); System.out.println(".................................."); sb.append("{"); sb.append(name+","); sb.append(phoneNumber+","); sb.append(sms); sb.append("}"); if (null==sms) sms=""; } while (cur.moveToNext()); } else { sb.append("no result!"); } return sb; } 
}

其中 OnCreate()中的

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

这句代码起的作用是当我们点击输入框时,让输入框不被弹出的键盘挡住,而是浮到键盘的上方

这里面也有发送短信的功能,上一篇博客已经详细介绍了,直接抄过来就好了

这里需要使用一个适配器

package com.xiaoxu.message.adapter;import java.util.List;import android.app.AlertDialog;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.TextView;import com.xiaoxu.message.R;
import com.xiaoxu.message.bean.DetailEntity;/*** 适配器* * @author Administrator* */
public class DetailAdapter implements ListAdapter
{private List<DetailEntity> coll;private Context ctx;// 消息DetailEntity entity;LinearLayout layout;// 加载布局LayoutInflater vi;// ------------------------------// 背景LinearLayout layout_bj;TextView tvName;TextView tvDate;TextView tvText;public DetailAdapter(Context context, List<DetailEntity> coll){ctx = context;this.coll = coll;}public boolean areAllItemsEnabled(){return true;}/*** 为true监听Item*/public boolean isEnabled(int arg0){return true;}public int getCount(){return coll.size();}public Object getItem(int position){return coll.get(position);}public long getItemId(int position){return position;}public int getItemViewType(int position){return position;}public View getView(int position, View convertView, ViewGroup parent){entity = coll.get(position);int itemLayout = entity.getLayoutID();// 加载布局layout = new LinearLayout(ctx);vi = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);vi.inflate(itemLayout, layout, true);layout.setBackgroundColor(0xffB4B4B4);// 图片背景layout_bj = (LinearLayout) layout.findViewById(R.id.layout_bj);tvName = (TextView) layout.findViewById(R.id.messagedetail_row_name);tvName.setText(entity.getName());tvDate = (TextView) layout.findViewById(R.id.messagedetail_row_date);tvDate.setText(entity.getDate());tvText = (TextView) layout.findViewById(R.id.messagedetail_row_text);tvText.setText(entity.getText());// 添加监听addListener(tvName, tvDate, tvText, layout_bj);return layout;}public int getViewTypeCount(){return coll.size();}public boolean hasStableIds(){return true;}public boolean isEmpty(){return true;}@Overridepublic void registerDataSetObserver(DataSetObserver observer){}@Overridepublic void unregisterDataSetObserver(DataSetObserver observer){}/*** 内容监听* * @param convertView*/public void addListener(final TextView tvName, final TextView tvDate,final TextView tvText, LinearLayout layout_bj){layout_bj.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){}});layout_bj.setOnLongClickListener(new OnLongClickListener(){@Overridepublic boolean onLongClick(View v){tvName.setTextColor(0xffffffff);tvDate.setTextColor(0xffffffff);tvText.setTextColor(0xffffffff);new AlertDialog.Builder(ctx).setTitle("当前是长按操作").setMessage("准备写个菜单").create().show();return true;}});// 按下改变字体颜色layout_bj.setOnTouchListener(new OnTouchListener(){@Overridepublic boolean onTouch(View v, MotionEvent event){switch (event.getAction()){case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:tvName.setTextColor(0xffffffff);tvDate.setTextColor(0xffffffff);tvText.setTextColor(0xffffffff);break;default:tvName.setTextColor(0xff000000);tvDate.setTextColor(0xff000000);tvText.setTextColor(0xff0000ff);break;}return false;}});}
}

当然还有一个工具类,根据用户的电话号码去查询头像

package com.xiaoxu.message.util;import java.io.InputStream;import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.ContactsContract;public class GetHeadImg {private  Context context;@SuppressWarnings("static-access")public GetHeadImg(Context context) {this.context = context;}public  Bitmap getHeadImage(String strPhoneNumber){//通话电话号码获取头像uriUri uriNumber2Contacts = Uri.parse("content://com.android.contacts/"+ "data/phones/filter/" + strPhoneNumber);Cursor cursorCantacts = context.getContentResolver().query(uriNumber2Contacts, null, null,null, null);if (cursorCantacts.getCount() > 0) {	//若游标不为0则说明有头像,游标指向第一条记录cursorCantacts.moveToFirst();Long contactID = cursorCantacts.getLong(cursorCantacts.getColumnIndex("contact_id"));Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactID);InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri);return BitmapFactory.decodeStream(input);} else {//么有头像设置默认头像return null;}}}

用到的两个javaBean。这两个之所以最后才放上来是因为这个没有逻辑,不影响我们的理解

(在里面我有些字段目前没有使用,是考虑到以后可能会使用到,所以没有删除)

package com.xiaoxu.message.bean;public class Conversation {private String imgpath;private String name; private String number;//对应canonical 表中的 addressprivate int num;private String content;//对应thread表中snippetprivate long time;  //对应thread表中 dateprivate String city;public String getImgpath() {return imgpath;}public void setImgpath(String imgpath) {this.imgpath = imgpath;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getNum() {return num;}public void setNum(int num) {this.num = num;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}}

package com.xiaoxu.message.bean;/*** 消息实体类* * @author Administrator* */
public class DetailEntity
{// 短信联系人private String name;// 短信日期private String date;// 短信内容private String text;// 布局IDprivate int layoutID;public String getName(){return name;}public void setName(String name){this.name = name;}public String getDate(){return date;}public void setDate(String date){this.date = date;}public String getText(){return text;}public void setText(String text){this.text = text;}public int getLayoutID(){return layoutID;}public void setLayoutID(int layoutID){this.layoutID = layoutID;}public DetailEntity(){}public DetailEntity(String name, String date, String text, int layoutID){super();this.name = name;this.date = date;this.text = text;this.layoutID = layoutID;}}

最后,大家是否发现,这个页面和上一个页面都有使用到发送短信,注册广播接收回执,等等一些内容,那我们要对他们进行一下优化,不能在每个页面里都要写的话,那工作量实在就太大了,下一篇博文会介绍下如何去优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31105.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chatgpt赋能python:Python自动化:如何用Python完成自动化任务

Python自动化&#xff1a;如何用Python完成自动化任务 随着技术的进步&#xff0c;自动化已经成为了许多企业和团队的必备工具。自动化可以帮助你节省大量时间和精力&#xff0c;也能帮助你提高工作效率。在这方面&#xff0c;Python是一种强大的工具语言&#xff0c;许多人都…

LLM系列 | 16: 如何基于LangChain打造联网版ChatGPT?

简介 连雨不知春去&#xff0c;一晴方觉夏深。 小伙伴们好&#xff0c;我是微信公众号《小窗幽记机器学习》的小编&#xff1a;卖锅盔的小男孩。汇总下之前撰写的ChatGPT Prompt工程和应用系列文章&#xff1a; 11:LangChain危矣&#xff1f;亲测ChatGPT函数调用功能&#…

【9】数据可视化:基于 Echarts + Python 实现的动态实时大屏 - 酒店行业

目录 精彩案例汇总 效果展示 1、动态效果图 2、实时分片数据图 3、丰富的背景样式 一、 确定需求方案 1、确定产品上线部署的屏幕LED分辨率 2、功能模块 3、部署方式&#xff1a; 二、整体架构设计 三、编码实现 &#xff08;基于篇幅及可读性考虑&#xff0c;此处展…

pyecarts动态交互图表-可视化大屏

早在几年前动态可交互的图表已经流行&#xff0c;在各公司前台、大厅都展示着漂亮的可视化大屏&#xff0c;本文简单介绍一个简单好用的动态可交互图表工具-pyecharts&#xff0c;并使用pyecharts制作一个简单的图表大屏&#xff0c;先附上部分动图效果&#xff1a; gif动图 附…

秀一波酷炫可视化大屏!

开局一张图&#xff0c;社会人小猪佩奇镇楼&#xff01; 开局两张图&#xff0c;你永远无法想到的效果&#xff0c;竟然是用帆软大屏模板实现的&#xff01; 开局三张图&#xff0c;带自动播放效果及3D动画特效的数据可视化&#xff01; 开局五张图&#xff0c;离屏内容交互&am…

Unity+chatgpt+webgl实现声音录制+语音识别

一、前言 AI二次元女友这个项目持续更新&#xff0c;在window端的语音识别和语音合成的功能&#xff0c;在上一篇博文里已经详细说明了微软Azure语音服务的代码实现。也是为了实现一次代码&#xff0c;多端复用这样的诉求&#xff0c;所以全部的代码实现都改成了web api的方式…

OpenAI CEO中国首次演讲,称未来十年出现超强AI系统!AGI安全治理是重点

来源 | 新智元 硅谷独角兽&#xff0c;又来震撼世界了&#xff01; 这支名叫Character Technologies的独角兽的核心力量&#xff0c;来自前谷歌LaMDA团队。 大模型研究测试传送门 GPT-4传送门&#xff08;免墙&#xff0c;可直接测试&#xff0c;遇浏览器警告点高级/继续访问…

首周下载量碾压ChatGPT!谷歌20年老员工叛逃,创立第二个OpenAI?

来自&#xff1a;新智元 进NLP群—>加入NLP交流群 【导读】这款爆火的AI聊天新宠&#xff0c;首周下载量就碾压了ChatGPT。更有意思的是&#xff0c;产品背后的独角兽&#xff0c;就是谷歌的前LaMDA团队。婉拒劈柴&#xff0c;出走谷歌&#xff0c;这是要走向人生巅峰了&…

韩启德院士:关于生死,我向ChatGPT提了一个问题

来源&#xff1a;学术世界 图源&#xff1a;pexels 第五届北京大学清明论坛今天开幕了&#xff0c;我衷心祝贺&#xff01; 前四届论坛都取得了成功&#xff0c;讨论越来越深入&#xff0c;社会影响越来越广泛。人们对死亡由忌讳到热议&#xff0c;实质是大家对生命和人生意…

如何从零开始构建一个网络讨论帖分类模型?

Motivation 前几天搭建了一个对牛客网每天最新的工作信息进行爬取的程序&#xff0c;见牛客网爬虫&#xff0c;但从网上爬取下来的帖子有很多不是工作信息&#xff0c;需要把这部分干扰信息给排除掉&#xff0c;否则很影响使用心情。之前使用关键词与正则表达式进行了简单过滤…

chatgpt赋能python:Python画图设置指南

Python画图设置指南 引言 Python是一种高级编程语言&#xff0c;在数据科学及数据可视化领域中越来越受欢迎。Python拥有众多的绘图库&#xff0c;例如matplotlib和seaborn。但是&#xff0c;你需要花费时间和精力在图的布局、颜色、字体等方面的调整上&#xff0c;以提高图表…

今日份安利:智能写诗的软件哪个好?

在传统的文学领域中&#xff0c;诗歌是一种高度艺术化的表达方式。然而&#xff0c;在科技的加持下&#xff0c;AI写诗生成器已经成为了一种新的创作方式。这些机器人诗人可以从大量的语料库中学习和理解诗歌的结构和意义&#xff0c;进而生成出令人惊叹的诗歌作品。对于那些渴…

川核灵境|三月AIGC新品热潮,AI 2.0时代已扑面而来

在元宇宙、Web3.0等概念风靡的2022年&#xff0c;AI凭借“创作”强势崛起&#xff0c;这预示着AIGC元年已经开启&#xff0c;下一个万亿赛道即将爆发。2023年&#xff0c;将是AIGC与Web3、元宇宙密切结合并将爆发的一年。三月再次迎来AIGC新品热潮&#xff0c;一场资本的盛宴正…

GPT Demo 分享|日不落直播间接入虚拟人AI互动

摘要 虚拟人和数字人是人工智能技术在现实生活中的具体应用&#xff0c;它们可以为人们的生活和工作带来便利和创新。在直播间场景里&#xff0c;虚拟人和数字人可用于直播主播、智能客服、营销推广等。接入GPT的虚拟人像是加了超强buff&#xff0c;具备更强大的自然语言处理能…

虚拟数字人成短视频/直播主阵地,虚拟人提升数字内容生产效率

由于短视频在传播便携性、功能性和交互性等多个方面的优势&#xff0c;短视频已逐渐成为现代社会情感表达和信息传播的重要载体。尤其随着移动互联网的普及和碎片化信息迅捷传播需求的高涨&#xff0c;各行各业的内容创作者纷纷涌入视频内容赛道&#xff0c;短视频成为了许多企…

AI数字人主播营销崛起,李佳琦还能继续保持领先地位吗?

“你们能想象我们的客户1万多平方米办公室只剩下几千个数字人在通宵直播吗&#xff1f;一个晚上赚几百万&#xff0c;基本上成本一晚上就赚回来了。”这是一名网友对数字人的发言。 随着今年ChatGPT掀起的人工智能大模型热潮&#xff0c;数字人又迎来一轮更加磅礴的爆发&#…

chatgpt赋能python:Python并行线程介绍:提高程序运行效率

Python并行线程介绍&#xff1a;提高程序运行效率 概述 随着计算机硬件的发展&#xff0c;越来越多的应用需要充分利用计算机的资源来提高程序运行效率。并行计算通过同时使用多个计算资源&#xff08;如CPU或GPU&#xff09;来加速计算过程。Python语言作为一种高效、易读易…

上市公司高管CEO员工数据大全 1991-2021年上市公司高管CEO教育背景学历结构薪酬职务任期年龄出生地 员工学历结构人员结构

&#xff08;1&#xff09;上市公司高管教育背景、学历结构&#xff0c;且含有多份不同来源的100多万数据集&#xff1b;包含 简历、出生地、年龄、教育背景、学历结构、薪酬、职务、股权期权等 &#xff08;2&#xff09;上市公司CEO教育背景、学历结构数据集&#xff0c;包含…

2004-2020中小企业板上市公司财务报表股票交易董事高管等面板数据

1200变量&#xff01;中小企业板上市公司面板数据大全 2004-2020年 1、时间&#xff1a;2004-2020年 2、数据范围&#xff1a;共计973家上市公司 3、数据指标&#xff1a;包括财务报表、股票交易、董事高管等1200变量 4、用途&#xff1a;进行上市公司高管股权激励与公司绩…

【AI实战】快速搭建中文 Alpaca 33B 大模型 Chinese-Alpaca-33B

【AI实战】快速搭建中文 Alpaca 33B 大模型 Chinese-Alpaca-33B 中文 33B 大模型 Chinese-Alpaca-33B环境配置搭建过程1.拉取 chinese-alpaca-lora-33b2.合并lora权重3.llaa.cpp量化模型准备模型权重转换为ggml的FP16格式对FP16模型进行4-bit量化 测试参考 中文 33B 大模型 Chi…