android聊天,存储聊天记录sqlite

项目中有聊天模块,需要用到打开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/  这个目录下面
时间: 2024-08-10 17:20:48

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

Android数据存储之SQLite的操作

Android作为一个应用在移动设备上的操作系统,自然也就少不了数据的存储.然而SQLite作为一个轻型的关系型数据库,基于其轻量.跨平台.多语言接口及安全性等诸多因数考虑,因而Android较大的数据存储采用了SQLite.SQLite与大多数关系型数据库一样都遵循ACID,语法也非常相似.只要您懂得mysql.sqlserver等关系型数据库的操作,只要查看下SQLite的官方文档便可快速上手.SQLite语法您可通过http://sqlite.org/lang.html进行查看. 接下来看

【转载】Android数据存储之SQLite

SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎.它支持大多数的SQL92标准,并且可以在所有主要的操作系统上运行. 在Android中创建的SQLite数据库存储在:/data/data/<包名>/databases/目录下. 主要特点: -轻量级 -独立性,没有不依赖,无需安装 -跨平台,支持众多操作系统 -支持高达2TB大小的数据库 -每个数据库以单个文件的形式存在 -以B-Tree的数据结构形式存储在硬盘 SQLite的数据类型: SQLite支持NULL.

Android数据存储之SQLite使用

SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎.它支持大多数的SQL92标准,并且可以在所有主要的操作系统上运行. 在Android中创建的SQLite数据库存储在:/data/data/<包名>/databases/目录下. 主要特点: -轻量级 -独立性,没有不依赖,无需安装 -跨平台,支持众多操作系统 -支持高达2TB大小的数据库 -每个数据库以单个文件的形式存在 -以B-Tree的数据结构形式存储在硬盘 SQLite的数据类型: SQLite支持NULL.

android之存储篇——SQLite数据库

转载:android之存储篇_SQLite数据库_让你彻底学会SQLite的使用 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值. 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误. 另外, SQLite 在解析CREATE TABLE 语句时

android数据存储之Sqlite(二)

SQLite学习笔记 前言:上一章我们介绍了sqlite的一些基本知识以及在dos命令下对sqlite进行的增删改查的操作,这一章我们将在android项目中实际来操作sqlite. 1. SQLiteDatabase的介绍 Android提供了创建和是用SQLite数据库的API.SQLiteDatabase代表一个数据库对象,提供了操作数据库的一些方法.在 Android的SDK目录下有sqlite3工具,我们可以利用它创建数据库.创建表和执行一些SQL语句.下面是SQLiteDatabas

Android数据存储之SQLite数据库

SQLite是一个小巧的嵌入式数据库,使用方便.开发简单,手机上最早由IOS运用,后来Android也采用了SQLite. SQLite的多数SQL语法与Oracle 一样,下面只列出不同的地方: (1)建表时为避免重复操作,应加上IF NOT EXISTS关键词,例如CREATE TABLE IF NOT EXISTS table_name (2)删表时为避免重复操作,应加上IF EXISTS关键词,例如DROP TABLE IF EXISTS table_name (3)添加新列时使用ALT

android数据存储之Sqlite(一)

SQLite学习笔记 1. Sqlite简介 SQLite是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入 式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了.它能够支持 Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如Tcl.PHP.Java.C++..Net等,还有 ODBC接口,同样比起 Mysql.PostgreSQL这两款开源世界著名的数据库管理系统来讲,它

Android数据存储之Sqlite采用SQLCipher数据库加密实战

前言: 最近研究了Android Sqlite数据库(文章地址:http://www.cnblogs.com/whoislcj/p/5506294.html)以及ContentProvider程序间数据共享(http://www.cnblogs.com/whoislcj/p/5507928.html),我们清晰的知道Sqlite数据库默认存放位置data/data/pakage/database目录下,对于已经ROOT的手机来说的没有任何安全性可以,一旦被利用将会导致数据库数据的泄漏,所以我们该

android 数据存储之SQLite

使用嵌入式关系型SQLite数据库存储数据 除了可以使用文件或SharedPreferences存储数据,还可以选择使用SQLite数据库存储数据. 在Android平台上,集成了一个嵌入式关系型数据库—SQLite, 1.SQLite3支持 NULL.INTEGER.REAL(浮点数字).TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型虽然只有五种,但实际上sqlite3也接受varchar(n).char(n).decimal(p,s) 等数据类型,只不过在运算或保存