基於SQLite的通信錄
實驗目的
- 掌握SQLiteOpenHelper類結構
- 掌握基於SQLite數據庫的應用開發過程
- 掌握ContentProvider發佈數據的方法
- 掌握ContentResolver獲取數據的方法
知識點回顧
Android系統中集成了SQLite數據庫,並且爲數據庫的操作提供了相關的類和方法,便於沒有數據庫開發經驗的開發者編寫程序。另外,Android平臺中得用ContentProvider機制來實現跨應用程序數據共享。一個應用程序可以通過ContentProvider來發布自己的數據,其他的應用程序可以通過ContentResolver來獲取共享數據。
實驗內容與步驟
1. 實現基於SQLite數據庫通信錄應用
運行結果視頻所示。通過單擊增加圖標打開添加通信錄界面,通過單擊通信錄中的各條信息可刪除選中項。
【步驟】
(1) 建立數據庫操作類DatabaseHelper,參考代碼如下:
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME="MyRelation.db";
private static final String TABLE_NAME="relation";
private static final String CREATE_TABLE="create table relation(" +
"_id integer primary key autoincrement,name text,tel text,groupName text)";
private SQLiteDatabase db;
public DatabaseHelper(Context context)
{
super(context,DB_NAME,null,2);
}
@Override
public void onCreate(SQLiteDatabase db) {
this.db=db;
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
public void insert(ContentValues values){
SQLiteDatabase db=getWritableDatabase();
db.insert(TABLE_NAME,null,values);
db.close();
}
public void del(int id){
if(null==db)
db=getWritableDatabase();
db.delete(TABLE_NAME,"_id=?",new String[]{String.valueOf(id)});
}
public Cursor query(){
SQLiteDatabase db=getWritableDatabase();
Cursor cursor=db.query(TABLE_NAME,null,null,null,null,null,null);
return cursor;
}
public void close()
{
if(db!=null)
db.close();
}
}
(2) 創建主佈局,參考步驟如下:
① 使用約束佈局
② 添加文本框,並顯示“通信錄”,id爲title
③ 添加列表框,並能選擇“同學”、“同事”和“朋友”,id爲listView
④ 添加圖片按鈕組件,並設置響應方法爲“myClick”
(3) 修改主Activity文件MainActivity.java,參考代碼如下:
public class MainActivity extends AppCompatActivity {
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView)findViewById(R.id.listView);
getRelationFromDB();
}
private void getRelationFromDB()
{
final DatabaseHelper dbHelper=new DatabaseHelper(this);
Cursor cursor=dbHelper.query();
String[] from={"_id","name","tel","groupName"};
int[] to={R.id._id, R.id.name, R.id.tel, R.id.group};
SimpleCursorAdapter scadapter=new SimpleCursorAdapter(this,R.layout.relationlist,cursor,from,to);
listView.setAdapter(scadapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final long temp=id;
Log.d("temp", "onItemClick: ");
AlertDialog.Builder adBuilder=new AlertDialog.Builder(MainActivity.this);
adBuilder.setMessage("確認要刪除記錄嗎?").setPositiveButton("確認",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dbHelper.del((int)temp);
Cursor cursor=dbHelper.query();
String[] from={"_id","name","tel","groupName"};
int[] to={R.id._id,R.id.name,R.id.tel,R.id.group};
SimpleCursorAdapter scadapter=new SimpleCursorAdapter(getApplicationContext(),R.layout.relationlist,cursor,from,to);
MainActivity.this.listView.setAdapter(scadapter);
}
}).setNegativeButton("取消",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {}
});
AlertDialog aleraDialog=adBuilder.create();
aleraDialog.show();
}
});
dbHelper.close();
}
public void myClick(View view)
{
Intent intent=new Intent(MainActivity.this,AddRelationActivity.class);
startActivityForResult(intent,0x111);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==0x111&&resultCode==0x111)
getRelationFromDB();
}
}
(4) 創建列表視圖佈局文件relationlist.xml,參考步驟如下:
① 使用水平線性佈局管理器
② 添加id文本框,id爲_id,設置爲不顯示
③ 添加姓名文本框,id爲name
④ 添加電話文本框,id爲tel
⑤ 添加聯繫人羣組文本框,id爲group
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:descendantFocusability="blocksDescendants"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/_id"
android:text="id "
android:visibility="gone"
android:textSize="20sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/name"
android:text="name"
android:textSize="20sp"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tel"
android:text="tel"
android:textSize="20sp"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/group"
android:text="group"
android:textSize="20sp" />
<CheckBox
android:id="@+id/select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:visibility="gone"/>
</LinearLayout>
(5) 創建增加聯繫人界面佈局文件addrelation.xml,參考步驟如下:
① 使用豎直線性佈局
② 添加輸入姓名提示文本框
③ 添加姓名文本輸入框,id爲addName
④ 添加電話輸入提示文本框
⑤ 添加電話輸入框,id爲addTel
⑥ 添加羣組選擇提示框
⑦ 添加羣組選擇下拉列表框,id爲addGroup
⑧ 添加保存按鈕,設置單擊響應函數名爲:save
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名"
android:textSize="20sp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/addName"
android:text="輸入姓名"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="電話"
android:textSize="20sp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/addTel"
android:text="輸入電話號碼"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="羣組"
android:textSize="20sp"/>
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/addGroup"
android:entries="@array/array_group" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:onClick="save"
android:text="保存" />
</LinearLayout>
(6) 創建增加聯繫人界面Activity文件AddRelationActivity.java,參考代碼如下:
public class AddRelationActivity extends Activity {
private EditText addName,addTel;
private Spinner addGroup;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addrelation);
addName=(EditText) findViewById(R.id.addName);
addTel=(EditText) findViewById(R.id.addTel);
addGroup=(Spinner) findViewById(R.id.addGroup);
}
public void save(View view)
{
final ContentValues values=new ContentValues();
values.put("name",addName.getText().toString());
values.put("tel",addTel.getText().toString());
values.put("groupName",addGroup.getSelectedItem().toString());
final DatabaseHelper dbHelper=new DatabaseHelper(getApplicationContext());
final AlertDialog.Builder adBuilder=new AlertDialog.Builder(this);
adBuilder.setMessage("確認保存記錄嗎?").setPositiveButton("確認",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dbHelper.insert(values);
Intent intent=getIntent();
setResult(0x111,intent);
AddRelationActivity.this.finish();
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
});
AlertDialog aleraDialog=adBuilder.create();
aleraDialog.show();
}
}
(7) 在AndroidManifest.xml文件中添加AddRelationActivity界面應用
<activity android:name=".AddRelationActivity"
android:label="@string/app_name">
</activity>
2. 增加批量刪除功能。
實現ListView單擊和多選操作,在參考代碼基礎上新建ItemBean類,MyAdapter類。ItemBean用於保存聯繫人信息以及在多選中是否選中狀態和是否展示覆選框,MyAdapter適配器類用於對頁面內容處理。
重寫onItemClick和onItemLongClick方法,處理ListView不同的模式。
ItemBean.java
public class ItemBean {
private String id;
private String name;
private String telphone;
private String group;
private boolean isSelect;
private boolean isShowCheckBox;
public boolean isShowCheckBox() {
return isShowCheckBox;
}
public void setIsShowCheckBox(boolean isShowCheckBox) {
this.isShowCheckBox = isShowCheckBox;
}
public ItemBean(String id,String name,String tellphone,String group,boolean isSelect,boolean isShowCheckBox ){
this.id = id;
this.name = name;
this.telphone = tellphone;
this.group = group;
this.isSelect = isSelect;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTelphone() {
return telphone;
}
public void setTelphone(String telphone) {
this.telphone = telphone;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public boolean isSelect() {
return isSelect;
}
public void setIsSelect(boolean select) {
isSelect = select;
}
}
MyAdapter.java
public class MyAdapter extends BaseAdapter {
private List<ItemBean> list;
private LayoutInflater layoutInflater;
public MyAdapter(Context context, List<ItemBean> list){
this.list = list;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = layoutInflater.inflate(R.layout.relationlist,null);
ViewHolder viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
viewHolder.id.setText(list.get(position).getId());
viewHolder.name.setText(list.get(position).getName());
viewHolder.tel.setText(list.get(position).getTelphone());
viewHolder.group.setText(list.get(position).getGroup());
if(list.get(position).isShowCheckBox()){
viewHolder.checkBox.setVisibility(View.VISIBLE);
if(list.get(position).isSelect()){
viewHolder.checkBox.setChecked(true);
}else{
viewHolder.checkBox.setChecked(false);
}
}else{
viewHolder.checkBox.setVisibility(View.INVISIBLE);
}
return convertView;
}
public class ViewHolder {
public final TextView id;
public final TextView name;
public final TextView tel;
public final TextView group;
public final CheckBox checkBox;
public final View root;
public ViewHolder(View root) {
id = (TextView) root.findViewById(R.id._id);
name = (TextView) root.findViewById(R.id.name);
tel = (TextView) root.findViewById(R.id.tel);
group = (TextView) root.findViewById(R.id.group);
checkBox = (CheckBox) root.findViewById(R.id.select);
this.root = root;
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
private ListView listView;
private Boolean Flag = false;
private LinearLayout editbar;//按鈕佈局
private Button sure,cancel; //cancel是全選多選切換
private MyAdapter adapter;
private List<ItemBean> list;
private Boolean isLineaLayoutVisible = false;//標記按鈕佈局的顯示
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView)findViewById(R.id.listView);
editbar = (LinearLayout)findViewById(R.id.edit_bar);
sure = (Button)findViewById(R.id.delete);
cancel = (Button)findViewById(R.id.cancel);
sure.setOnClickListener(this);
cancel.setOnClickListener(this);
list = new ArrayList<ItemBean>();
getFromDB_bean();
}
private void getFromDB_bean() {
if(list != null) {
list.clear();
}
final DatabaseHelper dbHelper=new DatabaseHelper(this);
Cursor cursor=dbHelper.query();
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
String ids = cursor.getString(cursor.getColumnIndex("_id"));
String names = cursor.getString(cursor.getColumnIndex("name"));
String tels = cursor.getString(cursor.getColumnIndex("tel"));
String groups = cursor.getString(cursor.getColumnIndex("groupName"));
list.add(new ItemBean(ids,names,tels,groups,false,false));
}
adapter = new MyAdapter(this,list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
listView.setOnItemLongClickListener(this);
dbHelper.close();
}
//這一段沒什麼用了,但是onActivityResult()用到
private void getRelationFromDB()
{
final DatabaseHelper dbHelper=new DatabaseHelper(this);
Cursor cursor=dbHelper.query();
String[] from={"_id","name","tel","groupName"};
int[] to={R.id._id, R.id.name, R.id.tel, R.id.group};
SimpleCursorAdapter scadapter=new SimpleCursorAdapter(this,R.layout.relationlist,cursor,from,to);
listView.setAdapter(scadapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final long temp=id;
Log.d("temp", "onItemClick: ");
AlertDialog.Builder adBuilder=new AlertDialog.Builder(MainActivity.this);
adBuilder.setMessage("確認要刪除記錄嗎?").setPositiveButton("確認",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dbHelper.del((int)temp);
Cursor cursor=dbHelper.query();
String[] from={"_id","name","tel","groupName"};
int[] to={R.id._id,R.id.name,R.id.tel,R.id.group};
SimpleCursorAdapter scadapter=new SimpleCursorAdapter(getApplicationContext(),R.layout.relationlist,cursor,from,to);
MainActivity.this.listView.setAdapter(scadapter);
}
}).setNegativeButton("取消",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {}
});
AlertDialog aleraDialog=adBuilder.create();
aleraDialog.show();
}
});
dbHelper.close();
}
public void myClick(View view)
{
Intent intent=new Intent(MainActivity.this,AddRelationActivity.class);
startActivityForResult(intent,0x111);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==0x111&&resultCode==0x111)
getRelationFromDB();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.delete:
String str = "";
for(ItemBean itemBean : list){
if(itemBean.isSelect()){
str+=itemBean.getName()+itemBean.getName()+"\n";
delete_one(itemBean);
}
}
if(str.equals("")){
Toast.makeText(this,"您沒有選擇",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this,str,Toast.LENGTH_SHORT).show();
}
break;
case R.id.cancel:
if(cancel.getText().equals("選擇全部")){
for(ItemBean itemBean : list){
itemBean.setIsSelect(true);
}
cancel.setText("取消全部");
}else{
for(ItemBean itemBean : list){
itemBean.setIsSelect(false);
}
cancel.setText("選擇全部");
}
adapter.notifyDataSetChanged();
break;
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(isLineaLayoutVisible){//當按鈕佈局顯示時候纔有權多項選擇
list.get(position).setIsSelect(!list.get(position).isSelect());//向表中記錄被選擇的item
adapter.notifyDataSetChanged();//更新ListView
}
else{
ItemBean item = list.get(position);
delete_one(item);
}
}
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
try {
list.get(position).setIsSelect(true);//記錄選擇的item有機率不成功,我也不知道爲啥,所以就用try
} catch (Exception e) {
e.printStackTrace();
list.get(position).setIsSelect(true);
}
for(ItemBean itemBean : list){
itemBean.setIsShowCheckBox(true);//將所有的Item的CheckBox設置爲選擇狀態
}
adapter.notifyDataSetChanged();
editbar.setVisibility(View.VISIBLE);//長按item設置按鈕佈局爲顯示狀態
isLineaLayoutVisible = true;
return true;
}
@Override
public void onBackPressed() {
if (isLineaLayoutVisible){
editbar.setVisibility(View.INVISIBLE);
isLineaLayoutVisible = false;
for(ItemBean itemBean : list){//按返回鍵時取消所有選擇記錄,同是吧按鈕佈局設置爲不可見
itemBean.setIsShowCheckBox(false);
itemBean.setIsSelect(false);
}
adapter.notifyDataSetChanged();
}else {
super.onBackPressed();
}
}
public void delete_one(ItemBean item){
final DatabaseHelper dbHelper=new DatabaseHelper(this);
Cursor cursor=dbHelper.query();
//Toast.makeText(this,list.get(position).getName()+list.get(position).getTelphone(),Toast.LENGTH_SHORT).show();
final String temp=item.getId();
Log.d("temp", "onItemClick: ");
AlertDialog.Builder adBuilder=new AlertDialog.Builder(MainActivity.this);
adBuilder.setMessage("確認要刪除記錄嗎?").setPositiveButton("確認",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dbHelper.del(Integer.parseInt(temp));
getFromDB_bean();
}
}).setNegativeButton("取消",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {}
});
AlertDialog aleraDialog=adBuilder.create();
aleraDialog.show();
dbHelper.close();
}
}
實驗問題
主要在參考代碼基礎上實現了ListView多選。
代碼中仍然存在Bug,例如單擊刪除後再多選,出錯;多選後再添加,出錯。後續修改