Android自学笔记(二)

SharedPreferences用法:

 ShareWriteActivity.java:

public class ShareWriteActivity 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;
    private Button btn_share;
    private SharedPreferences preferences;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_share_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);
        btn_share = findViewById(R.id.btn_share);
        btn_share.setOnClickListener(this);
        //生成config.xml文件
        preferences = getSharedPreferences("config", Context.MODE_PRIVATE);
        //重新打开app,读取config.xml
        reload();
    }

    private void reload() {
        String name = preferences.getString("name", null);
        if(name != null){
            et_name.setText(name);
        }
        int age = preferences.getInt("age", 0);
        if(age != 0){
            et_age.setText(String.valueOf(age));
        }
        float height = preferences.getFloat("height", 0f);
        if(height != 0f){
            et_height.setText(String.valueOf(height));
        }
        float weight = preferences.getFloat("weight", 0f);
        if(weight != 0f){
            et_weight.setText(String.valueOf(weight));
        }

        boolean married = preferences.getBoolean("married", false);
        ck_married.setChecked(married);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_share:
                String name = et_name.getText().toString();
                String age = et_age.getText().toString();
                String height = et_height.getText().toString();
                String weight = et_weight.getText().toString();

                //获取编辑器
                SharedPreferences.Editor editor = preferences.edit();
                editor.putString("name",name);
                editor.putInt("age", Integer.parseInt(age));
                editor.putFloat("height", Float.parseFloat(height));
                editor.putFloat("weight", Float.parseFloat(weight));
                editor.putBoolean("married",ck_married.isChecked());
                //提交编辑信息
                editor.commit();
                break;
        }
    }
}

 lactivity_share_write.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <TextView
            android:textColor="@color/black"
            android:textSize="18sp"
            android:text="@string/name"
            android:gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>

        <EditText
            android:id="@+id/et_name"
            android:layout_marginTop="3dp"
            android:layout_marginBottom="3dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:background="@drawable/edittest_selector"
            android:hint="@string/input_name"
            android:inputType="text"
            android:textSize="18sp"
            android:textColorHint="@color/grey"/>

    </LinearLayout>

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

        <TextView
            android:textColor="@color/black"
            android:textSize="18sp"
            android:text="@string/age"
            android:gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>

        <EditText
            android:id="@+id/et_age"
            android:layout_marginTop="3dp"
            android:layout_marginBottom="3dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:background="@drawable/edittest_selector"
            android:hint="@string/input_age"
            android:inputType="text"
            android:textSize="18sp"
            android:textColorHint="@color/grey"/>

    </LinearLayout>

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

        <TextView
            android:textColor="@color/black"
            android:textSize="18sp"
            android:text="@string/height"
            android:gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>

        <EditText
            android:id="@+id/et_height"
            android:layout_marginTop="3dp"
            android:layout_marginBottom="3dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:background="@drawable/edittest_selector"
            android:hint="@string/input_height"
            android:inputType="text"
            android:textSize="18sp"
            android:textColorHint="@color/grey"/>

    </LinearLayout>

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

        <TextView
            android:textColor="@color/black"
            android:textSize="18sp"
            android:text="@string/weight"
            android:gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>

        <EditText
            android:id="@+id/et_weight"
            android:layout_marginTop="3dp"
            android:layout_marginBottom="3dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:background="@drawable/edittest_selector"
            android:hint="@string/input_weight"
            android:inputType="text"
            android:textSize="18sp"
            android:textColorHint="@color/grey"/>

    </LinearLayout>

    <CheckBox
        android:id="@+id/ck_married"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/married"
        android:textSize="18sp"
        android:textColor="@color/black"/>

    <Button
        android:id="@+id/btn_share"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/share_preference"/>

</LinearLayout>

 点击保存,在Device File Explorer->data->data->对应的包下->shared_prefs->config.xml,将其保存到本地D盘下

 杀掉当前进程,重新进入,会重新读取config.xml文件信息,并显示在界面中,修改后保存后,xml内信息更新。

总结步骤:

1.获取sharedPreferences对象

2.如果保存密码被勾选(或其他条件满足),获取sharedPreferences的编辑器

3.通过编辑器put每个editTest中填写的值,提交编辑信息(commit)

4.重新进入时,读取上次保存的信息,(如果xml文件中保存密码是被选中的,读取xml文件信息,并set到对应的editTest里)

数据库的创建和删除: (关于数据库操作,后面采用Room框架,这里可不看)

创建:在data/data/对应包下的file文件夹下生成db文件

