Android手把手编写儿童手机远程监控App之SQLite详解

0 阅读5分钟

概述

上节详细描述通过Application 类全局获取Context,使得在程序开发中任何地方如Utils、ViewModel、Repository 轻松拿到Context,而不需要层层传递。 在这里插入图片描述

通过两步实现全局Context

  • 创建自定义 Application 类
  • 在 AndroidManifest.xml 中注册 嘟宝app启动,首先生成自定义 Application 类的实力,拿到Context。
public class app extends Application {
    private static Context context;

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }
    public static Context getContext() {
        return context;
    }
}
<application
    android:name=".MyApplication"  <!-- 关键:注册自定义 Application -->
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name">
    
    <!-- 你的 Activity、Service 等组件 -->
    
</application>

可在任何地方,使用app.getContext获取Context。 目前嘟宝完成的功能,开机自动启,启动前台服务建立连接mqtt长连接。通过二维码显示身份识别码(uuid),嘟妈通过二维码扫描绑定。嘟宝收到绑定指令后,发送消息通知栏引导用户确认。 用户绑定信息后,需要将嘟妈信息存储本地。一旦完成绑定,嘟妈可以发送信令,完成麦克、摄像头查看,嘟宝收到信令根本本地存储信息健全,将音视频通过一对一通道发送嘟妈。

SQLite

SQLite 是一款轻量级、零配置、嵌入式的关系型数据库引擎,自 Android 系统诞生之初就被内置支持。它的核心特点包括:

  • 轻量级,完全配置时小于 400KiB可选功能配置时小于 250KiB
  • 零配置,无需安装、无需管理、无需独立的服务器进程
  • 单文件存储,整个数据库存储在一个跨平台的磁盘文件中
  • ACID 兼容,支持原子性、一致性、隔离性、持久性事务
  • SQL 支持,支持 SQL92 标准的大部分查询语言功能
  • 跨平台,可在 Android、iOS、Windows、Linux、macOS 等平台运行 SQLite 的特性使其非常适合移动端应用场景,不需要单独部署数据库服务器,而是以单个存储在每个应用的私有目录中,方便迁移。 在这里插入图片描述

SQLite数据库创建

Android 通过SQLiteOpenHelper类管理数据库。负责数据库的创建与版本管理。嘟宝存储嘟妈绑定信息,表duma设计应包含是以下几个字段

  • id主键,类型
  • dumaName嘟妈别称
  • dumaId嘟妈uuid,嘟妈身份识别码
  • bindDateTime绑定时间 字段名称,字段类型SQLite含有类型
存储类型描述
NULL空值,缺省状态
INTEGER有符号整数
REAL浮点数
TEXT文本字符串
BLOB二进制大对象,按原始字节存储,用于图片文件存储
数据库表,duma创建的SQL语句
CREATE TABLE duma (
  id INTEGER PRIMARY KEY AUTOINCREMENT, 
	dumaName text,
  dumaId text,
  bindDateTime INTEGER
)

id主键自增,bindDateTime 为整数,SQLite没有日期类型。用时间戳作为类型

创建事例

  • 创建类MyDB,继承SQLiteOpenHelper
  • 在MainActivity通过点击按钮创建数据库dubao与表duma 创建类MyDB,如下图 在这里插入图片描述 MyDB类源码
package com.zilong.dubao;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

public class MyDB extends SQLiteOpenHelper {
    public MyDB( String name, SQLiteDatabase.CursorFactory factory,
                int version){
        super(app.getContext(), name, factory, version);


    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        Toast.makeText(app.getContext(),"数据库与表创建成功",Toast.LENGTH_SHORT).show();
        String dumaTabel="CREATE TABLE duma (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, dumaName text,dumaId text,bindDateTime INTEGER)";
        db.execSQL(dumaTabel);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

在MyDB构造函数中,调用父类构造函数 super(app.getContext(), name, factory, version);参数有四

  • Context Android 上下文
  • name,数据库名称
  • factory用于创建查询返回的 Cursor 对象
  • version版本号,用于对数据库升级。 MainActivity源码
package com.zilong.dubao;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
    private MyDB myDB=new MyDB("dubao.db",null,1);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initBtn();
    }
    private void initBtn(){
        Button createDBBtn=findViewById(R.id.createDB);
        createDBBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myDB.getWritableDatabase();

            }
        });
    }
}

