Android通讯录的制作有很多种方式,网上大部分也都有了,但是用数据库制作通讯录的却少之又少,这里我就制作一个简单的app供大家学习
首先打开app会有一个全屏的闪屏效果
//全屏显示welcome画面
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.start);
//延迟一秒后执行run方法中的页面跳转
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = newIntent(TongXunLuActivity.this, List.class);
startActivity(intent);
TongXunLuActivity.this.finish();
}
}, 1000);
接下来就是对数据库的管理了,关于这部分我前面也做了详细的讲解http://blog.csdn.net/mxcsdn/article/details/50974683,也就是增删该查,这里我就不做过多的解释了
StudentDAO.Java
package com.abc.sqlite;
import java.util.ArrayList;
import java.util.List;
import com.abc.entity.Student;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class StudentDAO {
/**
* 对数据库的增删改查
*/
private DBOpenHelper helper;//SQLiteOpenHelper实例对象
private SQLiteDatabase db;//数据库实例对象
public StudentDAO(Context context) {
helper = new DBOpenHelper(context);
}
public void add(Student student) {
// 增删改查
db = helper.getWritableDatabase();// 链接数据库
db.execSQL("insert into tb_student values(?,?,?,?)", new String[] {
student.getId(), student.getName(), student.getSpeciality(),
student.getQq() });
db.close();
}
/**
* // 添加数据
*
* @param student
*/
public void addContentValues(Student student) {
db = helper.getWritableDatabase();
ContentValues cv = new ContentValues();
//ContentValues 和HashTable类似都是一种存储的机制 但是两者最大的区别就在于,contenvalues只能存储基本类型的数据,
//像string,int之类的,不能存储对象这种东西,而HashTable却可以存储对象。
cv.put("Id", student.getId());
cv.put("Name", student.getName());
cv.put("Speciality", student.getSpeciality());
cv.put("Qq", student.getQq());
db.insert("tb_student", null, cv);
db.close();
}
/**
* 1、查询所有student数据rawQuery方法
*
* @return
*/
public List quereyTable() {
List listStudents = new ArrayList();
db = helper.getReadableDatabase();
// 显示视图
Cursor cursor = db.rawQuery("select * from tb_student", null);
// 挨个遍历
while (cursor.moveToNext()) {
Student student = new Student();
student.setId(cursor.getString(0));
student.setName(cursor.getString(1));
student.setSpeciality(cursor.getString(2));
student.setQq(cursor.getString(3));
// 添加到集合
listStudents.add(student);
db.close();
}
return listStudents;
}
/**
* // 查询单个student数据
*
* @param student
* @return
*/
public Student quereyStudentRaw(Student student) {
// Student student1 = new Student();
db = helper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from tb_student where Id=?",
new String[] { student.getId() });// 用数组填充占位符
//要创建一个Cursor(游标),必须执行一个查询,通过SQL使用rawQuery()方法或是更精心的query()方法,而不能使用execSQL(String sql)方法。
while (cursor.moveToNext()) {
student.setId(cursor.getString(cursor.getColumnIndex("id")));// 返回指定列的名称,如果不存在返回-1
// student.setId(cursor.getString(0));
student.setName(cursor.getString(1));
student.setSpeciality(cursor.getString(2));
student.setQq(cursor.getString(3));
db.close();
}
return student;
}
/**
* 2、查询所有student数据query方法
*
* @return
*/
public List queryAll(Student student) {
List sList = new ArrayList();
db = helper.getWritableDatabase();
Cursor cursor = db.query("tb_student", null, null, null, null, null,
null);
while (cursor.moveToNext()) {
Student student1 = new Student(cursor.getString(0),
cursor.getString(1), cursor.getString(2),
cursor.getString(3));
sList.add(student1);
}
return sList;
}
/**
* 2、查询单个student数据query方法
*
* @return
*/
public Student quereyStuden(Student student) {
db = helper.getReadableDatabase();
Cursor cursor=db.query("tb_student", null, "id=?", new String[] { student.getId() }, null, null, null);
//Cursor cursor = db.query("select * from tb_student where Id=?",
// new String[] { student.getId() });
//要创建一个Cursor(游标),必须执行一个查询,通过SQL使用rawQuery()方法或是更精心的query()方法,而不能使用execSQL(String sql)方法。
while (cursor.moveToNext()) {
student.setId(cursor.getString(cursor.getColumnIndex("id")));// 返回指定列的名称,如果不存在返回-1
// student.setId(cursor.getString(0));
student.setName(cursor.getString(1));
student.setSpeciality(cursor.getString(2));
student.setQq(cursor.getString(3));
db.close();
}
return student;
}
public int getCount() {
// TODO 自动生成的方法存根
return 0;
}
/*
* 修改数据库方法一
*/
public void upDate(Student student) {
db = helper.getWritableDatabase();
db.execSQL(
"update tb_student set Name=?,Speciality=?,Qq=? where Id=?",
new String[] { student.getName(), student.getSpeciality(),student.getQq(),student.getId()});
db.close();
}
/*public void delete(String id) {
// TODO 自动生成的方法存根
db = helper.getWritableDatabase();
Student student = new Student();
db.delete("tb_student", "Id=?", new String[]{student.getId()});
db.close();
}*/
public int delete(String id) {
// TODO 自动生成的方法存根
db = helper.getWritableDatabase();
Student student = new Student();
int count=db.delete("tb_student", "Id=?", new String[]{student.getId()});
db.close();
return count;
}
}
接下来是对每个student数据内容的解析现实
Service.java
package com.abc.sqlite;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import android.util.Xml;
import com.abc.entity.Student;
public class Service {
/**
* 对每个student数据内容的解析现实
*/
private Context context;
public Service(Context context) {
super();
this.context = context;
}
public List parserXml(String filesName) throws IOException,
XmlPullParserException {
List students=new ArrayList();
Student student=null;//初始化一个对象
AssetManager aManage = context.getAssets();
InputStream is = null;//1、获取解析文本
XmlPullParser parser =null;
is=aManage.open(filesName);
parser= Xml.newPullParser();// 2、创建一个解析器对象
parser.setInput(is, "utf-8");// 设置输入字节流与编码格式
int event = parser.getEventType();// 3、取得事件类型,用于开始解析时的判断
while (event!=XmlPullParser.END_DOCUMENT) {
switch (event) {
/* case XmlPullParser.START_DOCUMENT:
break;*/
case XmlPullParser.START_TAG:
if ("student".equalsIgnoreCase(parser.getName())) {//判断节点值是否相同
student=new Student();
student.setId(parser.getAttributeValue(0));//获取student的第一个属性 **********
Log.v("ID", "55555555555555555555555");
break;//while循环结束
}
if (student!=null) {//判断student节点下的文本节点是否为空
if ("name".equalsIgnoreCase(parser.getName())) {
student.setName(parser.nextText());//nextText获取具体的数据内容*************
Log.v("name", "&&&&&&&&&&&&&&&&&&&&&&&&");
}
if ("speciality".equalsIgnoreCase(parser.getName())) {
student.setSpeciality(parser.nextText());//nextText获取具体的数据内容*************
Log.v("speciality","????????????????????");
}
if ("qq".equalsIgnoreCase(parser.getName())) {
student.setQq(parser.nextText());//nextText获取具体的数据内容*************
Log.v("qq", "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
}
}
break;
case XmlPullParser.END_TAG:
if ("student".equalsIgnoreCase(parser.getName())) {
students.add(student);//讲解析的一个student对象添加到集合中去
student=null;//student置空
Log.v("END_TAG", "END_TAG");
}
break;
default:
break;
}
event = parser.next();//获取下一个事件类型
}
if(is !=null){
is.close();
}
return students;
}
}
接下来是数据内容位置的填充,并对增删改查进行监听事件,这里的删除出现了一个问题不能够实现,如有高见还请分享一下
StudentDetile.java
package com.abc.entity;
import com.abc.sqlite.StudentDAO;
import com.abc.tong.List;
import com.abc.tong.R;
import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.TextView;
public class StudentDetile extends Activity implements OnClickListener {
private EditText nameText, Idn;
private EditText qqText;
private EditText specialityText;
private Button saveButton;
private Button backButton;
private Button cancelButton;
private Button callButton;
private java.util.List sListQuery1=null;
StudentDAO studentDAO = new StudentDAO(this);// 2 创建对象 /////对数据库的增删改查
String qq;
String id;
StudentDAO studentDao = new StudentDAO(StudentDetile.this);
private Context context;
private java.util.List students;
Student student;
public StudentDetile() {
super();
}
public StudentDetile(Context context, java.util.List students) {
super();
this.context = context;
this.students = students;
}
protected void onCreate(Bundle savedInstanceState) {
// TODO 自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.student_detile);
Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("bundle");
String name = bundle.getString("strName");
qq = bundle.getString("strQq");
String speciality = bundle.getString("strSpeciality");
id = bundle.getString("strId");
nameText = (EditText) findViewById(R.id.EditName);
qqText = (EditText) findViewById(R.id.EditQq);
specialityText = (EditText) findViewById(R.id.EditSpeciality);
Idn = (EditText) findViewById(R.id.EditId);
saveButton = (Button) findViewById(R.id.update);
cancelButton = (Button) findViewById(R.id.delete);
backButton = (Button) findViewById(R.id.call);
callButton = (Button) findViewById(R.id.back);
saveButton.setOnClickListener(this);
cancelButton.setOnClickListener(this);
backButton.setOnClickListener(this);
callButton.setOnClickListener(this);
/* Idn.setText("学 号:" + id);
nameText.setText("姓 名:" + name);
qqText.setText("Q Q:" + qq);
specialityText.setText("宿 舍:" + speciality);*/
Idn.setText(id);
nameText.setText( name);
qqText.setText(qq);
specialityText.setText(speciality);
}
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(StudentDetile.this, List.class);
switch (v.getId()) {
case R.id.update:
android.content.DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
student = new Student(id, nameText.getText()
.toString().trim(), qqText.getText().toString()
.trim(), specialityText.getText().toString().trim());
updateStudent(student);
/*student.setName(student.getName()+1);
updateStudent(student);*/
Intent intent = new Intent(StudentDetile.this, List.class);
startActivity(intent);
}
};
// 创建对话框
Builder builder = new Builder(this);
builder.setTitle("确定要修改吗?");// 设置标题
builder.setPositiveButton("确定", listener);// 设置确定按钮的文本以及监听
builder.setNegativeButton("取消", null);
builder.show();// 显示对话框
break;
case R.id.delete:
// 删除数据之前首先弹出一个对话框
android.content.DialogInterface.OnClickListener listener1 = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO 自动生成的方法存根
sListQuery1=studentDAO.quereyTable();
student = new Student(Idn.getText().toString(), nameText.getText()
.toString().trim(), qqText.getText().toString()
.trim(), specialityText.getText().toString().trim());
//sListQuery1.remove(student);//从集合中删除
studentDao.delete(student.getId());// 从数据库中删除 no
Intent intent = new Intent(StudentDetile.this, List.class);
startActivity(intent);
}
};
// 创建对话框
Builder builder1 = new Builder(this);
builder1.setTitle("确定要删除吗?");// 设置标题
builder1.setPositiveButton("确定", listener1);// 设置确定按钮的文本以及监听
builder1.setNegativeButton("取消", null);
builder1.show();// 显示对话框
break;
case R.id.back:
startActivity(intent);
break;
case R.id.call:
Intent it = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + qq));
startActivity(it);
//StudentDetile.this.startActivity(it);
default:
break;
}
}
private void updateStudent(Student student) {
// TODO 自动生成的方法存根
studentDao.upDate(student);
}
}
接下来自定义一个适配器,进行界面数据的绑定,并在list方法中实现,这里对list进行了一个长按点击事件——打电话
CustomAdapter.java
package com.abc.adapter;
import java.util.ArrayList;
import java.util.List;
import com.abc.entity.Student;
import com.abc.sqlite.Service;
import com.abc.tong.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomAdapter extends BaseAdapter {
private List sList;
/*private int icons[]={R.drawable.ic_launcher,R.drawable.ic_launcher,
R.drawable.ic_launcher,R.drawable.ic_launcher,R.drawable.ic_launcher,
R.drawable.ic_launcher,R.drawable.ic_launcher,R.drawable.ic_launcher};*/
private Context context;
public CustomAdapter(List sList, Context context) {
super();
this.sList = sList;
this.context = context;
}
//sList=service.parserXml("text.xml");
@Override
public int getCount() {
// 返回ListView的Item条目 的总数
return sList.size();// 返回集合
// return strStudent.length;//返回数组
}
@Override
public Object getItem(int position) {
// 返回ListView的Item条目 代表的对象
return sList.get(position);// 返回集合
//return strStudent[position];//返回数组
}
@Override
public long getItemId(int position) {
// 返回ListView的Item条目 的id
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 将自定义的list_item.xml文件找出来并转换成View对象
//Android ListView中每显示出一条item的时候,都会自动的调用BaseAdapter.getView(int position, View convertView, ViewGroup parent)方法。
/*
* View.inflate(context, resource, root);
*
* resource: 布局文件的id,比如R.layout.layout_menu_item
* root:这是一个可选参数,resource布局文件中layout_
* *参数设置的参照物就是这个root,也就是说inflate方法会根据这个root的大小,
* 将resource布局文件中layout_*参数转换成一个LayoutParam对象
*/
// LayoutInflater inflate = LayoutInflater.from(context);
View view=View.inflate(context, R.layout.list_item,null );
//特别注意此时context不能写this,或CustomAdapter。this,因为此时的上下文是List.java
TextView nameText=(TextView) view.findViewById(R.id.text_name);
TextView qqText=(TextView) view.findViewById(R.id.text_qq);
TextView specialityText=(TextView) view.findViewById(R.id.text_speciality);
nameText.setText((CharSequence)sList.get(position).getName());
qqText.setText((CharSequence)sList.get(position).getQq());
specialityText.setText((CharSequence)sList.get(position).getSpeciality());
ImageView imageView=(ImageView) view.findViewById(R.id.imageView);
//imageView.setBackgroundResource(icons[position]);//数组过多就不写了,但是它默认会配上图片
return view;
}
}
List.java
package com.abc.tong;
import java.io.IOException;
import org.xmlpull.v1.XmlPullParserException;
import com.abc.adapter.CustomAdapter;
import com.abc.entity.Student;
import com.abc.entity.StudentDetile;
import com.abc.sqlite.Service;
import com.abc.sqlite.StudentDAO;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
public class List extends Activity implements OnItemLongClickListener {
private Student student = null;
private java.util.List sList = null;
private java.util.List sListQuery = null;
private ListView listv;
private EditText nameText, Idn;
private EditText qqText;
private EditText specialityText;
String strQq;
@Override
// 当退出app时弹出对话框
// 但是这个退出程序,可能并未完全退出,如果你进入管理APP界面,会看到程序仍在运行。如果想完全退出程序,需要进行进一步处理。
public boolean onKeyDown(int keyCode, KeyEvent event) {
// 如果是返回键,直接返回到桌面
if (keyCode == KeyEvent.KEYCODE_BACK) {
showExitGameAlert();
}
return super.onKeyDown(keyCode, event);
}
private void showExitGameAlert() {
Builder a = new AlertDialog.Builder(List.this);
a.setMessage("确定退出通讯录吗")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(0);
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).show();
}
protected void onCreate(Bundle savedInstanceState) {
// TODO 自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.list_contacts);
nameText = (EditText) findViewById(R.id.EditName);
qqText = (EditText) findViewById(R.id.EditQq);
specialityText = (EditText) findViewById(R.id.EditSpeciality);
Idn = (EditText) findViewById(R.id.EditId);
listv = (ListView) findViewById(R.id.list);
Service service = new Service(this);// 1 创建对象 /////对每个student数据内容的解析现实
try {
sList = service.parserXml("text.xml");
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
String[] strStudent = new String[sList.size()];// 初始化数组大小
StudentDAO studentDAO = new StudentDAO(this);// 2 创建对象 /////对数据库的增删改查
// huoqu yianjia xianshi
int i = 0;// 定义一个开始标识
for (Student student : sList) {
strStudent[i] = student.getId() + student.getName()
+ student.getQq() + student.getSpeciality();
studentDAO.addContentValues(student);// 将每一个student添加到studentDAO
// studentDAO.addContentValues(sList.get(i));//
// 将每一个student添加到studentDAO
i++;// ***************************
}
// sListQuery=studentDAO.queryAll(student);//从数据库查询出所有数据,此方法有bug
sListQuery = studentDAO.quereyTable();
CustomAdapter adapter = new CustomAdapter(sListQuery,
getApplicationContext());
/*
* ArrayAdapter adapter = new ArrayAdapter(this,
* android.R.layout.simple_expandable_list_item_1, strStudent);
*/// 数据集合
listv.setAdapter(adapter);
listv.setOnItemLongClickListener(this);
listv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view,
int position, long id) {
// TODO 自动生成的方法存根
// String strinfo=(String) ((TextView)view).getText();
/*
* String strId=strinfo.substring(0,strinfo.indexOf("888888"));
* String
* strName=strinfo.substring(1,strinfo.indexOf("8888888"));
* String
* strSpeciality=strinfo.substring(2,strinfo.indexOf("6666666"
* )); String
* strQq=strinfo.substring(3,strinfo.indexOf("6666666"));
*/
// 获取点击内容
/*
* String strId=Idn.getText().toString().trim(); String
* strName=nameText.getText().toString().trim(); String
* strSpeciality=specialityText.getText().toString().trim();
* String strQq=qqText.getText().toString().trim();
*
* Idn.setText("姓 名:"+strId); nameText.setText("姓 名:"+strName);
* qqText.setText("Q Q:"+strQq);
* specialityText.setText("宿 舍:"+strSpeciality);
*/
String strId = sListQuery.get(position).getId();
String strName = sListQuery.get(position).getName();
String strSpeciality = sListQuery.get(position).getSpeciality();
strQq = sListQuery.get(position).getQq();
Intent intent = new Intent(List.this, StudentDetile.class);
// Student stu_intent=new Student();
Bundle bundle = new Bundle();
bundle.putString("strId", strId);
bundle.putString("strQq", strQq);
bundle.putString("strName", strName);
bundle.putString("strSpeciality", strSpeciality);
intent.putExtra("bundle", bundle);
startActivity(intent);
}
});
}
public boolean onItemLongClick(AdapterView> arg0, View view,
int position, long arg3) {
// TODO 自动生成的方法存根
strQq = sListQuery.get(position).getQq();
Log.e("mxmxmxmmxmxmxmxmm", view.toString() + "position=" + position);
Intent it = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + strQq));
// Intent it = new Intent(List.this, StudentDetile.class);
List.this.startActivity(it);
return true;// 为了区分点击事件和长按事件,长按事件里的return false; 改为true就好了
}
}
部分简单代码与布局文件在这里就不贴出来了,水滴石穿。
在这里分享一下源码,项目源码下载