您的位置:首页 > 移动开发 > Android开发

我的第一个带数据库的Android通讯录项目

2017-11-13 11:42 225 查看
数据库用SQLite,,轻量级,好用。没有SQLite的同学云盘自取:http://pan.baidu.com/s/1kU7EIyF

然后做该项目之前我们简单分析一下功能:

1.添加联系人

2.更新联系人

3.删除联系人

然后再考虑有几个activity(3个,一个UserListActivity,一个AddActivity,一个UpdateActivity),预览图是这样的

点击左上方加号出现以下

上代码:

布局文件:

user_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right" >

<ImageButton
android:id="@+id/add"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/add" />
</LinearLayout>

<TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="通讯录"
android:textSize="26sp" />

<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>

</LinearLayout>
activity_add.xml

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

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

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名:" />

<EditText
android:id="@+id/et_Name"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</EditText>
</LinearLayout>

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

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="电话:" />

<EditText
android:id="@+id/et_Phone"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</EditText>
</LinearLayout>

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

<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="地址:" />

<EditText
android:id="@+id/et_Address"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</EditText>
</LinearLayout>

<Button
android:id="@+id/btn_OK"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="确定" />

<Button
android:id="@+id/btn_Cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消" />

</LinearLayout>


activity_update.xml

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

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

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名:" />

<EditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</EditText>
</LinearLayout>

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

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="电话:" />

<EditText
android:id="@+id/etPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</EditText>
</LinearLayout>

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

<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="地址:" />

<EditText
android:id="@+id/etAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</EditText>
</LinearLayout>

<Button
android:id="@+id/btnOK"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="确定" />

<Button
android:id="@+id/btnCancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消" />

</LinearLayout>
item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:id="@+id/id"
android:layout_width="15dp"
android:layout_height="wrap_content"
android:textSize="16sp" />

<TextView
android:id="@+id/name"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:textSize="16sp" />

<TextView
android:id="@+id/phone"
android:layout_width="95dp"
android:layout_height="wrap_content"
android:textSize="16sp" />

<TextView
android:id="@+id/address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />

</LinearLayout>


图片文件:

Java代码:

UserListActivity.java

package com.example.sqlitedemo;

import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Window;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class UserListActivity extends Activity {

private ImageButton add;//右上角的加号按钮
private ListView listView;//通讯录listview
private MyOpenHelper helper;//声明一个MyOpenHelper对象
private List<User> users;//通讯录列表
private MyBaseAdapter adapter;//适配器

@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATUR
4000
E_NO_TITLE);
setContentView(R.layout.user_list);
add = (ImageButton) findViewById(R.id.add);//从布局文件中获取绑定控件
listView = (ListView) findViewById(R.id.listView);
helper = new MyOpenHelper(this);//创建数据库 需要调用  getReadableDatabase 或 getWritableDatabase
GetData();//调用下方GetData();
if (users != null) {//只要数据表名不为空
adapter = new MyBaseAdapter(); //初始化适配器
listView.setAdapter(adapter);//设置adapter
}

this.registerForContextMenu(listView);//为所有列表项注册上下文菜单
add.setOnClickListener(new OnClickListener() {//按钮监听事件

@Override
public void onClick(View v) {
Intent intent = new Intent(UserListActivity.this,
AddActivity.class);//点击加号跳到添加页面
startActivity(intent);//开启intent
}
});
}