mDatabaseName = getFilesDir() + "/test.db";
SQLiteDatabase db = openOrCreateDatabase(mDatabaseName, Context.MODE_PRIVATE, null);
desc = String.format("数据库%s创建%s",db.getPath(),(db!=null)?"成功":"失败");
tv_content.setText(desc);

删除:

mDatabaseName = getFilesDir() + "/test.db";
boolean result = deleteDatabase(mDatabaseName);
desc = String.format("数据库%s删除%s",mDatabaseName,result?"成功":"失败");
tv_content.setText(desc);

数据的增删改查

获取读写连接等准备:

//使用单例模式,构造函数用private修饰
    private UserDBHelper(@Nullable Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

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

    //打开数据库的读连接
    public SQLiteDatabase openReadLink(){
        if(mRDB == null || !mRDB.isOpen()){
            mRDB = mHelper.getReadableDatabase();
        }
        return mRDB;
    }

    //打开数据库的读连接
    public SQLiteDatabase openWriteLink(){
        if(mWDB == null || !mWDB.isOpen()){
            mWDB = mHelper.getWritableDatabase();
        }
        return mWDB;
    }

    //关闭数据库连接
    public void closeLink(){
        if(mRDB != null && mRDB.isOpen()){
            mRDB.close();
            mRDB = null;
        }
        if(mWDB != null && mWDB.isOpen()){
            mWDB.close();
            mWDB = null;
        }
    }

    //创建数据库,执行建表语句
    @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 db, int oldVersion, int newVersion) {

    }

添加:

    public long insert(User user){
        ContentValues values = new ContentValues();
        values.put("name",user.name);
        values.put("age",user.age);
        values.put("height",user.height);
        values.put("weight",user.weight);
        values.put("married",user.married);
        //insert(String table, String nullColumnHack, ContentValues values)
        //如果第三个参数values为null或者元素个数为0,由于insert()方法要求必须添加一条除了主键之外其他字段为null值的记录,
        // 如:insert into person() values(),在添加数据时什么值都没给,左边的sql语句不满足标准sql的语法
        //为了满足sql的语法,insert语句必须给定一个字段,则语句变成:insert into person(name) values(NULL)
        //该字段要求为非主键
        //当第三个参数不为null,并且元素个数大于0时,可以把第二个参数设置为null
        return mWDB.insert(TABLE_NAME,null,values);
    }

 删除:

    public long deleteByName(String name){
        //删除所有
        //mWDB.delete(TABLE_NAME,"1=1",null);
        //第三个参数就是第二个参数中的问号,有几个问号,String数组传几个值
        return mWDB.delete(TABLE_NAME,"name = ?",new String[]{name});
    }

更新:

    public long updateByName(User user){
        ContentValues values = new ContentValues();
        values.put("name",user.name);
        values.put("age",user.age);
        values.put("height",user.height);
        values.put("weight",user.weight);
        values.put("married",user.married);
        return mWDB.update(TABLE_NAME,values,"name = ?",new String[]{user.name});
    }

查询:

    public List<User> queryAll(){
        List<User> list = new ArrayList<>();
        //执行记录查询动作,该语句返回结果集的游标
        Cursor cursor = mRDB.query(TABLE_NAME,null,null,null,null,null,null);
        while(cursor.moveToNext()){
            User user = new User();
            user.id = cursor.getInt(0);
            user.name = cursor.getString(1);
            user.age = cursor.getInt(2);
            user.height = cursor.getLong(3);
            user.weight = cursor.getFloat(4);
            //SQLite没有Boolean类型,用0表示false,用1表示true
            user.married = (cursor.getInt(5) != 0);
            list.add(user);
        }
        return list;
    }

    public List<User> queryByName(String name){
        List<User> list = new ArrayList<>();
        //执行记录查询动作,该语句返回结果集的游标
        Cursor cursor = mRDB.query(TABLE_NAME,null,"name = ?",new String[]{name},null,null,null);
        while(cursor.moveToNext()){
            User user = new User();
            user.id = cursor.getInt(0);
            user.name = cursor.getString(1);
            user.age = cursor.getInt(2);
            user.height = cursor.getLong(3);
            user.weight = cursor.getFloat(4);
            //SQLite没有Boolean类型,用0表示false,用1表示true
            user.married = (cursor.getInt(5) != 0);
            list.add(user);
        }
        return list;
    }

事务:

try {
    mWDB.beginTransaction();
    mWDB.insert(TABLE_NAME, null, values);
    int i = 10 / 0;
    mWDB.insert(TABLE_NAME, null, values);
    mWDB.setTransactionSuccessful();
} catch (Exception e) {
    e.printStackTrace();
} finally {
    mWDB.endTransaction();
}

完整代码:

 User.java:

public class User {

