安卓基础学习 Day 27|内容共享

学习要求

在这里插入图片描述

ContentProvide

  • ContentProvide为APP存取内部数据提供统一的外部接口,让不同的应用之间得以共享数据
    在这里插入图片描述
    ClientAPP将用户的输入内容,通过ContentProvide跨进程通信传递给ServerAPP,保存到数据库中。
    ContentProvide不会直接操作数据库或者是文件,数据库会通过调用SQLiteDatabase来操作SQLite.
    请添加图片描述
    ContentProvide相当于一个窗口(门卫),你什么数据允许其他的应用来读取,就写在里面,提供这个接口。

案例

  • 创建两个Module【 server端、client端】
    在这里插入图片描述
    在这里插入图片描述

server端

基于模板创建ContentProvide

  • 命名为UserinfoProvider
  • 主要用于对数据进行增删改查
    在这里插入图片描述
    在这里插入图片描述
  • 新建一个包provider
    在这里插入图片描述
  • UserinfoProvider移动到provider
    在这里插入图片描述

在项目清单文件中修改authorities

  • 写完整类名,最好是复制
    在这里插入图片描述

创建database的包并创建UserDBHelper

  • 主要是用来获取到实例SQLiteDatabase
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class UserDBHelper extends SQLiteOpenHelper {
    private static final String DB_NAME = "user.db";//数据库名称
    private static final String TABLE_NAME = "user_info";//表名称
    private static final int DB_VERSION = 1;//数据库的版本号
    private static UserDBHelper mHelper = null;

    //提供一个子类的构造方法调用父类构造方法
    private UserDBHelper(Context context) {
//第一个参数为:上下文、第二个参数为:数据库名称、第三个参数为:游标、第四个参数为:版本号
        super(context, DB_NAME, null, DB_VERSION);
    }

    //利用单列模式获取数据库帮助器的唯一实例
    public static UserDBHelper getInstance(Context context) {
        if (mHelper == null) {
            mHelper = new UserDBHelper(context);
        }
        return mHelper;
    }

    //onCreate用来创建数据库,执行表语句
    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建表
        String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
                " name VARCHAR NOT NULL," +
                " age INTEGER NOT NULL," +
                " height LONG NOT NULL," +
                " weight FLOAT NOT NULL," +
                " married INTEGER NOT NULL);";
        db.execSQL(sql);
    }

    //更新数据库版本
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}
  • 实例化 dbHelper
    在这里插入图片描述
  • 增加
    在这里插入图片描述

关于uri

Uri(通用资源标识符Universal Resource identifer),代表数据操作的地址,每一个ContentProvider都会有唯一的地址。
ContentProvider使用的Uri语法结构如下:content://authority/data_path/id
content:是通用前缀,表示该Uri用于ContentProvider定位资源。
authority:是授权者名称,用来确定具体由哪一个ContentProvider提供资源。因此一般authority都由类的小写全称组成,以保证唯一性。
data_path:是数据路径,用来确定请求的是哪个数据集。
id:是数据编号,用来请求单条数据。如果是多条这个字段忽略。
  • 查询
    在这里插入图片描述
  • UserinfoProvider的全部代码
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;

import net.lzt.server.database.UserDBHelper;

public class UserinfoProvider extends ContentProvider {

    private UserDBHelper dbHelper;

    @Override
    public boolean onCreate() {
        Log.d("ning", "UserinfoProvider onCreate");
        dbHelper = UserDBHelper.getInstance(getContext());
        return true;
    }

    //增加
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Log.d("ning", "UserinfoProvider insert");
        //拿到SQLiteDatabase
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        db.insert(UserDBHelper.TABLE_NAME, null, values);
        return uri;
    }

    //查询
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        Log.d("ning", "UserinfoProvider query");
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = db.query(UserDBHelper.TABLE_NAME, projection, selection, selectionArgs, null, null, null);
        return cursor;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // Implement this to handle requests to delete one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public String getType(Uri uri) {
        // TODO: Implement this to handle requests for the MIME type of the data
        // at the given URI.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        // TODO: Implement this to handle requests to update one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

client端

基于Empty Activity模板创建ContentWriteActivity

  • 布局资源文件
    这里将之前的shape_edit_focusshape_edit_normaleditext_selector三个xml文件直接复制过来了在这里插入图片描述
