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

来源:互联网 发布:淘宝成交指数 编辑:程序博客网 时间:2024/05/22 08:18

数据库用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;//通讯录listviewprivate MyOpenHelper helper;//声明一个MyOpenHelper对象private List<User> users;//通讯录列表private MyBaseAdapter adapter;//适配器@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.user_list);add = (ImageButton) findViewById(R.id.add);//从布局文件中获取绑定控件listView = (ListView) findViewById(R.id.listView);helper = new MyOpenHelper(this);//创建数据库 需要调用  getReadableDatabase 或 getWritableDatabaseGetData();//调用下方GetData();if (users != null) {//只要数据表名不为空adapter = new MyBaseAdapter(); //初始化适配器  listView.setAdapter(adapter);//设置adapter}this.registerForContextMenu(listView);//为所有列表项注册上下文菜单 add.setOnClickListener(new OnClickListener() {//按钮监听事件@Overridepublic void onClick(View v) {Intent intent = new Intent(UserListActivity.this,AddActivity.class);//点击加号跳到添加页面startActivity(intent);//开启intent}});}@Overrideprotected 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表示一个arraylistCursor 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开始,如果不存在返回-1int 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);}@Overridepublic int getCount() {return users.size();}@Overridepublic Object getItem(int position) {return users.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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() {@Overridepublic 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();} elseToast.makeText(UserListActivity.this,"删除失败", 2000).show();db.close();//数据库关闭}GetData();//重新获取数据adapter.notifyDataSetChanged();}});deletebuilder.setNegativeButton("取消",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {}});deletebuilder.create().show();break;}return super.onContextItemSelected(item);}@Overridepublic 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;@Overrideprotected 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() {@Overridepublic void onClick(View v) {Log.i("MSG", "add");AddUser();}});btnCancel.setOnClickListener(new View.OnClickListener() {@Overridepublic 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();}@Overridepublic 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;@Overrideprotected 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() {@Overridepublic void onClick(View v) {UpdateUser();}});btnCancel.setOnClickListener(new View.OnClickListener() {@Overridepublic 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();}@Overridepublic 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;}}

数据库中的图