    public int id;
    public String name;
    public int age;
    public long height;
    public float weight;
    public boolean married;

    public User(){

    }

    public User(String name, int age, long 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 +
                '}';
    }
}

UserDBHelper.java:

public class UserDBHelper extends SQLiteOpenHelper {

    public static final String DB_NAME = "user.db";
    public static final String TABLE_NAME = "user_info";
    public static final int DB_VERSION = 1;
    public static UserDBHelper mHelper = null;
    private SQLiteDatabase mRDB = null;
    private SQLiteDatabase mWDB = null;

    //使用单例模式,构造函数用private修饰
    private UserDBHelper(@Nullable Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

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

    //打开数据库的读连接
    public SQLiteDatabase openReadLink() {
        if (mRDB == null || !mRDB.isOpen()) {
            mRDB = mHelper.getReadableDatabase();
        }
        return mRDB;
    }

    //打开数据库的读连接
    public SQLiteDatabase openWriteLink() {
        if (mWDB == null || !mWDB.isOpen()) {
            mWDB = mHelper.getWritableDatabase();
        }
        return mWDB;
    }

    //关闭数据库连接
    public void closeLink() {
        if (mRDB != null && mRDB.isOpen()) {
            mRDB.close();
            mRDB = null;
        }
        if (mWDB != null && mWDB.isOpen()) {
            mWDB.close();
            mWDB = null;
        }
    }

    //创建数据库,执行建表语句
    @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 db, int oldVersion, int newVersion) {
        //数据库版本升级
        String sql = "ALTER TABLE "+ TABLE_NAME + " ADD COLUMN phone VARCHAR;";
        db.execSQL(sql);
        sql = "ALTER TABLE "+ TABLE_NAME + " ADD COLUMN password VARCHAR;";
        db.execSQL(sql);
    }

    public long insert(User user) {
        ContentValues values = new ContentValues();
        values.put("name", user.name);
        values.put("age", user.age);
        values.put("height", user.height);
        values.put("weight", user.weight);
        values.put("married", user.married);
        //insert(String table, String nullColumnHack, ContentValues values)
        //如果第三个参数values为null或者元素个数为0,由于insert()方法要求必须添加一条除了主键之外其他字段为null值的记录,
        // 如:insert into person() values(),在添加数据时什么值都没给,左边的sql语句不满足标准sql的语法
        //为了满足sql的语法,insert语句必须给定一个字段,则语句变成:insert into person(name) values(NULL)
        //该字段要求为非主键
        //当第三个参数不为null,并且元素个数大于0时,可以把第二个参数设置为null
        return mWDB.insert(TABLE_NAME,null,values);
    }

    public long deleteByName(String name) {
        //删除所有
//        mWDB.delete(TABLE_NAME,"1=1",null);
        //第三个参数就是第二个参数中的问号,有几个问号,String数组传几个值
        return mWDB.delete(TABLE_NAME, "name = ?", new String[]{name});
    }

    public long updateByName(User user) {
        ContentValues values = new ContentValues();
        values.put("name", user.name);
        values.put("age", user.age);
        values.put("height", user.height);
        values.put("weight", user.weight);
        values.put("married", user.married);
        return mWDB.update(TABLE_NAME, values, "name = ?", new String[]{user.name});
    }

    public List<User> queryAll() {
        List<User> list = new ArrayList<>();
        //执行记录查询动作,该语句返回结果集的游标
        Cursor cursor = mRDB.query(TABLE_NAME, null, null, null, null, null, null);
        while (cursor.moveToNext()) {
            User user = new User();
            user.id = cursor.getInt(0);
            user.name = cursor.getString(1);
            user.age = cursor.getInt(2);
            user.height = cursor.getLong(3);
            user.weight = cursor.getFloat(4);
            //SQLite没有Boolean类型,用0表示false,用1表示true
            user.married = (cursor.getInt(5) != 0);
            list.add(user);
        }
        return list;
    }

    public List<User> queryByName(String name) {
        List<User> list = new ArrayList<>();
        //执行记录查询动作,该语句返回结果集的游标
        Cursor cursor = mRDB.query(TABLE_NAME, null, "name = ?", new String[]{name}, null, null, null);
        while (cursor.moveToNext()) {
            User user = new User();
            user.id = cursor.getInt(0);
            user.name = cursor.getString(1);
            user.age = cursor.getInt(2);
            user.height = cursor.getLong(3);
            user.weight = cursor.getFloat(4);
            //SQLite没有Boolean类型,用0表示false,用1表示true
            user.married = (cursor.getInt(5) != 0);
            list.add(user);
        }
        return list;
    }
}

SQLiteHelperActivity.java:

public class SQLiteHelperActivity extends AppCompatActivity implements View.OnClickListener {

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sqlite_helper);
        et_name = findViewById(R.id.et_name);
        et_age = findViewById(R.id.et_age);
        et_weight = findViewById(R.id.et_weight);
        et_height = findViewById(R.id.et_height);
        ck_married = findViewById(R.id.ck_married);

        findViewById(R.id.btn_add).setOnClickListener(this);
        findViewById(R.id.btn_delete).setOnClickListener(this);
        findViewById(R.id.btn_update).setOnClickListener(this);
        findViewById(R.id.btn_select).setOnClickListener(this);
        findViewById(R.id.btn_reset).setOnClickListener(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        //获取数据库帮助器的实例
        mHelper = UserDBHelper.getInstance(this);
        //打开数据库帮助器的读写连接
        mHelper.openWriteLink();
        mHelper.openReadLink();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mHelper.closeLink();
    }

    @Override
    public void onClick(View v) {
        String name = et_name.getText().toString();
        String age = et_age.getText().toString();
        String height = et_height.getText().toString();
        String weight = et_weight.getText().toString();
        Boolean married = ck_married.isChecked();
        User user = null;
        switch (v.getId()) {
            case R.id.btn_add:
                user = new User(name,
                        Integer.parseInt(age),
                        Long.parseLong(height),
                        Float.parseFloat(weight),
                        married);
                if (mHelper.insert(user) > 0) {
                    ToastUtil.show(this, "添加成功");
                }
                break;
            case R.id.btn_delete:
                if (mHelper.deleteByName(name) > 0) {
                    ToastUtil.show(this, "删除成功");
                }
                break;
            case R.id.btn_update:
                user = new User(name,
                        Integer.parseInt(age),
                        Long.parseLong(height),
                        Float.parseFloat(weight),
                        married);
                if (mHelper.updateByName(user) > 0) {
                    ToastUtil.show(this, "修改成功");
                }
                break;
            case R.id.btn_select:
                List<User> list = mHelper.queryByName(name);
                for(User u : list){
                    Log.d("ning",u.toString());
                }
                break;
            case R.id.btn_reset:
                et_name.setText(null);
                et_age.setText(null);
                et_height.setText(null);
                et_weight.setText(null);
                ck_married.setChecked(false);
                ToastUtil.show(this,"重置成功");
                break;
        }
    }
}
    public static void show(Context context, String desc){
        Toast.makeText(context,desc,Toast.LENGTH_SHORT).show();
    }

对记住密码的优化:

LoginSQLiteActivity.java:

public class LoginSQLiteActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, View.OnClickListener, View.OnFocusChangeListener {