<?xml version="1.0" encoding="utf-8"?>
<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:padding="5dp"
    tools:context=".ContentWriteActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="姓名"
            android:textColor="@color/black"
            android:textSize="17dp" />

        <EditText
            android:id="@+id/et_name"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginTop="3dp"
            android:layout_marginBottom="3dp"
            android:layout_weight="1"
            android:background="@drawable/editext_selector"
            android:text="lisa"
            android:inputType="text"
            android:maxLength="12"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="年龄"
            android:textColor="@color/black"
            android:textSize="17dp" />

        <EditText
            android:id="@+id/et_age"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginTop="3dp"
            android:layout_marginBottom="3dp"
            android:layout_weight="1"
            android:background="@drawable/editext_selector"
            android:text="19"
            android:inputType="number"
            android:maxLength="2"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="身高"
            android:textColor="@color/black"
            android:textSize="17dp" />

        <EditText
            android:id="@+id/et_height"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginTop="3dp"
            android:layout_marginBottom="3dp"
            android:layout_weight="1"
            android:background="@drawable/editext_selector"
            android:text="162"
            android:inputType="numberDecimal"
            android:maxLength="3"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="体重"
            android:textColor="@color/black"
            android:textSize="17dp" />

        <EditText
            android:id="@+id/et_weight"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginTop="3dp"
            android:layout_marginBottom="3dp"
            android:layout_weight="1"
            android:background="@drawable/editext_selector"
            android:text="98"
            android:inputType="numberDecimal"
            android:maxLength="5"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>

    <CheckBox
        android:id="@+id/ck_married"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"
        android:gravity="center"
        android:text="已婚"
        android:textColor="@color/black"
        android:textSize="17sp" />

    <Button
        android:id="@+id/btn_save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存"
        android:textColor="@color/black"
        android:textSize="17sp" />

    <Button
        android:id="@+id/btn_read"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="读取"
        android:textColor="@color/black"
        android:textSize="17sp" />

    <Button
        android:id="@+id/btn_delete"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="删除"
        android:textColor="@color/black"
        android:textSize="17sp" />

</LinearLayout>

效果展示

在这里插入图片描述

UserinfoContent

  • 实例化并设置监听并重写onClick方法
    在这里插入图片描述
  • 保存

【这里需要访问ContentProvider需要用到ContentResolve】
通过ContentResolve访问数据
利用ContentProvider只实现服务端App的数据封装,如果客户端App想访问对方的内部数据,就要通过内容解析器ContentResolver访问。
请添加图片描述

  • insert
    请添加图片描述
  • uri
    单独定义一个类UserinfoContent

在这里插入图片描述

  • UserinfoContent 的全部代码
import android.net.Uri;
import android.provider.BaseColumns;

public class UserinfoContent implements BaseColumns {

    public static final String AUTHORITIES = "net.lzt.server.provider.UserinfoProvider";

    //最终访问路径://content://net.lzt.server.provider.UserinfoProvider/user

    //访问内容提供器的URI
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITIES + "/user");


    //构建字段名:该表的各个字段
    public static final String USER_NAME = "name";
    public static final String USER_AGE = "age";
    public static final String USER_HEIGHT = "height";
    public static final String USER_WEIGHT = "weight";
    public static final String USER_MARRIED = "married";
}
  • 获取几个字段并写入一个吐司在这里插入图片描述
  • 读取【查询】

在这里插入图片描述

  • 这里需要构建一个User对象,再讲User对象打印出来

在这里插入图片描述

  • 实体类User的完整代码
public class User {public int id; //序号
    public String name; //姓名
    public int age; //年龄
    public int height; //身高
    public float weight; //体重
    public boolean married; //婚否

    //无参的构造方法
    public User() {

    }

    //有参数的构造方法
    public User(String name, int age, int height, float weight, boolean married) {
        this.name = name;
        this.age = age;
        this.height = height;
        this.weight = weight;
        this.married = married;
    }

    //后面查询
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                ", weight=" + weight +
                ", married=" + married +
                '}';
    }
}
  • ContentWriteActivity 的完整代码