运行代码 在这里插入图片描述 当首次点击按钮时,程序调用MyDB onCreate函数,生成数据库dubao,并创建表duma,再次点击时,不再调用,原因在数据库已经创建。 若要引起数据库的创建,需要将构造函数中version版本号增加。

插入数据

MyDB类不变,在MainActivity增加按钮,插入新数据 MainActivity源码

package com.zilong.dubao;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
    private MyDB myDB=new MyDB("dubao.db",null,12);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initBtn();

    }
    private void initBtn(){
        Button createDBBtn=findViewById(R.id.createDB);
        createDBBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myDB.getWritableDatabase();

            }
        });
        Button InsertBtn=findViewById(R.id.insertDB);
        InsertBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db =myDB.getWritableDatabase();
                ContentValues values = new ContentValues();
                values.put("dumaName","嘟妈一号");
                values.put("dumaId","f1122aeb-f2b0-400d-9919-eddd2eaebaa2");
                values.put("dumaName","嘟妈一号");
                values.put("bindDateTime",System.currentTimeMillis());
                db.insert("duma",null,values);

            }
        });

    }
}

运行结果 在这里插入图片描述 点击按钮,插入一条数据。

查新数据

package com.zilong.dubao;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private MyDB myDB=new MyDB("dubao.db",null,12);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initBtn();
    }
    private void initBtn(){
        Button createDBBtn=findViewById(R.id.createDB);
        createDBBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myDB.getWritableDatabase();

            }
        });
        Button insertBtn=findViewById(R.id.insertDB);
        insertBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db =myDB.getWritableDatabase();
                ContentValues values = new ContentValues();
                values.put("dumaName","嘟妈一号");
                values.put("dumaId","f1122aeb-f2b0-400d-9919-eddd2eaebaa2");
                values.put("dumaName","嘟妈一号");
                values.put("bindDateTime",System.currentTimeMillis());
                db.insert("duma",null,values);

            }
        });
        Button queryBtn=findViewById(R.id.queryDB);
        queryBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db =myDB.getWritableDatabase();
                Cursor cursor = db.rawQuery("SELECT * FROM duma", null);
                if (cursor.moveToFirst()){
                    do{
                        @SuppressLint("Range") String dumaName=cursor.getString(cursor.getColumnIndex("dumaName"));
                        @SuppressLint("Range") String dumaId=cursor.getString(cursor.getColumnIndex("dumaId"));
                        Toast.makeText(MainActivity.this,dumaId+dumaName,Toast.LENGTH_SHORT).show();

                    }while (cursor.moveToNext());
                }
               cursor.close();




            }
        });

    }

}

运行结果

在这里插入图片描述

使用SQL操作数据库

虽然Andorid提供非常多的api操作数据,但直接使用SQL语句操作数据库,才是最便捷舒适。 增删改使用db.execSQL(sql),查询使用rawQuery 重新更改MainActivity源码

package com.zilong.dubao;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private MyDB myDB=new MyDB("dubao.db",null,12);
    private int index=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initBtn();
    }
    private void initBtn(){
        Button createDBBtn=findViewById(R.id.createDB);
        createDBBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myDB.getWritableDatabase();

            }
        });
        Button insertBtn=findViewById(R.id.insertDB);
        insertBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db =myDB.getWritableDatabase();
                String sql="";
                sql=String.format("INSERT INTO duma( \"dumaName\", \"dumaId\", \"bindDateTime\") VALUES ( '%s', '%s', '%d');","嘟妈"+index,"999"+index ,System.currentTimeMillis());
                Log.d("mqtt",sql);
                db.execSQL(sql);

            }
        });
        Button queryBtn=findViewById(R.id.queryDB);
        queryBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db =myDB.getWritableDatabase();
                Cursor cursor = db.rawQuery("SELECT * FROM duma", null);
                if (cursor.moveToFirst()){
                    do{
                        @SuppressLint("Range") String dumaName=cursor.getString(cursor.getColumnIndex("dumaName"));
                        @SuppressLint("Range") String dumaId=cursor.getString(cursor.getColumnIndex("dumaId"));
                        @SuppressLint("Range") int bindDateTime=cursor.getInt(cursor.getColumnIndex("bindDateTime"));
                        Toast.makeText(MainActivity.this,dumaId+dumaName+bindDateTime,Toast.LENGTH_SHORT).show();

                    }while (cursor.moveToNext());
                }
                cursor.close();




            }
        });

    }
}