    private RadioGroup rg_login;
    private TextView tv_password;
    private EditText et_password;
    private Button btn_forget;
    private CheckBox ck_remember;
    private EditText et_phone;
    private RadioButton rb_verifycode;
    private RadioButton rb_password;
    private ActivityResultLauncher<Intent> register;
    private Button btn_login;
    private String mPassword="111111";
    private String mVerifyCode;
    private LoginDBHelper mHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login_main);
        rg_login = findViewById(R.id.rg_login);
        rg_login.setOnCheckedChangeListener(this);
        tv_password = findViewById(R.id.tv_password);
        et_password = findViewById(R.id.et_password);
        et_phone = findViewById(R.id.et_phone);
        btn_forget = findViewById(R.id.btn_forget);
        btn_forget.setOnClickListener(this);
        ck_remember = findViewById(R.id.ck_remember);
        et_password.addTextChangedListener(new HideTextWatcher(et_password,6));
        et_phone.addTextChangedListener(new HideTextWatcher(et_phone,11));
        rb_password = findViewById(R.id.rb_password);
        rb_verifycode = findViewById(R.id.rb_verifycode);
        btn_login = findViewById(R.id.btn_login);
        btn_login.setOnClickListener(this);
        register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                Intent intent = result.getData();
                if(intent != null && result.getResultCode() == Activity.RESULT_OK){
                    mPassword = intent.getStringExtra("new_password");
                }
            }
        });
        et_password.setOnFocusChangeListener(this);
    }

    private void reload() {
        LoginInfo info = mHelper.queryTop();
        if(info != null && info.remember){
            et_phone.setText(info.phone);
            et_password.setText(info.password);
            ck_remember.setChecked(true);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        mHelper = LoginDBHelper.getInstance(this);
        mHelper.openReadLink();
        mHelper.openWriteLink();
        reload();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mHelper.closeLink();
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (checkedId) {
            case R.id.rb_password:
                tv_password.setText(getString(R.string.login_password));
                et_password.setHint(getString(R.string.input_password));
                btn_forget.setText(getString(R.string.forget_password));
                ck_remember.setVisibility(View.VISIBLE);
                break;
            case R.id.rb_verifycode:
                tv_password.setText(getString(R.string.verifycode));
                et_password.setHint(getString(R.string.inpout_verifycode));
                btn_forget.setText(getString(R.string.get_verifycode));
                ck_remember.setVisibility(View.GONE);
                break;
        }
    }

    @SuppressLint({"DefaultLocale", "NonConstantResourceId"})
    @Override
    public void onClick(View v) {
        String phone = et_phone.getText().toString();
        if(phone.length()<11){
            Toast.makeText(this,"请输入正确的手机号",Toast.LENGTH_LONG).show();
            return;
        }
        switch(v.getId()){
            case R.id.btn_forget:
                //选择了密码方式校验,此时要跳到找回密码页面
                if (rb_password.isChecked()){
                    Intent intent = new Intent(this, LoginForgetActivity.class);
                    intent.putExtra("phone",phone);
                    register.launch(intent);
                }else if(rb_verifycode.isChecked()){
                    //生成六位数,范围是0-999999,如果生成位数不满6位,用0代替
                    mVerifyCode = String.format("%06d",new Random().nextInt(999999));
                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("请记住验证码");
                    builder.setMessage("手机号"+phone+",本次验证码是"+mVerifyCode+",请输入验证码");
                    builder.setPositiveButton("好的",null);
                    AlertDialog dialog = builder.create();
                    dialog.show();
                }
                break;
            case R.id.btn_login:
                if(rb_password.isChecked()){
                    if (!mPassword.equals(et_password.getText().toString())){
                        Toast.makeText(this,"请输入正确的密码",Toast.LENGTH_LONG).show();
                        return;
                    }
                }else if (rb_verifycode.isChecked()){
                    if(!mVerifyCode.equals(et_password.getText().toString())){
                        Toast.makeText(this,"请输入正确的密码",Toast.LENGTH_LONG).show();
                        return;
                    }
                }
                //提示用户登录成功
                loginSuccess();
                break;
        }
    }

    private void loginSuccess() {
        String desc = String.format("您的手机号码是%s,恭喜你通过登录验证,点击\"确定\"按钮返回上一个页面",et_phone.getText().toString());
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("登录成功");
        builder.setMessage(desc);
        builder.setPositiveButton("确定返回", (dialog, which) -> finish());
        builder.setNegativeButton("我再看看",null);
        AlertDialog dialog = builder.create();
        dialog.show();

        //保存到数据库
        LoginInfo info = new LoginInfo();
        info.phone = et_phone.getText().toString();
        info.password = et_password.getText().toString();
        info.remember = ck_remember.isChecked();
        mHelper.save(info);
    }

    //当密码输入框获取焦点后,根据输入的电话号码,查询出对应的密码,自动填入
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(v.getId() == R.id.et_password && hasFocus){
            LoginInfo info = mHelper.queryByPhone(et_phone.getText().toString());
            if(info != null){
                et_password.setText(info.password);
                ck_remember.setChecked(info.remember);
            }else {
                et_password.setText("");
                ck_remember.setChecked(false);
            }
        }
    }

    //定义一个编辑框监听器,在输入文本达到指定长度时自动隐藏输入法
    private class HideTextWatcher implements TextWatcher {
        private int mMaxLength;
        private EditText mView;

        public HideTextWatcher(EditText v, int maxLength) {
            this.mMaxLength = maxLength;
            this.mView = v;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            String str = s.toString();
            if(str.length() == mMaxLength){
                ViewUtil.hideOneInputMethod(LoginSQLiteActivity.this,mView);
            }
        }
    }
}

LoginDBHelper.java:

public class LoginDBHelper extends SQLiteOpenHelper {

    public static final String DB_NAME = "login.db";
    public static final String TABLE_NAME = "login_info";
    public static final int DB_VERSION = 1;
    public static LoginDBHelper mHelper = null;
    private SQLiteDatabase mRDB = null;
    private SQLiteDatabase mWDB = null;

    //使用单例模式,构造函数用private修饰
    private LoginDBHelper(@Nullable Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

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

    //打开数据库的读连接
    public SQLiteDatabase openReadLink() {
        if (mRDB == null || !mRDB.isOpen()) {
            mRDB = mHelper.getReadableDatabase();
        }
        return mRDB;
    }

    //打开数据库的读连接
    public SQLiteDatabase openWriteLink() {
        if (mWDB == null || !mWDB.isOpen()) {
            mWDB = mHelper.getWritableDatabase();
        }
        return mWDB;
    }

    //关闭数据库连接
    public void closeLink() {
        if (mRDB != null && mRDB.isOpen()) {
            mRDB.close();
            mRDB = null;
        }
        if (mWDB != null && mWDB.isOpen()) {
            mWDB.close();
            mWDB = null;
        }
    }

    //创建数据库,执行建表语句
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
                " phone VARCHAR NOT NULL," +
                " password INTEGER NOT NULL," +
                " remember INTEGER NOT NULL);";
        db.execSQL(sql);
    }

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

    }

    public void save(LoginInfo info) {
        //如果存在则先删除,再添加
        //好处是最近一次登录的永远在最上面
        try {
            mWDB.beginTransaction();
            delete(info);
            insert(info);
            mWDB.setTransactionSuccessful();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mWDB.endTransaction();
        }
    }

    public long delete(LoginInfo info) {
        return mWDB.delete(TABLE_NAME, "phone = ?", new String[]{info.phone});
    }

    public long insert(LoginInfo info) {
        ContentValues values = new ContentValues();
        values.put("phone", info.phone);
        values.put("password", info.password);
        values.put("remember", info.remember);
        return mWDB.insert(TABLE_NAME, null, values);
    }

    public List<User> queryAll() {
        List<User> list = new ArrayList<>();
        //执行记录查询动作,该语句返回结果集的游标
        Cursor cursor = mRDB.query(TABLE_NAME, null, null, null, null, null, null);
        while (cursor.moveToNext()) {
            User user = new User();
            user.id = cursor.getInt(0);
            user.name = cursor.getString(1);
            user.age = cursor.getInt(2);
            user.height = cursor.getLong(3);
            user.weight = cursor.getFloat(4);
            //SQLite没有Boolean类型,用0表示false,用1表示true
            user.married = (cursor.getInt(5) != 0);
            list.add(user);
        }
        return list;
    }

    public LoginInfo queryTop() {
        LoginInfo info = null;
        String sql = "select * from " + TABLE_NAME + " where remember = 1 ORDER BY _id DESC limit 1";
        //执行自己拼接的sql语句
        Cursor cursor = mRDB.rawQuery(sql, null);
        if (cursor.moveToNext()) {
            info = new LoginInfo();
            info.id = cursor.getInt(0);
            info.phone = cursor.getString(1);
            info.password = cursor.getString(2);
            info.remember = (cursor.getInt(3) != 0);
        }
        return info;
    }

    public LoginInfo queryByPhone(String phone) {
        LoginInfo info = null;
        String sql = "select * from " + TABLE_NAME;
        Cursor cursor = mRDB.query(TABLE_NAME, null, "phone = ? and remember = 1", new String[]{phone}, null, null, null);
        if (cursor.moveToNext()) {
            info = new LoginInfo();
            info.id = cursor.getInt(0);
            info.phone = cursor.getString(1);
            info.password = cursor.getString(2);
            info.remember = (cursor.getInt(3) != 0);
        }
        return info;
    }
}

LoginInfo.java: 

public class LoginInfo {

    public int id;
    public String phone;
    public String password;
    public boolean remember = false;

    public LoginInfo(){

    }

    public LoginInfo(String phone, String password, boolean remember) {
        this.phone = phone;
        this.password = password;
        this.remember = remember;
    }

    @Override
    public String toString() {
        return "LoginInfo{" +
                "id=" + id +
                ", phone='" + phone + '\'' +
                ", password='" + password + '\'' +
                ", remember=" + remember +
                '}';
    }
}

存储空间:

外部存储私有空间、外部存储公共空间、内部存储私有空间

 FileActivity.java:

public class FileWriteActivity 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;
    private Button btn_share;
    private String path;
    private TextView tv_text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file_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);
        btn_share = findViewById(R.id.btn_share);
        btn_share.setOnClickListener(this);
        findViewById(R.id.btn_read).setOnClickListener(this);
        tv_text = findViewById(R.id.tv_read);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_share:
                String name = et_name.getText().toString();
                String age = et_age.getText().toString();
                String height = et_height.getText().toString();
                String weight = et_weight.getText().toString();

                StringBuilder sb = new StringBuilder();
                sb.append("姓名:").append(name);
                sb.append("\n年龄:").append(age);
                sb.append("\n身高:").append(height);
                sb.append("\n体重:").append(weight);
                sb.append("\n婚否:").append(ck_married.isChecked()?"是":"否");

                String fileName = System.currentTimeMillis() + ".txt";
                String directory = null;
                //外部存储的私有空间,应用卸载后就没有了
//                directory = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString();
                //外部存储的公共空间,应用卸载还在
//                directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
                //内部存储私有空间
                directory = getFilesDir().toString();
                path = directory + File.separatorChar + fileName;
                Log.d("syf",path);
                FileUtil.saveText(path,sb.toString());
                ToastUtil.show(this,"保存成功");
                break;
            case R.id.btn_read:
                tv_text.setText(FileUtil.openText(path));
                break;
        }
    }
}

 FileUtil.java:

public class FileUtil {

    //把字符串保存到指定路径的文本文件
    public static void saveText(String path, String txt) {
        BufferedWriter os = null;
        try {
            os = new BufferedWriter(new FileWriter(path));
            os.write(txt);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //从指定路径的文本文件中读取内容字符串
    public static String openText(String path) {
        BufferedReader is = null;
        StringBuilder sb = new StringBuilder();
        try {
            is = new BufferedReader(new FileReader(path));
            String line = null;
            while ((line = is.readLine()) != null) {
                sb.append(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}

 保存读取图片:

            case R.id.btn_save:
                String fileName = System.currentTimeMillis() + ".jepg";
                //获取当前APP的私有下载目录
                path = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + File.separatorChar + fileName;
                Log.d("syf",path);
                //从指定的资源文件中获取位图对象
                Bitmap b1 = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap_1);
                FileUtil.saveImage(path,b1);
                ToastUtil.show(this,"保存成功");
                break;
            case R.id.btn_read:
                //
//                Bitmap b2 = FileUtil.openImage(path);
//                ivShow.setImageBitmap(b2);
                //
//                Bitmap b2 = BitmapFactory.decodeFile(path);
//                ivShow.setImageBitmap(b2);
                //直接调用setImageURI方法,设置图像视图的路径对象
                ivShow.setImageURI(Uri.parse(path));
                break;

//把位图数据保存到指定路径的图片文件
    public static void saveImage(String path, Bitmap bitmap) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(path);
            //把位图数据压缩到文件输出流中
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    //从指定路径的图片文件中读取位图数据
    public static Bitmap openImage(String path) {
        Bitmap bitmap = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(path);
            bitmap = BitmapFactory.decodeStream(fis);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bitmap;
    }

Application生命周期:

public class MyApplication extends Application {

    //在APP启动时调用
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("syf","MyApplication onCreate...");
    }

    //在App终止时调用,不会有回调,log不会打
    @Override
    public void onTerminate() {
        super.onTerminate();
        Log.d("syf","MyApplication onTerminal...");
    }

    //在配置改变时调用,例如从竖屏变为横屏
    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d("syf","MyApplication onConfigurationChanged...");
    }
}

在声明文件的application标签中加上

android:name=".MyApplication"

Application全局变量:

public class AppWriteActivity 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;
    private MyApplication app;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_app_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_share).setOnClickListener(this);
        app = MyApplication.getInstance();
        reload();
    }

    private void reload() {
        String name = app.infoMap.get("name");
        if(name == null){
            return;
        }
        String age = app.infoMap.get("age");
        String height = app.infoMap.get("height");
        String weight = app.infoMap.get("weight");
        String married = app.infoMap.get("married");
        et_name.setText(name);
        et_age.setText(age);
        et_height.setText(height);
        et_weight.setText(weight);
        if ("是".equals(married)) {
            ck_married.setChecked(true);
        } else {
            ck_married.setChecked(false);
        }
    }

    @Override
    public void onClick(View v) {
        String name = et_name.getText().toString();
        String age = et_age.getText().toString();
        String height = et_height.getText().toString();
        String weight = et_weight.getText().toString();
        app.infoMap.put("name", name);
        app.infoMap.put("age", age);
        app.infoMap.put("height", height);
        app.infoMap.put("weight", weight);
        app.infoMap.put("married", ck_married.isChecked() ? "是" : "否");
    }
}
public class MyApplication extends Application {

    private static MyApplication mApp;
    //声明一个公共的信息映射对象,可当做全局变量使用
    public HashMap<String,String> infoMap = new HashMap<>();

    public static MyApplication getInstance(){
        return mApp;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mApp = this;
        Log.d("syf","onCreate.....");
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        Log.d("syf","onTerminate.....");
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d("syf","onConfigurationChanged.....");
    }
}

infoMap中的数据随着App销毁会被清除

使用ROOM框架操作数据库:

 1.创建实体类,添加@Entity注解

@Entity
public class Book {

    @PrimaryKey(autoGenerate = true)//自动增长
    private int id;

    private String name;
    private String editor;
    private String publication;
    private double money;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEditor() {
        return editor;
    }

    public void setEditor(String editor) {
        this.editor = editor;
    }