import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class ContentWriteActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText et_name;
    private EditText et_age;
    private EditText et_height;
    private EditText et_weight;
    private CheckBox ck_married;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_content_write);

        et_name = findViewById(R.id.et_name);
        et_age = findViewById(R.id.et_age);
        et_height = findViewById(R.id.et_height);
        et_weight = findViewById(R.id.et_weight);
        ck_married = findViewById(R.id.ck_married);

        //设置监听
        findViewById(R.id.btn_save).setOnClickListener(this);
        findViewById(R.id.btn_read).setOnClickListener(this);
        findViewById(R.id.btn_delete).setOnClickListener(this);
    }


    @SuppressLint("Range")
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            //保存【访问 ContentProvide】//添加
            case R.id.btn_save:
                ContentValues values = new ContentValues();
                values.put(UserinfoContent.USER_NAME, et_name.getText().toString());
                values.put(UserinfoContent.USER_AGE, Integer.parseInt(et_age.getText().toString()));
                values.put(UserinfoContent.USER_HEIGHT, Integer.parseInt(et_height.getText().toString()));
                values.put(UserinfoContent.USER_WEIGHT, Float.parseFloat(et_weight.getText().toString()));
                values.put(UserinfoContent.USER_MARRIED, ck_married.isChecked());
                getContentResolver().insert(UserinfoContent.CONTENT_URI, values);
                Toast.makeText(ContentWriteActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
                break;
            //读取
            case R.id.btn_read:
                Cursor cursor = getContentResolver().query(UserinfoContent.CONTENT_URI, null, null, null, null);
                if (cursor != null) {
                    while (cursor.moveToNext()) {
                        User info = new User();
                        info.id = cursor.getInt(cursor.getColumnIndex(UserinfoContent._ID));
                        info.name = cursor.getString(cursor.getColumnIndex(UserinfoContent.USER_NAME));
                        info.age = cursor.getInt(cursor.getColumnIndex(UserinfoContent.USER_AGE));
                        info.height = cursor.getInt(cursor.getColumnIndex(UserinfoContent.USER_HEIGHT));
                        info.weight = cursor.getFloat(cursor.getColumnIndex(UserinfoContent.USER_WEIGHT));
                        info.married = cursor.getInt(cursor.getColumnIndex(UserinfoContent.USER_MARRIED)) == 1 ? true : false;
                        Log.d("ning", info.toString());
                    }
                    cursor.close();
                }
                break;
        }
    }
}extends AppCompatActivity implements View.OnClickListener {

    private EditText et_name;
    private EditText et_age;
    private EditText et_height;
    private EditText et_weight;
    private CheckBox ck_married;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_content_write);

        et_name = findViewById(R.id.et_name);
        et_age = findViewById(R.id.et_age);
        et_height = findViewById(R.id.et_height);
        et_weight = findViewById(R.id.et_weight);
        ck_married = findViewById(R.id.ck_married);

        //设置监听
        findViewById(R.id.btn_save).setOnClickListener(this);
        findViewById(R.id.btn_read).setOnClickListener(this);
        findViewById(R.id.btn_delete).setOnClickListener(this);
    }


    @SuppressLint("Range")
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            //保存【访问 ContentProvide】//添加
            case R.id.btn_save:
                ContentValues values = new ContentValues();
                values.put(UserinfoContent.USER_NAME, et_name.getText().toString());
                values.put(UserinfoContent.USER_AGE, Integer.parseInt(et_age.getText().toString()));
                values.put(UserinfoContent.USER_HEIGHT, Integer.parseInt(et_height.getText().toString()));
                values.put(UserinfoContent.USER_WEIGHT, Float.parseFloat(et_weight.getText().toString()));
                values.put(UserinfoContent.USER_MARRIED, ck_married.isChecked());
                getContentResolver().insert(UserinfoContent.CONTENT_URI, values);
                Toast.makeText(ContentWriteActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
                break;
            //读取
            case R.id.btn_read:
                Cursor cursor = getContentResolver().query(UserinfoContent.CONTENT_URI, null, null, null, null);
                if (cursor != null) {
                    while (cursor.moveToNext()) {
                        User info = new User();
                        info.id = cursor.getInt(cursor.getColumnIndex(UserinfoContent._ID));
                        info.name = cursor.getString(cursor.getColumnIndex(UserinfoContent.USER_NAME));
                        info.age = cursor.getInt(cursor.getColumnIndex(UserinfoContent.USER_AGE));
                        info.height = cursor.getInt(cursor.getColumnIndex(UserinfoContent.USER_HEIGHT));
                        info.weight = cursor.getFloat(cursor.getColumnIndex(UserinfoContent.USER_WEIGHT));
                        info.married = cursor.getInt(cursor.getColumnIndex(UserinfoContent.USER_MARRIED)) == 1 ? true : false;
                        Log.d("ning", info.toString());
                    }
                    cursor.close();
                }
                break;
        }
    }
}

修改AndroidManifest

在这里插入图片描述

运行效果

【先运行server,然后运行client】
在这里插入图片描述
由运行结果可知在应用启动时就创建了UserinfoProvider

删除

在这里插入图片描述

  • 构建匹配器
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 最终运行效果
    请添加图片描述
    已经实现了增删改查的相关内容
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鲁不吃猪蹄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值