@Override
protected void onResume() {//在 Activity从 Pause状态转换到 Active 状态时被调用
super.onResume();
GetData();
adapter.notifyDataSetChanged();//通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容
}
public void GetData() {
SQLiteDatabase db = helper.getReadableDatabase();//声明并打开数据库
if (db.isOpen()) {
users = new ArrayList<User>();//users表示一个arraylist
Cursor cursor = db.query("users", new String[] { "*" }, null, null,
null, null, null);//cursor是行的集合
//			Cursor cursor = db.rawQuery("select * from users", null);
while (cursor.moveToNext()) {//cursor必须调用moveToNext()方法才能开始取数据,需要使用while循环
User u = new User();
//返回指定列的索引,从0开始,如果不存在返回-1
int idIndex = cursor.getColumnIndex("_id");
int nameIndex = cursor.getColumnIndex("name");
int phoneIndex = cursor.getColumnIndex("phone");
int addressIndex = cursor.getColumnIndex("address");
//通过cursor获取数据,使用getInt(),getString()
int id = cursor.getInt(idIndex);
String name = cursor.getString(nameIndex);
String phone = cursor.getString(phoneIndex);
String address = cursor.getString(addressIndex);
//给列表u赋值
u.setId(id);
u.setName(name);
u.setPhone(phone);
u.setAddress(address);
users.add(u);//把u添加到list中
}
cursor.close();//关闭游标
db.close();//关闭数据库
}
}
// 继承BaseAdapter
public class MyBaseAdapter extends BaseAdapter {
//LayoutInflater,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)
private LayoutInflater inflater;

public MyBaseAdapter() {
inflater = getLayoutInflater();//获得 LayoutInflater 实例
//			inflater = LayoutInflater.from(UserListActivity.this);
}

@Override
public int getCount() {
return users.size();
}

@Override
public Object getItem(int position) {
return users.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh=null;
//ViewHolder作用就是一个临时的储存器,把你getView方法中每次返回的View存起来,可以下次再用。这样做的好处就是不必每次都到布局文件中去拿到你的View
// 判断concertView是否存在
if (convertView == null) {
//将布局填充进来
convertView = inflater.inflate(R.layout.item, null);
vh = new ViewHolder();
// 获取convertView视图下的布局id
vh.id = (TextView) convertView.findViewById(R.id.id);
vh.name = (TextView) convertView.findViewById(R.id.name);
vh.phone = (TextView) convertView.findViewById(R.id.phone);
vh.address = (TextView) convertView.findViewById(R.id.address);
convertView.setTag(vh);  // viewHolder打上标签
// concertView存在则将view重新赋给viewHolder
} else {
vh = (ViewHolder) convertView.getTag();
}
User user = users.get(position);
int id = user.getId();
vh.id.setText(id+"");
vh.name.setText(user.getName());
vh.phone.setText(user.getPhone());
vh.address.setText(user.getAddress());

return convertView;
}

}

public class ViewHolder {
public TextView id;
public TextView name;
public TextView phone;
public TextView address;
}

@Override
//上下文菜单:选择某项后长按键,就会显示出来
//菜单项响应事件
public boolean onContextItemSelected(MenuItem item) {
//菜单项获取上下文
AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
int position = menuInfo.position;
User user = users.get(position);
switch (item.getItemId()) {
case 1:
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"
+ user.getPhone()));
startActivity(intent);//拨打电话
break;
case 2:
Intent sendIntent = new Intent(Intent.ACTION_SENDTO,
Uri.parse("smsto:" + user.getPhone()));
sendIntent.putExtra("sms_body", "");
startActivity(sendIntent);//发送短信
break;
case 3:
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);//剪切板
ClipData clipData = ClipData.newPlainText("phone", user.getPhone());
clipboardManager.setPrimaryClip(clipData);//编辑
break;
case 4:
Intent intent2 = new Intent(UserListActivity.this,
UpdateActivity.class);
intent2.putExtra("id", user.getId());
startActivity(intent2);//修改
break;
case 5:
final int id=user.getId();
AlertDialog.Builder deletebuilder = new AlertDialog.Builder(this);
deletebuilder.setTitle("删除联系人");
deletebuilder.setMessage("要删除" + user.getName() + "吗?");
deletebuilder.setPositiveButton("确定",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

SQLiteDatabase db = helper.getWritableDatabase();//打开数据库
if (db.isOpen()) {
if (db.delete("users", "_id=?",new String[] { id+"" }) > 0) {

Toast.makeText(UserListActivity.this,"成功删除", 2000).show();
} else
Toast.makeText(UserListActivity.this,"删除失败", 2000).show();
db.close();//数据库关闭
}
GetData();//重新获取数据
adapter.notifyDataSetChanged();
}
});
deletebuilder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog,int which) {

}
});
deletebuilder.create().show();
break;
}
return super.onContextItemSelected(item);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
//第一个int类型的group ID参数,代表的是组概念,你可以将几个菜单项归为一组,以便更好的以组的方式管理你的菜单按钮。
//	       第二个int类型的item ID参数,代表的是项目编号。这个参数非常重要,一个item ID对应一个menu中的选项。在后面使用菜单的时候,就靠这个item ID来判断你使用的是哪个选项。
//	       第三个int类型的order ID参数,代表的是菜单项的显示顺序。默认是0,表示菜单的显示顺序就是按照add的显示顺序来显示。
//	       第四个String类型的title参数,表示选项中显示的文字。
menu.add(1, 1, 1, "呼叫");
menu.add(1, 2, 1, "发消息");
menu.add(1, 3, 1, "复制");
menu.add(1, 4, 1, "编辑");
menu.add(1, 5, 1, "删除");
}
}


