一、实现功能
将图片转换为Byte数组储存在LitePal数据库中,进行读取使用,将数据库转移至不同项目文件中。
二、具体操作
1.图片写入
创建工程文件databaseTest,定义类MainActivity。
使用LitePal技术创建需要储存的数据表(服装类):定义属性及其getter、setter方法
package com.example.databasetest;
import org.litepal.crud.LitePalSupport;
import org.litepal.exceptions.DataSupportException;
public class ClothStore extends LitePalSupport {
private int id;
private String clothname;
private double price;
private String img_src;
private byte[] clothpic;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getClothname() {
return clothname;
}
public void setClothname(String clothname) {
this.clothname = clothname;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getImg_src() {
return img_src;
}
public void setImg_src(String img_src) {
this.img_src = img_src;
}
public byte[] getClothpic() {
return clothpic;
}
public void setClothpic(byte[] clothpic) {
this.clothpic = clothpic;
}
}
在app/src/main路径下创建assets文件夹
创建litePal.xml配置映射关系
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="Wardrobe" />
<version value="1" />
<list>
<mapping class="com.example.databasetest.ClothStore"></mapping>
</list>
</litepal>
由于电脑中储存文件无法由Android虚拟机内部访问到,因此将需要储存的图片导入到res/drawable中。
储存图片过程:先将jpg/png文件打开为Bitmap格式,再将Bitmap格式图片使用bitmap.compress转换为比特数组Byte[];
注意,由于Android安全设置,须在AndroidManifest.xml文件中设置读写权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
储存过程实现代码(布局文件只需加入按钮就行,由于简单就忽略了):
通过定义img方法对图片进行转换
package com.example.databasetest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import org.litepal.LitePal;
import org.litepal.crud.LitePalSupport;
import org.litepal.tablemanager.Connector;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private byte[]img(Bitmap bitmap){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button createDB = findViewById(R.id.create_DB);
createDB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bitmap cloth = BitmapFactory.decodeResource(getResources(), R.drawable.j1);
byte[] images = img(cloth);
ClothStore clothStore = new ClothStore();
clothStore.setClothpic(images);
clothStore.save();
}
});
在录入图片后,使用adb shell进行查看(查看时确保虚拟机正在运行,访问的是虚拟机中的文件):
打开cmd
输入adb root
获得root权限,确保你使用的虚拟机不支持google store,不知道为什么,如果选用支持google store权限的虚拟机无法获得root权限,不获得root权限则无法访问到内部文件
adb shell进入虚拟机的adb shell界面
输入cd /data/data/com.example.databasetest/databases进入你储存数据库的地方
使用ls -l 指令可以查看当前路径下的文件
使用sqlite3 Wardrobe.db进入数据库
输入.schema查询当前数据库中的所有表(由于我之前已在数据库中创建过许多表,所以忽略其他表文件,只需关注我们之前创建的clothstore表即可)
使用SQL语言 select * from clothstore;查看图片是否导入
如果出现则图片导入成功。
2.图片读取
确认图片已成功存放进入数据库后,进行读取调用就比较简单了:
只需要将Byte[]类型的图片进行反转码,转回为Bitmap类型即可,具体实现代码如下
Button searchData =findViewById(R.id.searchData);
searchData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImageView imageView = findViewById(R.id.pic);
TextView textView1 = findViewById(R.id.name);
TextView textView2 = findViewById(R.id.price);
List<ClothStore> clothStore = LitePal.findAll(ClothStore.class);
ClothStore item = clothStore.get(5); //注意这里是你要读取的数据在数据库中的位置
byte[] images = item.getClothpic();
Bitmap bitmap = BitmapFactory.decodeByteArray(images, 0, images.length);
imageView.setImageBitmap(bitmap);
}
});
点击按钮即可发现图片加载进入imageView中:
3.数据库转移
在很多时候,我们需要在另一个工程项目中加载数据库,不同于MySQL等大型数据库,在Android环境中的数据库由于存放位置的原因我们在转移时不能从路径直接进行转移,因此我们需要通过adb shell进行操作来转移。
1.使用adb shell将数据库文件转移至电脑中
打开cmd ,确保adb shell具有root权限
在cmd界面,切记不要进入adb shell中,输入adb pull /data/data/com.example.databasetest/databases/Wardrobe.db "D:\Android developmentt\demo"
前半段是你的数据库存放位置,后半段是你要导出到的位置,如果导出路径有空格则用引号括住。
2.新建项目文件,导入数据库
新建项目文件ClothSQL,在app/src/main下新建assets文件夹,将电脑中储存的Wardrobe.db导入
在MainActivity.java中将数据库复制进入虚拟机储存:
package com.example.clothsql;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MainActivity extends AppCompatActivity {
private static String DB_PATH = "/data/data/" + BuildConfig.APPLICATION_ID + "/databases/";
private static String DB_NAME = "Wardrobe.db";
public static void copyDatabase(Context context) {
File dbFile = context.getDatabasePath(DB_NAME);
if (!dbFile.exists()) {
try {
InputStream is = context.getAssets().open(DB_NAME);
OutputStream os = new FileOutputStream(dbFile);
byte[] buffer = new byte[1024];
while (is.read(buffer) > 0) {
os.write(buffer);
}
os.flush();
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
copyDatabase(this);
}
}
储存后使用adb shell检查存放位置,
发现数据库储存成功。