    public String getPublication() {
        return publication;
    }

    public void setPublication(String publication) {
        this.publication = publication;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", editor='" + editor + '\'' +
                ", publication='" + publication + '\'' +
                ", money=" + money +
                '}';
    }
}

2.创建持久化类,添加@Dao注解

@Dao
public interface BookDao {
    @Insert
    //可变参数,可添加多个参数
    void insert(Book... book);

    @Delete
    void delete(Book... book);

    //删除所有书籍信息
    @Query("DELETE from Book")
    void deleteAll();

    @Update
    int update(Book... book);

    //加载所有书籍信息
    @Query("SELECT * FROM Book")//表名建议和类名一致
    List<Book> queryAll();

    //根据名字加载书籍
    @Query("SELECT * FROM Book WHERE name = :name ORDER BY id DESC limit 1")
    Book queryByName(String name);
}

3.创建数据库类,添加@Database注解

//entities表示该数据库有哪些表,version表示数据库的版本号
//exportSchema表示是否导出数据库信息的json串,建议设为false,若设为true还需指定json
@Database(entities = {Book.class},version = 1,exportSchema = true)
public abstract class BookDatabase extends RoomDatabase {

    public abstract BookDao bookDao();

    @NonNull
    @Override
    protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config) {
        return null;
    }

    @NonNull
    @Override
    protected InvalidationTracker createInvalidationTracker() {
        return null;
    }

    @Override
    public void clearAllTables() {

    }
}

exportSchema为true,添加json文件保存路径

javaCompileOptions {
            annotationProcessorOptions {
                //指定数据库schema导出的位置
                arguments = ["room.schemaLocation":"$projectDir/schemas".toString()]
            }
        }

4.在Application类声明数据库的唯一实例

public class MyApplication extends Application {

    private static MyApplication mApp;
    //声明一个公共的信息映射对象,可当做全局变量使用
    public HashMap<String,String> infoMap = new HashMap<>();

    private BookDatabase bookDatabase;

    public static MyApplication getInstance(){
        return mApp;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mApp = this;
        Log.d("syf","onCreate.....");

        //构建数据库的实例
        bookDatabase = Room.databaseBuilder(this,BookDatabase.class,"book")
                //允许迁移数据库(发生数据库变更时,Room默认删除原数据库再创建新数据库。如此一来原来的记录会丢失,故而要改为迁移方式以便保存原有记录)
                .addMigrations()
                .allowMainThreadQueries()//一般不允许在主线程操作数据库
                .build();
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        Log.d("syf","onTerminate.....");
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d("syf","onConfigurationChanged.....");
    }

    public BookDatabase getBookDB(){
        return bookDatabase;
    }
}

5.操作数据

public class RoomWriteActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText et_book_name;
    private EditText et_editor;
    private EditText et_publication;
    private EditText et_money;
    private BookDao bookDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_room_write);
        et_book_name = findViewById(R.id.et_book_name);
        et_editor = findViewById(R.id.et_editor);
        et_publication = findViewById(R.id.et_publication);
        et_money = findViewById(R.id.et_money);

        findViewById(R.id.btn_add).setOnClickListener(this);
        findViewById(R.id.btn_delete).setOnClickListener(this);
        findViewById(R.id.btn_update).setOnClickListener(this);
        findViewById(R.id.btn_query).setOnClickListener(this);

        //从App实例中获取唯一的书籍持久化对象
        bookDao = MyApplication.getInstance().getBookDB().bookDao();
    }

    @Override
    public void onClick(View v) {
        String name = et_book_name.getText().toString();
        String editor = et_editor.getText().toString();
        String publication = et_publication.getText().toString();
        String money = et_money.getText().toString();

        switch (v.getId()) {
            case R.id.btn_add:
                Book b1 = new Book();
                b1.setName(name);
                b1.setEditor(editor);
                b1.setPublication(publication);
                b1.setMoney(Double.parseDouble(money));
                bookDao.insert(b1);
                Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_delete:
                Book b2 = new Book();
                b2.setId(1);
                bookDao.delete(b2);
                break;
            case R.id.btn_update:
                Book b3 = new Book();
                //根据名字查询到数据库中已有的记录
                Book b4 = bookDao.queryByName(name);
                b3.setId(b4.getId());
                b3.setName(name);
                b3.setEditor(editor);
                b3.setPublication(publication);
                b3.setMoney(Double.parseDouble(money));
                bookDao.update(b3);
                break;
            case R.id.btn_query:
                List<Book> list = bookDao.queryAll();
                for (Book b : list) {
                    Log.d("syf", b.toString());
                }
                break;
        }
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值