android聊天,存储聊天记录sqlite

时间:2022-09-02 13:39:50

项目中有聊天模块,需要用到打开activity的时候初始化聊天记录的情况。大致情况如下:

辅助类:ChatSQLiteHelper   在第一次时会调用oncreate方法(判断的标准是schedule.db里面会存储是否已经新建过,若没有,则会调用onCreate,只会调用一次)

package com.example.qurenwu.chat;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory; public class ChatSQLiteHelper extends SQLiteOpenHelper{
//调用父类构造器
public ChatSQLiteHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
} /**
* 当数据库首次创建时执行该方法,一般将创建表等初始化操作放在该方法中执行.
* 重写onCreate方法,调用execSQL方法创建表
* */
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE chat (id INTEGER PRIMARY KEY,"+
"user_id varchar(64), "+
"friend_id varchar(64), "+
"contentChat varchar(255), typeChat varchar(8), "+
"postdateChat DATETIME, "+
"isreadChat integer,"+
"ismineChat integer NOT NULL DEFAULT (0),"+
"deleteChat integer);");
} //当打开数据库时传入的版本号与当前的版本号不同时会调用该方法
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
} }

以下是使用方法(由于赶时间,下面的代码都是在activity中的页面代码中)

package com.example.qurenwu.qurenwu_2.chat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast; import com.example.qurenwu.qurenwu_2.R;
import com.example.qurenwu.qurenwu_2.custom.GotaskGlobalVal;
import com.example.qurenwu.qurenwu_2.thread.UserHttpThread; import org.json.JSONException;
import org.json.JSONObject; public class ChatPageActivity extends Activity implements OnClickListener{ private ImageView back;
private Button mBtnSend;
private EditText mEditTextContent;
private ListView mTalkView;
private ChatMsgAdapter mAdapter;
private List<ChatMsgEntity> mDataArrays = new ArrayList<ChatMsgEntity>();
private GotaskGlobalVal globalVal; UserHttpThread userHttpThread;
private String myuser_id,friend_id;
private String friend_head_image_url; //对方头像
private String my_head_image_url; //我的头像 DisplayMetrics dm;
int dmwidth;
SocketThread st;
public DataInputStream dis = null;
public DataOutputStream dos = null;
Handler handler;
SQLiteOpenHelper openHelper; private final int REV_MSG = 1; //接收消息
private final int REQUEST_MINE_HEADURL = 2; //获取我的头像url
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_page); getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); //软键盘
//获取手机屏幕像素
dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
dmwidth = dm.widthPixels; globalVal = (GotaskGlobalVal) getApplicationContext();
back = (ImageView)findViewById(R.id.back);
back.setOnClickListener(this);
//接收好友对象资料
Intent intent = getIntent();
friend_id = intent.getStringExtra("friend_id");
friend_head_image_url = intent.getStringExtra("friend_head_image"); //获取对方头像url
my_head_image_url = intent.getStringExtra("my_head_image"); //获取自己头像url
Log.v("获取头像:","对方头像"+friend_head_image_url+";我的头像:"+my_head_image_url);
myuser_id = globalVal.GetUserID();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case REV_MSG://处理接收到的消息
String str = msg.obj.toString();
try
{
int forend = str.indexOf(config.PROTOCOL_FOR_END);
//解析str
if(forend>0) {
String fromname = str.substring(str.indexOf(config.PROTOCOL_COME) + 1, str.indexOf(config.PROTOCOL_COME_END));
String forname = str.substring(str.indexOf(config.PROTOCOL_FOR) + 1, str.indexOf(config.PROTOCOL_FOR_END));
String _date = str.substring(str.indexOf(config.PROTOCOL_DATE) + 1, str.indexOf(config.PROTOCOL_DATE_END));
String forchat = str.substring(str.indexOf(config.PROTOCOL_DATE_END) + 1);
ChatMsgEntity entity = new ChatMsgEntity();
entity.setDate(_date);
entity.setName(fromname);
entity.setText(forchat);
entity.setMsgType(true);
mDataArrays.add(entity);
mAdapter.notifyDataSetChanged();
mTalkView.setSelection(mDataArrays.size()-1);
Log.v("Handle接收到的消息",forchat);
}
}
catch (Exception ex)
{}
break;
case REQUEST_MINE_HEADURL:
break;
}
}
};
initView();
//1、从本地sqlite数据库获取历史数据
//首次进入,先把聊天记录调出
initdb();
readChat();
//2、socket连接服务器
chatContent();
new Thread(new ReceiveThread()).start();
} //初始化界面
public void initView() {
mTalkView = (ListView) findViewById(R.id.listview);
mBtnSend = (Button) findViewById(R.id.btn_send);
mBtnSend.setOnClickListener(this);
mEditTextContent = (EditText) findViewById(R.id.et_sendmessage);
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.back:
openHelper.close();
finish();
break;
case R.id.btn_send:
send();
break;
}
} @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& ((FaceRelativeLayout) findViewById(R.id.FaceRelativeLayout))
.hideFaceView()) {
Log.v("onKeyDown","表情FaceRelativeLayout");
return true;
}
return super.onKeyDown(keyCode, event);
} private void send() {
String contString = mEditTextContent.getText().toString();
//更新界面
if (contString.length() > 0) {
ChatMsgEntity entity = new ChatMsgEntity();
entity.setDate(getDate());
entity.setMsgType(false);
entity.setText(contString);
entity.setHeadImg(my_head_image_url);
mDataArrays.add(entity);
mAdapter.notifyDataSetChanged();
mEditTextContent.setText("");
mTalkView.setSelection(mTalkView.getCount() - 1);
}
//发送socket消息
DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String date = df.format(new Date());
try {
if(dos!=null){
dos.writeUTF(config.PROTOCOL_KEY+config.PROTOCOL_FOR + friend_id + config.PROTOCOL_FOR_END
+myuser_id+"end;"+contString);
//将发送的消息存入本地
ContentValues con = new ContentValues();
con.put("fromChat", friend_id);
con.put("nameChat", myuser_id);
con.put("contentChat", contString);
con.put("typeChat", "text");
con.put("postdateChat", date);
con.put("isreadChat", "1");
con.put("ismineChat", "1");
con.put("deleteChat", "0");
//getContentResolver().insert(DataChangeProvider.CONTENT_URI, con); //保存到本地sqlite
SQLiteDatabase db=openHelper.getReadableDatabase();
ContentValues values = new ContentValues();
values.put("user_id",myuser_id);
values.put("friend_id",friend_id);
values.put("contentChat",contString);
values.put("typeChat","text");
values.put("postdateChat",date);
values.put("isreadChat",1);
values.put("ismineChat",1);
db.insert("chat",null,values);
db.close();
}else{
Toast.makeText(ChatPageActivity.this, "连接超时,服务器未开放或IP错误,dos is null", Toast.LENGTH_LONG).show();
} }catch (SocketTimeoutException e) {
System.out.println("连接超时,服务器未开放或IP错误"+e.getMessage());
Toast.makeText(ChatPageActivity.this, "连接超时,服务器未开放或IP错误", Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("连接超时,服务器未开放或IP错误"+e.getMessage());
Toast.makeText(ChatPageActivity.this, "连接超时,服务器未开放或IP错误", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
} private String getDate() {
Calendar c = Calendar.getInstance(); String year = String.valueOf(c.get(Calendar.YEAR));
String month = String.valueOf(c.get(Calendar.MONTH));
String day = String.valueOf(c.get(Calendar.DAY_OF_MONTH) + 1);
String hour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));
String mins = String.valueOf(c.get(Calendar.MINUTE)); StringBuffer sbBuffer = new StringBuffer();
sbBuffer.append(year + "-" + month + "-" + day + " " + hour + ":"
+ mins);
return sbBuffer.toString();
} //子线程连接服务器socket
public void chatContent(){
new Thread(){
public void run ()
{
try {
st = new SocketThread();
st.SocketStart(config.SERVER_IP, config.SERVER_PORT, friend_id);
if(st.isConnected()){
dos = st.getDOS();
dis = st.getDIS();
dos.writeUTF(config.PROTOCOL_KEY+config.PROTOCOL_ONLINE+myuser_id);
dos.flush();
dos.writeUTF(config.PROTOCOL_KEY+config.PROTOCOL_WAIT+myuser_id);
dos.flush();
}
}catch (UnknownHostException e) {
System.out.println("连接失败");
Toast.makeText(ChatPageActivity.this, "连接失败", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}catch (SocketTimeoutException e) {
System.out.println("连接超时,服务器未开放或IP错误");
Toast.makeText(ChatPageActivity.this, "连接超时,服务器未开放或IP错误", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}catch (IOException e) {
System.out.println("连接失败");
e.printStackTrace();
}
}
}.start();
}
private class ReceiveThread implements Runnable {
public void run() {
try {
while (true) {
try
{
String str = dis.readUTF();
Message msg = new Message();
msg.what = REV_MSG;
msg.obj = str;
handler.sendMessage(msg);
}
catch (NullPointerException ex)
{}
}
} catch (SocketException e) {
System.out.println("SocketException");
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void RequestUserInfo(String user_id)
{
Map<String,String> param = new HashMap<String, String>();
param.put("datatype","5");
param.put("user_id",user_id);
userHttpThread = new UserHttpThread(handler,param,REQUEST_MINE_HEADURL);
new Thread(userHttpThread).start();
}
private void initdb()
{
//准备数据库,存取聊天记录
openHelper=new ChatSQLiteHelper(this,"chat.db",null,1) ;
}
private void readChat(){
String _date;
String _text;
String _isreadChat;
String _ismineChat; //0:对方的消息 1:自己发送的消息
boolean _isComMeg = true;
//获取数据库中的信息
SQLiteDatabase db=openHelper.getReadableDatabase();
String sql="select contentChat,postdateChat,isreadChat,ismineChat from chat where user_id=? and friend_id=?";
Cursor c = db.rawQuery(sql,new String[]{globalVal.GetUserID(),friend_id});
while(c.moveToNext()){
_text=c.getString(0);
_date=c.getString(1);
_isreadChat=c.getString(2);
_ismineChat=c.getString(3);
Log.v("ceshi", _text+_date+_isreadChat);
ChatMsgEntity entity = new ChatMsgEntity();
entity.setText(_text);
entity.setDate(_date);
if(_ismineChat!=null && _ismineChat.equals("0")){_isComMeg= false;}
entity.setMsgType(_isComMeg);
entity.setHeadImg(_isComMeg?my_head_image_url:friend_head_image_url);
mDataArrays.add(entity);
}
mAdapter = new ChatMsgAdapter(this, mDataArrays,mTalkView);
mTalkView.setAdapter(mAdapter);
mTalkView.setSelection(mTalkView.getCount() - 1);
db.close();
}
}

说一下我当时遇到的问题:

1、sqlite出现no such table chat  ,原因:没有调用ChatSQLiteHelper的Oncreate方法,因为我在activity中有重写了ChatSQLiteHelper的Oncreate方法

如下:

openHelper=new ChatSQLiteHelper(this,"chat.db",null,1) {
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void onCreate(SQLiteDatabase db) {
//这里是空的,什么事情都没做,所以也就不会新建chat表了
}
}

2、出现 android_meta***忘记了,反正纠结在数据库的路径这一块,下面大略写出来对比一下

之前错误的写法:

private SQLiteDatabase openDateBase(String dbFile) //dbFile是我自己命名的一个路径:/data/data/你的报名/databases/chat.db
{
File file = new File(dbFile);
if (!file.exists())
{
// // 打开raw中得数据库文件,获得stream流
InputStream stream = this.mContext.getResources().openRawResource(R.raw.chat); //该目录下也放了一个自己导出来的chat.db,所以不能这么做,自己都晕了
try
{
// 将获取到的stream 流写入道data中
FileOutputStream outputStream = new FileOutputStream(dbFile);
....
}
}
}

现在的写法:

openHelper=new ChatSQLiteHelper(this,"chat.db",null,1) ;  //直接调用,默认ChatSQLiteHelper创建的路径,真实地址应该是:/data/data/你的报名/databases/  这个目录下面

android聊天,存储聊天记录sqlite的更多相关文章

  1. Android数据存储:SQLite

    Android数据存储之SQLite SQLite:Android提供的一个标准的数据库,支持SQL语句.用来处理数据量较大的数据.△ SQLite特征:1.轻量性2.独立性3.隔离性4.跨平台性5. ...

  2. Android数据存储之SQLite数据库

    Android数据存储 之SQLite数据库简介 SQLite的相关知识,并结合Java实现对SQLite数据库的操作. SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎. ...

  3. 【转载】Android数据存储之SQLite

    SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎.它支持大多数的SQL92标准,并且可以在所有主要的操作系统上运行. 在Android中创建的SQLite数据库存储在:/d ...

  4. Android数据存储之SQLite的操作

    Android作为一个应用在移动设备上的操作系统,自然也就少不了数据的存储.然而SQLite作为一个轻型的关系型数据库,基于其轻量.跨平台.多语言接口及安全性等诸多因数考虑,因而Android较大的数 ...

  5. android之存储篇——SQLite数据库

    转载:android之存储篇_SQLite数据库_让你彻底学会SQLite的使用 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在In ...

  6. Android数据存储之SQLite使用

    SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎.它支持大多数的SQL92标准,并且可以在所有主要的操作系统上运行. 在Android中创建的SQLite数据库存储在:/d ...

  7. android数据存储之Sqlite(二)

    SQLite学习笔记 前言:上一章我们介绍了sqlite的一些基本知识以及在dos命令下对sqlite进行的增删改查的操作,这一章我们将在android项目中实际来操作sqlite. 1. SQLit ...

  8. Android数据存储之Sqlite的介绍及使用

    前言: 本来没有打算整理有关Sqlite数据库文章的,最近一直在研究ContentProvider的使用,所有觉得还是先对Sqlite进行一个简单的回顾,也方便研究学习ContentProvider. ...

  9. Android 数据存储之 SQLite数据库存储

    ----------------------------------------SQLite数据库---------------------------------------------- SQLi ...

随机推荐

  1. JavaScript list 去重复

    function unique(arr) { var result = [], hash = {}; for (var i = 0, elem; (elem = arr[i]) != null; i+ ...

  2. 【机器学习】正则化的线性回归 —— 岭回归与Lasso回归

    注:正则化是用来防止过拟合的方法.在最开始学习机器学习的课程时,只是觉得这个方法就像某种魔法一样非常神奇的改变了模型的参数.但是一直也无法对其基本原理有一个透彻.直观的理解.直到最近再次接触到这个概念 ...

  3. django会话

    django会话 可以把会话理解为客户端与服务器之间的一次会晤,在一次会话过程中有多次请求和响应,但是由于HTTP协议的特性-->无状态,每次浏览器的请求都是无状态的,无法保存状态信息,也就是说 ...

  4. Hadoop记录-监控几个思路

    1.存活监控 基本监控,主要对进程的存活.端口连通性.url可检测性等指标进行监控. 2.2 可用性监控 主要指对用户而言是否可用,能否返回预期结果,通常部署在一些业务主流程或一些关键环节,如接口调用 ...

  5. 关联Left Outer Join的第一条记录

    数据准备 CREATE TABLE person (person_id ), lastname )) / INSERT ALL INTO person (person_id, firstname, l ...

  6. 铁乐学python-面向对象的更多说明

    以下内容摘自授课老师的博客http://www.cnblogs.com/Eva-J/ 面向对象的更多说明 面向对象的软件开发 很多人在学完了python的class机制之后,遇到一个生产中的问题,还是 ...

  7. malloc和free的实现

     C++ Code  12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...

  8. 20155309 2016-2017-2《Java程序设计》课程总结

    预备作业1http://www.cnblogs.com/nhx19970709/p/6155580.html 第一次写博客,也是第一次用Markdown,具体流程都还不是很熟悉 预备作业2http:/ ...

  9. Java程序设计9——泛型

    泛型是对集合的补充,JDK1.5增加泛型支持很大程度上都是为了让集合能记住其元素的数据类型.在没有泛型之前,一旦把一个对象丢进Java集合中,集合就会忘记对象的类型,把所有的对象都当成Object类型 ...

  10. &lbrack;转&rsqb;Android Studio常用快捷键

    (会持续更新)这边讲的常用快捷键是指做完Keymap到Eclipse后的,不是纯Android Studio的,这边主要讲下比较常用的一些快捷键: Ctrl+G / Ctrl+Alt+Shift+G: ...