一、实验目的
练习掌握 Android 软件开发基本编程技术、Android 系统 SQLite 数据库的使用、通话、短信的使用等,设计制作一 Android 通讯录软件。
二、实验内容
实现的通讯录功能和界面可在实验开发中由每位同学自己设计,但必须使用SQLite 数据库保存通讯录信息。以下功能和软件界面供参考:仿照一般手机通讯录的使用界面和功能,主要功能可包括: (1)可以添加、删减联系人
(2)联系人的信息包括:姓名、手机号码、工作单位、群组、电子邮件、手机铃声
(3)选择联系人后,可以快速进行操作,如:拨打电话发送短信、查看详细、移出群组、移动分组、删除联系人等。查看详细时显示手机号码、群组、和设定的手机铃声以及同该联系人的通话记录。
(4)在联系人界面,可以查看各群组。点击群组,跳出对应联系人。
(5)有拨号键盘,点击数字将号码显示出来,并可以对手机号码进行删减
(6)可以发送信息,显示信息记录
(7)发送信息时,可以快速选择现有联系人。
三、实验要求
(1)每位同学独立设计软件功能、完成软件的开发与测试。
(2)每位同学独立完成实验报告(根据模板),并提交至网络课堂。
四、数据代码及运行结果截图
全部代码如图所示
//mainactivity.java 代码太多了,所以其他文件的代码就没有贴上。
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.NotificationCompat;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;
import com.google.android.material.navigation.NavigationView;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.pan.coursedesign.recyclerview.Person;
import com.pan.coursedesign.recyclerview_logs.recording;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.litepal.crud.DataSupport;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
AlertDialog.Builder builder5;//自定义
AlertDialog dialog;
private int tag = 0;
private int DataDownTag = 0;
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//自定义Toolbar并设置进系统
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//因为滑动菜单不容易被用户知道,所以加一个折叠按钮
ActionBar actionBar = getSupportActionBar();//得到actionBar的实例(toolbar实现的哦,也就是toolbar对象)
if (actionBar != null) { //有的话
actionBar.setDisplayHomeAsUpEnabled(true); //显示一个home按钮,HomeAsUp这个按钮的id永远是Home
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu); //设置一个图标
}
//获取抽屉的实例用于打开和关闭抽屉的事件
mDrawerLayout = findViewById(R.id.my_drawer);
//默认加载的碎片,text1
replaceFragment(new Contacts_Fragment());
//启动弹窗
//从文件读取tag数据
SharedPreferences preferences = getSharedPreferences("statata", MODE_PRIVATE);
tag = preferences.getInt("tag", 0);
if (tag == 0) { //tag没被修改,显示弹窗
loding();
}
//设置侧面munu的点击事件
NavigationView navigationView = (NavigationView) findViewById(R.id.my_nav_view);
navigationView.setCheckedItem(R.id.nav_text1);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
//详细设计抽屉菜单的点击事件
switch (item.getItemId()) {
case R.id.nav_text1:
replaceFragment(new Contacts_Fragment());
mDrawerLayout.closeDrawer(navigationView);
break;
case R.id.nav_text2:
replaceFragment(new Call_Fragment());
mDrawerLayout.closeDrawer(navigationView);
break;
case R.id.nav_text3:
replaceFragment(new Call_logs_Fragment());
mDrawerLayout.closeDrawer(navigationView);
break;
case R.id.nav_text4:
replaceFragment(new Help_Fragment());
mDrawerLayout.closeDrawer(navigationView);
break;
case R.id.nav_text5:
replaceFragment(new About_Fragment());
mDrawerLayout.closeDrawer(navigationView);
break;
default:
break;
}
return true;
}
});
}
//动态替换碎片
private void replaceFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.DTFragment, fragment);
transaction.commit();
}
// ----toolbar逻辑----
//传统的方法实现菜单的植入(command + O快捷键)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//设置一个menu
getMenuInflater().inflate(R.menu.toolbar, menu);
return true;
}
//tab按键事件
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//设置menu的选项点击事件
switch (item.getItemId()) {
case android.R.id.home://这是内置的哦
mDrawerLayout.openDrawer(GravityCompat.START);//将滑动菜单显示出来,打开抽屉 参数是方式和xml设置的保持一致
break;
case R.id.DataDown:
DataDown();//阿帕奇服务器上下载json数据
break;
case R.id.DataUp:
try {
UpData(GetJsonString());//先把数据导出成json文本在作为数据上传到服务器
} catch (JSONException e) {
e.printStackTrace();
}
// Toast.makeText(this,"此功能开发中...",Toast.LENGTH_LONG).show();
break;
case R.id.settings:
try {
ExportData();
Toast.makeText(this, "导出成功: 内部目录file文件夹下", Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
}
break;
case R.id.settings_1:
if (Import().isEmpty()) {
Toast.makeText(this, "导入失败,没有数据", Toast.LENGTH_LONG).show();
} else {
ImportData();
Toast.makeText(this, "导入成功", Toast.LENGTH_LONG).show();
}
break;
case R.id.settings_2:
delall();
break;
default:
}
return true;
}
//1.下载时提示框
public void DataDown() {
//启动弹窗
//从文件读取tag数据
SharedPreferences preferences = getSharedPreferences("DataDown", MODE_PRIVATE);
DataDownTag = preferences.getInt("DataDownTag", 0);
if (DataDownTag == 0) { //tag没被修改,显示弹窗
//inflate方法返回的是一个view(自定义那个),
View loginview = LayoutInflater.from(this).inflate(R.layout.datadown_dialog_info, null);
//loginview里的控件声明一下
CheckBox checkBox = loginview.findViewById(R.id.info_2);
Button btnLogin = loginview.findViewById(R.id.datadown);
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//把状态计入文件供下次读取
if (checkBox.isChecked()) {//如果被选中
SharedPreferences.Editor editor = getSharedPreferences("DataDown", MODE_MULTI_PROCESS).edit();
editor.putInt("DataDownTag", 1);
editor.apply();
}
dialog.dismiss();
DownData();
}
});
//设置Dialog和View
builder5 = new AlertDialog.Builder(this);
dialog = builder5.setTitle("重要提示").setView(loginview).setCancelable(false).show();
} else {
DownData();
}
}
//从服务器下载json数据
public void DownData() {
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
// 指定访问的服务器地址是电脑本机
.url("http://172.20.10.5:8081/pro")
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
parseJSONWithGSON(responseData);//下载json数据导入解析
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
//导入json进行解析的方法
private void parseJSONWithGSON(String jsonData) {
//Log.d("aaaaa---", jsonData);
Contacts_Fragment contacts_fragment = (Contacts_Fragment) getSupportFragmentManager().findFragmentById(R.id.DTFragment);
Gson gson = new Gson();
List<Person> appList = gson.fromJson(jsonData, new TypeToken<List<Person>>() {
}.getType());
//c=appList;
int tag = 0;
//遍历并先把数据存入数据库
for (Person person : appList) {
person.setTel(formatInviteCode(person.getTel()));//获取的数据同样要处理
if (RemoveRepetition(person.getName())) { //只有数据库没有时才更新
contacts_fragment.Persons.add(person);
person.save();
tag = 1;
}
}
if (tag == 1) {//只要有一个变就刷新
//这个方法是在任务线程执行的,需要去主线程更新ui
//加个下载成功的通知
DataNotification();
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
contacts_fragment.load();
}
});
} else {
DataFailNotification();//找不到服务器/导入的数据都有
}
}
public Boolean RemoveRepetition(String name) {
List<Person> Persons = DataSupport.select("name", "Tel", "Email").where("name like ?", "%" + name + "%").find(Person.class);
if (Persons.size() != 0) {
return false;//如果数据库有,不更新
}
return true;
}
//下载成功的通知
public void DataNotification() {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this, "5996773")
.setContentTitle("文件下载的通知")//标题内容
.setContentText("导入数据成功!")//正文内容
.setWhen(System.currentTimeMillis())//指定通知被创建的时间
.setSmallIcon(R.mipmap.ic_launcher)//设置通知小图标
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))//设置通知大图标
.setVibrate(new long[]{0, 1000, 1000, 1000})//通知到了让手机震动
.setLights(Color.GREEN, 1000, 1000)//设置手机前置LED灯的显示效果
.setPriority(NotificationCompat.PRIORITY_MAX)//设置通知的重要程度
.build();//build完算是构建完成notification对象
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("5996773", "安卓10的通知哦", NotificationManager.IMPORTANCE_HIGH);
channel.enableLights(true);//是否在桌面icon右上角展示小红点
channel.setLightColor(Color.GREEN);//小红点颜色
channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知
manager.createNotificationChannel(channel);//将channel设置进manager
}
//id唯一即可
manager.notify(1, notification);
}
//下载失败的通知
public void DataFailNotification() {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this, "5996774")
.setContentTitle("文件下载的通知")//标题内容
.setContentText("文件下载成功,但您不需要导入!")//正文内容
.setWhen(System.currentTimeMillis())//指定通知被创建的时间
.setSmallIcon(R.mipmap.ic_launcher)//设置通知小图标
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))//设置通知大图标
.setVibrate(new long[]{0, 1000, 1000, 1000})//通知到了让手机震动
.setLights(Color.GREEN, 1000, 1000)//设置手机前置LED灯的显示效果
.setPriority(NotificationCompat.PRIORITY_MAX)//设置通知的重要程度
.build();//build完算是构建完成notification对象
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("5996774", "安卓10的通知哦", NotificationManager.IMPORTANCE_HIGH);
channel.enableLights(true);//是否在桌面icon右上角展示小红点
channel.setLightColor(Color.GREEN);//小红点颜色
channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知
manager.createNotificationChannel(channel);//将channel设置进manager
}
//id唯一即可
manager.notify(2, notification);
}
//2.上传json到服务器
public void UpData(String body){
new Thread(new Runnable(){
@Override
public void run(){
String url="http://172.20.10.5:8081/air";//你要訪問的地址
String mesg = null;//定义服务器返回的结果
HttpClient httpClient = new HttpClient();//构建HttpClient实例
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(60000); //设置请求超时时间
httpClient.getHttpConnectionManager().getParams().setSoTimeout(60000);//设置响应超时时间
PostMethod postMethod=new PostMethod(url);//构造PostMethod的实例
postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"utf-8");
String jsonString="{'data':" + body + "}";
//com.alibaba.fastjson.JSONObject意思是导入阿里的parseObject,parseObject第一个参数是json对象
Map<String,Object> map = com.alibaba.fastjson.JSONObject.parseObject(jsonString,Map.class);
Set<String> set = map.keySet();
for(String s : set){
postMethod.addParameter(s,map.get(s).toString());
}
try {
httpClient.executeMethod(postMethod);//执行post请求
mesg = postMethod.getResponseBodyAsString();//可以对响应回来的报文进行处理
//Log.d("aaaa--", mesg);//获取成功!!!!
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(mesg!=null){//有数据
DataupNotification();//文件上传成功的通知
}
//关闭连接释放资源的方法
postMethod.releaseConnection();
httpClient.getHttpConnectionManager().closeIdleConnections(0);
}
}
}).start();
}
//上传成功的通知
public void DataupNotification() {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this, "599111")
.setContentTitle("文件上传的通知")//标题内容
.setContentText("上传数据成功!")//正文内容
.setWhen(System.currentTimeMillis())//指定通知被创建的时间
.setSmallIcon(R.mipmap.ic_launcher)//设置通知小图标
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))//设置通知大图标
.setVibrate(new long[]{0, 1000, 1000, 1000})//通知到了让手机震动
.setLights(Color.GREEN, 1000, 1000)//设置手机前置LED灯的显示效果
.setPriority(NotificationCompat.PRIORITY_MAX)//设置通知的重要程度
.build();//build完算是构建完成notification对象
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("599111", "安卓10的通知哦", NotificationManager.IMPORTANCE_HIGH);
channel.enableLights(true);//是否在桌面icon右上角展示小红点
channel.setLightColor(Color.GREEN);//小红点颜色
channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知
manager.createNotificationChannel(channel);//将channel设置进manager
}
//id唯一即可
manager.notify(3, notification);
}
//3.导出json到文件
public void ExportData() throws JSONException {
String str = GetJsonString();
save(str);
}
//导出json文本
public String GetJsonString() throws JSONException {
//获取碎片实例以调用碎片中的方法
Contacts_Fragment contacts_fragment = (Contacts_Fragment) getSupportFragmentManager().findFragmentById(R.id.DTFragment);
List<Person> Persons = contacts_fragment.Persons;
//转换list为json
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();//这个巨坑,注意包
JSONObject tmpObj = null;
int count = Persons.size();
for (int i = 0; i < count; i++) {
tmpObj = new JSONObject();
tmpObj.put("name", Persons.get(i).getName());
tmpObj.put("Email", Persons.get(i).getEmail());
tmpObj.put("Tel", Persons.get(i).getTel());
jsonArray.put(tmpObj);
tmpObj = null;
}
String personInfos = jsonArray.toString(); // 将JSONArray转换得到String
//Log.d("DDDDD",personInfos);
return personInfos;
}
//将一段json文本保存到文件中去
public void save(String inputText) {
FileOutputStream out = null;
BufferedWriter writer = null;
//command + alt + t 快速生成
try {
File file = new File(getCacheDir().getPath(), "data.json");
if (file != null) {
file.delete();
} else {
file.createNewFile();
}
out = openFileOutput("data.json", Context.MODE_PRIVATE);
// out = new FileOutputStream(file);
// OutputStreamWriter是从字符流到字节流的桥接:字节流搞成了字符流传递给缓冲流
writer = new BufferedWriter(new OutputStreamWriter(out));
// 写入
writer.write(inputText);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();//关闭上层流(缓冲流),下层数据流就自动关了
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//4.从文件导入json
public void ImportData() {
String str1 = Import();
parseJSONWithGSON(str1);//显示
}
//从文件中读取json文件
public String Import() {
//准备从文件读数据
FileInputStream in = null;
//缓冲流,输入
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
in = openFileInput("data.json");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
//reader.readLine()是读取一行
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return content.toString();
}
//初始化加载
private void loding() {
//inflate方法返回的是一个view(自定义那个),
View loginview = LayoutInflater.from(this).inflate(R.layout.ui_dialog_info, null);
//loginview里的控件声明一下
CheckBox checkBox = loginview.findViewById(R.id.info_2);
Button btnLogin = loginview.findViewById(R.id.info_3);
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 把状态计入文件供下次读取
if (checkBox.isChecked()) {//如果被选中
SharedPreferences.Editor editor = getSharedPreferences("statata", MODE_MULTI_PROCESS).edit();
editor.putInt("tag", 1);
editor.apply();
}
dialog.dismiss();
}
});
//设置Dialog和View
builder5 = new AlertDialog.Builder(this);
dialog = builder5.setTitle("重要信息").setView(loginview).setCancelable(false).show();
}
//5.一键删除
public void delall() {
DataSupport.deleteAll(Person.class);
DataSupport.deleteAll(recording.class);
Toast.makeText(this, "删除全部数据成功!", Toast.LENGTH_SHORT).show();
}
//处理一下系统获取联系人时字符串的-/空格
public String formatInviteCode(String str1) {
String str2 = "";
for (int i = 0; i < str1.length(); i++) {
if (Character.isDigit(str1.charAt(i))) {//判断被索引处的字符是不是数字
str2 += str1.charAt(i);
}
}
return str2;
}
}
五、错误总结
1、错误:
no such column: userName
解决:格式错误,类型TEXT前面必须有一个空格!
UserInfoEntry.COLUMN_USER_NAME + " TEXT NOT NULL, "
2、类型前面全部都添加了空格,仍旧报错:
no such column: userName
解决:数据库没有更新,更新版本号。在生产应用程序中,可能会修改此方法以更改表格,而不是删除它,以便不删除现有数据。
新手学习中,尚不知道如何修改。
//如果更改数据库架构,则必须增加数据库版本
private static final int DATABASE_VERSION = 4;
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
// //在onUpgrade中,删除表(如果存在)
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + UserInfoEntry.TABLE_NAME);
// //调用onCreate并传入SQLiteDatabase(传入onUpgrade)记得更新版本号
onCreate(sqLiteDatabase);
}
3、错误:
android.database.CursorIndexOutOfBoundsException: Index -1 requested,
with a size of 1
解决:下标越界,cursor下标从-1开始,而不是0,需要移动,添加if语句。其实还是不太明白,为什么移动到第一个就可以了。
if (cursor.moveToFirst()){
queryPassword=cursor.getString(cursor.getColumnIndex(UserInfoContract.UserInfoEntry.COLUMN_USER_PASSWORD));
}
4、错误:
android.database.sqlite.SQLiteException: no such column:
错误例子:
return mDb.update(DATABASE_TABLE, args, KEY_SSID + "=" + ssid , null) > 0;
原因:
在执行数据库的增删改查操作时,如:update、query等方法,传入的参数是字符串类型。
其实这些方法会将参数拼接成sql语句,而字符串类型需要用引号引上
所以上方错误的代码应改为:
return mDb.update(DATABASE_TABLE, args, KEY_SSID + "='" + ssid + "'", null) > 0;
六、个人心得体会
SQLite的基本数据类型:Byte,Long,Short,Integer,Float,Double,String,Boolean,byte[]
理论存储容量为140TB
SQLiteOpenHelper
既然是数据库的增删改查,我们首先需要一个数据库,而数据库要通过SQLiteOpenHelper的子类生成,所以首先需要建一个类来继承SQLiteOpenHelper。由于这个类是一个抽象类,我们需要实现他的构造方法和抽象方法。所以:
public class DBHelper extends SQLiteOpenHelper {
// 数据库默认名字
public static final String db_name = "test.db";
public DBHelper(Context context, int version) {
super(context, db_name, null, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
需要重载的方法
onCreate:创建表和一些基本属性。
onUpgrade:数据库需要更新的时候使用,前提是已经存在了一个相同的数据库,需要新加表,或者原来的表字段要修改。
举例:现在创建一个名为table1的表:直接执行SQL语句
public class DBHelper extends SQLiteOpenHelper {
public static final String db_name = "test.db";
public DBHelper(Context context, int version) {
super(context, db_name, null, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table table1 (" +
" _byte byte," +
" _long long," +
" _text text," +
" _short short," +
" _int int," +
" _float float," +
" _double double," +
" _boolean boolean," +
" _blob blob" +
")");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
表的增删改查
public class DBManger {
private Context context;
private static DBManger instance;
// 操作表的对象,进行增删改查
private SQLiteDatabase writableDatabase;
private DBManger(Context context) {
this.context = context;
DBHelper dbHelper = new DBHelper(context, 1);
//通过DBHelper的getWritableDatabase方法得到SQLiteDatabase对象,SQLiteDatabase可以对数据库表进行操作
writableDatabase = dbHelper.getWritableDatabase();
}
public static DBManger getInstance(Context context) {
if (instance == null) {
synchronized (DBManger.class) {
if (instance == null) {
instance = new DBManger(context);
}
}
}
return instance;
}
}
增加:
public void add() {
ContentValues contentValues = new ContentValues();
byte _byte = Byte.MAX_VALUE;
contentValues.put("_byte", _byte);
long _long = Long.MAX_VALUE;
contentValues.put("_long", _long);
String _text = "字符串";
contentValues.put("_text", _text);
short _short = Short.MAX_VALUE;
contentValues.put("_short", _short);
int _int = Integer.MAX_VALUE;
contentValues.put("_int", _int);
float _float = Float.MAX_VALUE;
contentValues.put("_float", _float);
double _double = Double.MAX_VALUE;
contentValues.put("_double", _double);
boolean _boolean = true;
contentValues.put("_boolean", _boolean);
byte[] _byteArr = {Byte.MIN_VALUE, Byte.MAX_VALUE};
contentValues.put("_blob", _byteArr);
writableDatabase.insert("table1", null, contentValues);
}
删:删除_int = Integer.MAX_VALUE的值
public void del() {
writableDatabase.delete("table1", "_int = ?", new String[]{Integer.MAX_VALUE + ""});
}
改:调用update方法,参数依次:表名、包裹、条件、条件的值
public void update() {
ContentValues contentValues = new ContentValues();
contentValues.put("_text", "修改后的字符串");
writableDatabase.update("table1", contentValues, "_text = ?", new String[]{"字符串"});
}
查:首先query方法返回了一个Cursor对象,用来定位。
Query的参数:
String table:表名
String[] columns:需要被查询的列名
String selection:代表只查多少条数据,比如只查10条数据,就直接传递一个10就行了。
String[] selectionArgs:代表只查多少条数据,比如只查10条数据,就直接传递一个10就行了。
String groupBy:将相同值划分为一组
String having:条件判断的参数,不过这个要跟groupby这个参数同时存在,也就是要同时使用。也就是说,在groupby筛选后的数据中,再使用这个所谓的having再筛选一次。
String orderBy:代表排序,可以传某个字段,比如_byte,这就代表按照这个字段排序,默认是升序,也就是从小到大排序,我们可以这样传递参数,让其降序排列_byte desc,如果是_byte asc就是升序,由于默认升序,所以这个asc也就省略了。
String limit:代表只查多少条数据,比如只查10条数据,就直接传递一个10就行了。
public String select() {
Cursor cursor = writableDatabase.query("table1", null, null, null, null, null, null, null);
int position = cursor.getPosition();
Log.e(TAG, "select: 游标默认位置:" + position);
String result = "";
while (cursor.moveToNext()) {
byte _byte = (byte) cursor.getShort(cursor.getColumnIndex("_byte"));
long _long = cursor.getLong(cursor.getColumnIndex("_long"));
String _text = cursor.getString(cursor.getColumnIndex("_text"));
short _short = cursor.getShort(cursor.getColumnIndex("_short"));
int _int = cursor.getInt(cursor.getColumnIndex("_int"));
float _float = cursor.getFloat(cursor.getColumnIndex("_float"));
double _double = cursor.getDouble(cursor.getColumnIndex("_double"));
boolean _boolean = cursor.getInt(cursor.getColumnIndex("_boolean")) == 1 ? true : false;
byte[] _byteArr = cursor.getBlob(cursor.getColumnIndex("_blob"));
result += String.format("_byte = %s, _long = %s, _text = %s, _short = %s, _int = %s, _float = %s, _double = %s, _boolean = %s, _byteArr = %s",
_byte, _long, _text, _short, _int, _float, _double, _boolean, _byteArr) + "\n";
}
return result;
}