项目中有聊天模块,需要用到打开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. Python(2.7.6) 标准日志模块 - Logging Configuration

    除了使用 logging 模块中的 basicConfig 方法配置日志, Python 的 logging.config 模块中, dictConfig 和 fileConfig 方法分别支持通过字 ...

  2. android app性能优化大汇总(google官方Android性能优化典范 - 第2季)

    Google前几天刚发布了Android性能优化典范第2季的课程,一共20个短视频,包括的内容大致有:电量优化,网络优化,Wear上如何做优化,使用对象池来提高效率,LRU Cache,Bitmap的 ...

  3. Part 89 to 91 Talking about pass the parameters in thread

    Part 89   ParameterizedThreadStart delegate Use ParameterizedThreadStart delegate to pass data to th ...

  4. webkit常见问题汇总

    前段时间有人问我一个简单的问题,html如何创建解析的? 我讲了一大堆,什么通过DocumentLoader, CachedResourceLoader, CacheResource, Resourc ...

  5. Exchange 2013 基本部署独立与非独立

    Exchange 2013 基本部署独立与非独立 转载请注明原出处 From yang 先决条件 Active Directory需要准备的,安装Microsoft .NET Framework 4. ...

  6. iOS中—触摸事件详解及使用

    iOS中--触摸事件详解及使用 (一)初识 要想学好触摸事件,这第一部分的基础理论是必须要学会的,希望大家可以耐心看完. 1.基本概念: 触摸事件 是iOS事件中的一种事件类型,在iOS中按照事件划分 ...

  7. 【Unity3D】刚体与碰撞体以及is Trigger属性的意义

    [Unity3D]刚体与碰撞体以及is Trigger属性的意义 刚体:个人理解就是具有物理属性(如:质量),接受物理作用(如:重力)的组件. 碰撞体:个人理解就是计算碰撞后的物理量(如:弹力). 刚 ...

  8. 一个简单的获取参数的jqure

    今天做项目的时候需要用到上一页面传递过来的参数(只要一个参数),其解决办法就是下面: char latter=location.search.split('=')[1] 以上直接获取到第一个参数的值为 ...

  9. dicom格式文件 界定标识符的处理

    转自:http://www.cnblogs.com/assassinx/archive/2013/05/18/3084854.html 说到底无非几个事情 :1传输语法确定 2数据元素读取 3 7fe ...

  10. js动态添加事件

    转载的,但不明确出处 往往我们需要在 JS 中动态添加事件,这就涉及到浏览器兼容性问题了,以下谈及的几种方法,我们也常常混合使用.方法一.setAttributevar obj = document. ...