标签:
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 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<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"); @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<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() { @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<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() { @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就好了 } }部分简单代码与布局文件在这里就不贴出来了,水滴石穿。
在这里分享一下源码,项目源码下载
标签:
原文地址:http://blog.csdn.net/mxcsdn/article/details/51345539