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

<pre name="code" class="html">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<Student> quereyTable() {List<Student> listStudents = new ArrayList<Student>();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<Student> queryAll(Student student) {List<Student> sList = new ArrayList<Student>();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<Student> parserXml(String filesName) throws IOException,XmlPullParserException {  List<Student> students=new ArrayList<Student>();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<Student> 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<Student> students;Student student;public StudentDetile() {super();}public StudentDetile(Context context, java.util.List<Student> 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 stubIntent intent = new Intent(StudentDetile.this, List.class);switch (v.getId()) {case R.id.update:android.content.DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {@Overridepublic 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() {@Overridepublic 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());// 从数据库中删除 noIntent 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<Student> 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<Student> sList, Context context) {super();this.sList = sList;this.context = context;}//sList=service.parserXml("text.xml");@Overridepublic int getCount() {// 返回ListView的Item条目 的总数return sList.size();// 返回集合// return strStudent.length;//返回数组}@Overridepublic Object getItem(int position) {// 返回ListView的Item条目 代表的对象return sList.get(position);// 返回集合//return strStudent[position];//返回数组}@Overridepublic long getItemId(int position) {// 返回ListView的Item条目 的idreturn position;}@Overridepublic 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.javaTextView 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<Student> sList = null;private java.util.List<Student> 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {System.exit(0);}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic 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 xianshiint 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添加到studentDAOi++;// ***************************}// sListQuery=studentDAO.queryAll(student);//从数据库查询出所有数据,此方法有bugsListQuery = studentDAO.quereyTable();CustomAdapter adapter = new CustomAdapter(sListQuery,getApplicationContext());/* * ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, * android.R.layout.simple_expandable_list_item_1, strStudent); */// 数据集合listv.setAdapter(adapter);listv.setOnItemLongClickListener(this);listv.setOnItemClickListener(new OnItemClickListener() {@Overridepublic 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就好了}}
部分简单代码与布局文件在这里就不贴出来了,水滴石穿。

在这里分享一下源码,项目源码下载

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. 一句话锁定MySQL数据占用元凶
  3. Android(安卓)WebSettings设置
  4. Android单元测试-Robolectric 浅析
  5. 关于android应用--内存的优化
  6. Android(安卓)数据库创建字段时的数据类型
  7. App Widget(Application Widget)第一讲(Android学习随笔十)
  8. Android中的自定义注解(反射实现-运行时注解)
  9. ExpandableListView的用法

随机推荐

  1. Android实现音乐播放 Music 详解
  2. Android(安卓)判断、创建和删除快捷方式
  3. android之JSON解析(二)
  4. Ubuntu13.04环境下载、编译Android源代码
  5. node.js+android(使用HttpURLConnection
  6. Android(安卓)Activty使用示例【慢慢更新
  7. [cocos2dx] cocosdx编译工程那些事
  8. receiver定制自动启动一个程序
  9. Android(安卓)使用RadioGroup和RadioButt
  10. Android驱动入门-在Android系统上运行JAV