AddActivity.java

package com.example.sqlitedemo;

import android.os.Bundle;
import android.app.Activity;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class AddActivity extends Activity {

private EditText etName, etPhone, etAddress;
private Button btnOK,btnCancel;
private MyOpenHelper helper;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
etName = (EditText) findViewById(R.id.et_Name);
etPhone = (EditText) findViewById(R.id.et_Phone);
etAddress = (EditText) findViewById(R.id.et_Address);
btnOK = (Button) findViewById(R.id.btn_OK);
btnCancel = (Button) findViewById(R.id.btn_Cancel);
helper = new MyOpenHelper(this);
btnOK.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
Log.i("MSG", "add");
AddUser();
}

});
btnCancel.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
finish();
}

});
}
private void AddUser() {
SQLiteDatabase db=	helper.getReadableDatabase();
ContentValues cv = new ContentValues();
cv.put("name", etName.getText().toString());
cv.put("phone", etPhone.getText().toString());
cv.put("address", etAddress.getText().toString());
long result = db.insert("users", null, cv);
Log.i("MSG", etName.getText().toString());
db.close();
finish();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.add, menu);
return true;
}

}


UpdateActivity.java

package com.example.sqlitedemo;

import android.os.Bundle;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class UpdateActivity extends Activity {

private EditText etName, etPhone, etAddress;
private Button btnOK,btnCancel;
private int id;
private MyOpenHelper helper;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
etName = (EditText) findViewById(R.id.etName);
etPhone = (EditText) findViewById(R.id.etPhone);
etAddress = (EditText) findViewById(R.id.etAddress);
btnOK = (Button) findViewById(R.id.btnOK);
btnCancel = (Button) findViewById(R.id.btnCancel);
Intent intent = this.getIntent();
id = intent.getIntExtra("id", 1);
helper = new MyOpenHelper(this);
SQLiteDatabase db = helper.getReadableDatabase();
String name = "", phone = "", address = "";
if (db.isOpen()) {
Cursor cursor = db.query("users", new String[] { "*" }, "_id=?",
new String[] { id + "" }, null, null, null);

if (cursor.getCount() > 0) {
if (cursor.moveToNext()) {
name = cursor.getString(cursor.getColumnIndex("name"));
phone = cursor.getString(cursor.getColumnIndex("phone"));
address = cursor
.getString(cursor.getColumnIndex("address"));
etName.setText(name);
etPhone.setText(phone);
etAddress.setText(address);
}
}
cursor.close();
}
db.close();
btnOK.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
UpdateUser();
}

});
btnCancel.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
finish();
}

});
}

public void UpdateUser() {
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", etName.getText().toString());
contentValues.put("phone", etPhone.getText().toString());
contentValues.put("address", etAddress.getText().toString());
int count = db.update("users", contentValues, "_id=?",
new String[] { id + "" });
db.close();
finish();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.update, menu);
return true;
}

}


User.java

package com.example.sqlitedemo;

public class User {
private int id;
private String name;
private String phone;
private String address;

public User(){

}
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 getPhone()
{
return phone;
}
public void setPhone(String phone)
{
this.phone=phone;
}
public String getAddress()
{
return address;
}
public void setAddress(String address)
{
this.address=address;
}
}


数据库中的图
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: