精华内容
下载资源
问答
  • android项目之通讯录数据库

    千次阅读 2016-05-08 14:51:29
    Android通讯录的制作有很多种方式,网上大部分也都有了,但是用数据库制作通讯录的却少之又少,这里我就制作一个简单的app供大家学习 先看一下效果图,在下面有提供项目源码 首先打开app会有一个全屏的闪屏效果 ...

      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就好了
    	}
    
    }
    
    部分简单代码与布局文件在这里就不贴出来了,水滴石穿。

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

     

     

     

     

     

    展开全文
  • 1.文件夹txl1中的是用PB自带数据库创建通讯录,基本没问题。 2.文件夹txl2中的是用Kingbase数据库创建通讯录,存在如下问题: 我已将需要用的TXL数据库备份到txl2文件夹中,可直接导入使用;先修改连接数据库...
  • printf("**选择:1 创建通讯录 \n"); printf("**选择:2 查找联系人 \n"); printf("**选择:3 删除联系人 \n"); printf("**选择:4 添加联系人 \n"); printf("**选择:5 对联系人排序 \n"); printf(...
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<string.h>
    #include <sqlite3.h>


    #define len sizeof(struct Node)
    #define ERROR   1
    #define OK      0
    void inquire_nocb(sqlite3 *db);
    void inquire_usecb(sqlite3 * db);


    struct Node
    {
    char name[30];
        char data[30];
        struct Node *next;
    };
    typedef struct Node  LinkList; /* 定义LinkList */




    /* 初始化顺序线性表生成一个头
    返回head */
    LinkList * InitList() 

    LinkList *head;
       head=(LinkList *)malloc(len);  /* 产生头结点,并使L指向此头结点 */
       if(head==NULL)     /* 存储分配失败 */
        printf("malloc is not good");
       head->next=NULL;   /* 指针域为空 */
       return head;
    }
    /*数据的输出打印*/
    void print(LinkList *head)
    {
    LinkList *p;
    p=head->next;
    if(p==NULL)
    printf("this is empty\n");
    while(p!=NULL)
    {
    printf("姓名: %-10s 号码: %-10s\n",p->name,p->data);
    p=p->next;
    }
    }




    /*  初始化后   数据添加   采用(头插法) */
    LinkList * CreateListHead(LinkList *head) 
    {
    printf("*表示输入结束\n");
    LinkList *p;
    int i;
    //head = (LinkList *)malloc(len);
    //head->next = NULL;            /*  先建立一个带头结点的单链表 */

    //p=head->next;//
    while(1)
    {
    p = (LinkList *)malloc(len); /*  生成新结点 */
    printf("请输入姓名:\n");
    scanf("%s",p->name);
    if(strcmp(p->name,"*") == 0)
    break;
    printf("请输入号码:\n");
    scanf("%s",&p->data);
    p->next = head->next;    
    head->next = p; /*  插入到表头 */
    }
    return head;
    }


    /* 删除 */
    /* 操作结果:输入要删除的  元素     进行删除 */
    LinkList * ListDelete(LinkList *head) 
    {
    LinkList *pre,*after,*p;
    p=(LinkList *)malloc(len);//插入时申请空间
    printf("请输入要删除姓名:\n");
    scanf("%s",p->name);

    pre = head;
    after=head->next;
    while(after != NULL)
    {
    if(strcmp(after->name,p->name)==0)
    {
    pre->next=after->next;
    free(after);
    break;
    }
    else
    {
    pre=after;
    after=after->next;//错误地点
    }
    }
    if(after == NULL)
    printf("this data is not exist\n");
    return head;
    }


    /* 插入 */
    /* 操作结果:把数据插在第 n 个位置 */
    LinkList * ListInsert(LinkList *head,int n)
    {
    LinkList *new,*look;;
    new=(LinkList *)malloc(len);//插入时申请空间
    printf("添加  新联系人\n");
    printf("新加  姓名:\n");
    scanf("%s",new->name);
    printf("新加  号码:\n");
    scanf("%s",&new->data);
    int count=0;
    if(head==NULL)
    {
    head=new;
    new->next=NULL;
    }

    if(n==0)
    {
    new->next=head;
    head=new;
    }
    else
    {
    look=head;
    while((look!=NULL)&&(count<n-1))
    {
    look=look->next;
    count++;
    }
    if(count==n-1)
    {
    new->next=look->next;
    look->next=new;
    }
    if(new==NULL)
    printf("out of the range,");
    }
    return head;
    }


    /*   排序*/
    /*  按照   名字    排序*/
    LinkList *ListSort(LinkList *head)
    {
    LinkList *p1,*p2,*p,*s;
    int i,j,n=1;
       s=head->next; /* s指向第一个结点 */
       while(s)        /*数元素的个数,计数...........遍历得到n*/                
        {
            n++;
            s=s->next;
           }
    p=(LinkList *)malloc(len);
    for(i=0;i<(n-1);i++)
    { p1=head;
    p2=p1->next;
    for(j=0;j<(n-i-1);j++)
    {
    if(strcmp(p1->name,p2->name)>0)
    {
    /*p->data=p1->data;
    p1->data=p2->data;
    p2->data=p->data;*/
    strcpy(p->data,p1->data);
    strcpy(p1->data,p2->data);
    strcpy(p2->data,p->data);
    strcpy(p->name,p1->name);
    strcpy(p1->name,p2->name);
    strcpy(p2->name,p->name);
    }
    p1=p2;
    p2=p2->next;
    }
    }
    return head;
    }


    /*     查找     通过名字,找到电话号码*/
    LinkList *xuzhao(LinkList *head)
    {
    LinkList *p,*x;
    p=head;
    int count=0;
    x=(LinkList *)malloc(len);//申请空间
    printf("****输入要查找姓名****\n");
    scanf("%s",x->name);
    while(1)
    {
    if( strcmp(p->name,x->name)==0 )
    {
    printf("姓名%-10s 号码:%-10s\n",p->name,p->data);
    break;
    }
    p=p->next;
    if(p==NULL)
    {
    printf("*********查无此人*************\n");
    break;
    }
    }
    }


    LinkList * xiugai(LinkList *head)
    {
    LinkList *p,*x,*q;
    p=head;
    int count=0;
    x=(LinkList *)malloc(len);
    printf("输入要修改姓名\n");
    scanf("%s",x->name);
    while(1)
    {
    if( strcmp(p->name,x->name)==0 )
    {
    break;
    }
    p=p->next;
    if(p == NULL)
    {
    printf("这个名字不存在\n");

    return head;
    }
    }
    printf("修改为:姓名   \n");

    scanf("%s",p->name);

    printf("修改为:  号码\n");

    scanf("%s",p->data);
    printf("姓名%-10s 号码:%-10s\n",p->name,p->data);
    return head;

    }
    /*桌面显示*/
    int beijing()
    {
    printf("********************************************\n");
    printf("**选择:1   创建通讯录                          \n");
    printf("**选择:2   查找联系人                        \n");
    printf("**选择:3   删除联系人                          \n");
    printf("**选择:4   添加联系人                         \n");
    printf("**选择:5   对联系人排序                      \n");
    printf("**选择:6   对联系人信息修改               \n");
    printf("**选择:0   退出编辑                           \n");
    printf("********************************************\n");
    }




    /*将数据进行保存*/
    void save(LinkList *head)
    {
    sqlite3 *db;
    char *sql;
    char sql1[100];
    char *errmsg;
    char *name;
    char *data;
    int ret;

    LinkList *p;
    FILE *fp;
    p=head->next; 
    ///
    ret=sqlite3_open("kuwenj.db",&db);
    if(ret != SQLITE_OK)
    {
    printf("open error");
    exit(1);
    }

    /
    sql="create table if not exists kuwenj(name text primary key,data text);";
    ret=sqlite3_exec(db,sql,NULL,NULL,&errmsg);
    if(ret != SQLITE_OK)
    printf("creat error");

    /
    sql="delete from kuwenj;";
    ret=sqlite3_exec(db,sql,NULL,NULL,&errmsg);
    if(ret != SQLITE_OK)
    printf("delete error\n");
    while( p != NULL)
    {
    sprintf(sql1,"insert into kuwenj values('%s','%s');",p->name,p->data);
    ret=sqlite3_exec(db,sql1,NULL,NULL,&errmsg);
    if(ret != SQLITE_OK)
    {
    printf("insert  error");
    exit(1);
    }
    p=p->next;
    }
    //inquire_nocb(db);
    inquire_usecb(db);
    sqlite3_close(db);

    }
    /*******显示数据库内部数据**************/
    void inquire_nocb(sqlite3 *db)
    {
    int nrow,ncolumn;
    char **azresult;
    char *sql;
    char *errmsg;
    int ret;
    int i;

    sql = "select * from kuwenj;";
    ret = sqlite3_get_table(db,sql,&azresult,&nrow,&ncolumn,&errmsg);
    if(ret != SQLITE_OK)
    printf("get table error:%s",errmsg);

    printf("nrow = %d,column = %d\n",nrow,ncolumn);
    for(i = ncolumn;i < (nrow + 1) * ncolumn;i++)
    {
    printf("%10s",azresult[i]);
    if((i + 1) % ncolumn == 0)
    {
    printf("\n");
    }
    }
    sqlite3_free_table(azresult);
    }


    /*数据库读入链表*/
    int displaycb(void *para,int ncolumn,char ** columnvalue,char *columnname[])
    {
    int i;
    printf("total column is %d\n",ncolumn);


    for(i = 0;i < ncolumn; i++)
    {
    printf("col_name:%s----> clo_value:%s\n",columnname[i],columnvalue[i]);
    }
    printf("===========================\n");


    return 0;
    }
    void inquire_usecb(sqlite3 * db)
    {
        char *sql;
        char *errmsg;
        int ret;


    sql = "select * from kuwenj;";


    ret = sqlite3_exec(db,sql,displaycb,NULL,&errmsg);


    if(ret != SQLITE_OK)
    {
    printf("select error : %s\n",errmsg);
    exit(-1);
    }


    }


    /*数据库存入链表中*/
    LinkList * out_liaobiao(LinkList *head)
    {
    LinkList *tmp,*p;
    int nrow,ncolumn;
    char **azresult;
    char *sql,*a[1000];
    char *errmsg;
    int ret;
    int i,j;
    sqlite3 *db;

    ret=sqlite3_open("kuwenj.db",&db);
    if(ret != SQLITE_OK)
    {
    printf("open error");
    exit(1);
    }
    sql = "select * from kuwenj;";
    ret = sqlite3_get_table(db,sql,&azresult,&nrow,&ncolumn,&errmsg);
    if(ret != SQLITE_OK)
    {
    printf("get table error:%s",errmsg);
    }

    tmp=(LinkList *)malloc(len);
    for(i=1;i<=nrow;i++)
    {

    strcpy(tmp->name,azresult[i * ncolumn]);
    strcpy(tmp->data,azresult[i * ncolumn+1]);
    tmp->next = head->next;    
    head->next = tmp;
    tmp=(LinkList *)malloc(len);
    }
    sqlite3_free_table(azresult);
    return head;
    }






    int main()
    {
    LinkList *head;
    int num;

    head=InitList();
    head=out_liaobiao(head);
    print(head); 
    while(1)
    {
    beijing();
    printf("请选择\n");
    scanf("%d",&num);
    switch(num)
    {
    case 0: save(head);
    exit(0);
    case 1: head=CreateListHead(head); 
    print(head);
    break; 
    case 2: xuzhao(head);              
    break;
    case 3: head=ListDelete(head);
    print(head); 
    break;
    case 4: head=ListInsert(head,1);
    print(head); 
    break;
    case 5: head=ListSort(head);
    print(head); 
    break;
    case 6: head=xiugai(head);
    print(head); 
    break;
    default : printf("这是错误的,请重新选择\n"); break;
    }
    }
    }
    展开全文
  • 用户关系通讯录数据库设计

    千次阅读 2014-09-24 13:12:16
    现阶段在为自己设计一个用户关系通讯录小程序,

    现阶段在为自己设计一个用户关系通讯录小程序,谈不上系统。数据库设计如下:

    详细设计如下:


    sql生成的脚本代码:

    USE [master]
    GO
    /****** Object:  Database [db_contacts]    Script Date: 09/24/2014 13:17:15 ******/
    CREATE DATABASE [db_contacts] ON  PRIMARY 
    ( NAME = N'db_contacts', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\db_contacts.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
     LOG ON 
    ( NAME = N'db_contacts_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\db_contacts_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
    GO
    ALTER DATABASE [db_contacts] SET COMPATIBILITY_LEVEL = 100
    GO
    IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
    begin
    EXEC [db_contacts].[dbo].[sp_fulltext_database] @action = 'enable'
    end
    GO
    ALTER DATABASE [db_contacts] SET ANSI_NULL_DEFAULT OFF
    GO
    ALTER DATABASE [db_contacts] SET ANSI_NULLS OFF
    GO
    ALTER DATABASE [db_contacts] SET ANSI_PADDING OFF
    GO
    ALTER DATABASE [db_contacts] SET ANSI_WARNINGS OFF
    GO
    ALTER DATABASE [db_contacts] SET ARITHABORT OFF
    GO
    ALTER DATABASE [db_contacts] SET AUTO_CLOSE OFF
    GO
    ALTER DATABASE [db_contacts] SET AUTO_CREATE_STATISTICS ON
    GO
    ALTER DATABASE [db_contacts] SET AUTO_SHRINK OFF
    GO
    ALTER DATABASE [db_contacts] SET AUTO_UPDATE_STATISTICS ON
    GO
    ALTER DATABASE [db_contacts] SET CURSOR_CLOSE_ON_COMMIT OFF
    GO
    ALTER DATABASE [db_contacts] SET CURSOR_DEFAULT  GLOBAL
    GO
    ALTER DATABASE [db_contacts] SET CONCAT_NULL_YIELDS_NULL OFF
    GO
    ALTER DATABASE [db_contacts] SET NUMERIC_ROUNDABORT OFF
    GO
    ALTER DATABASE [db_contacts] SET QUOTED_IDENTIFIER OFF
    GO
    ALTER DATABASE [db_contacts] SET RECURSIVE_TRIGGERS OFF
    GO
    ALTER DATABASE [db_contacts] SET  DISABLE_BROKER
    GO
    ALTER DATABASE [db_contacts] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
    GO
    ALTER DATABASE [db_contacts] SET DATE_CORRELATION_OPTIMIZATION OFF
    GO
    ALTER DATABASE [db_contacts] SET TRUSTWORTHY OFF
    GO
    ALTER DATABASE [db_contacts] SET ALLOW_SNAPSHOT_ISOLATION OFF
    GO
    ALTER DATABASE [db_contacts] SET PARAMETERIZATION SIMPLE
    GO
    ALTER DATABASE [db_contacts] SET READ_COMMITTED_SNAPSHOT OFF
    GO
    ALTER DATABASE [db_contacts] SET HONOR_BROKER_PRIORITY OFF
    GO
    ALTER DATABASE [db_contacts] SET  READ_WRITE
    GO
    ALTER DATABASE [db_contacts] SET RECOVERY FULL
    GO
    ALTER DATABASE [db_contacts] SET  MULTI_USER
    GO
    ALTER DATABASE [db_contacts] SET PAGE_VERIFY CHECKSUM
    GO
    ALTER DATABASE [db_contacts] SET DB_CHAINING OFF
    GO
    EXEC sys.sp_db_vardecimal_storage_format N'db_contacts', N'ON'
    GO
    USE [db_contacts]
    GO
    /****** Object:  Table [dbo].[t_user]    Script Date: 09/24/2014 13:17:16 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_PADDING ON
    GO
    CREATE TABLE [dbo].[t_user](
    	[id] [int] IDENTITY(1,1) NOT NULL,
    	[userName] [varchar](50) NOT NULL,
    	[passWord] [varchar](50) NOT NULL,
    	[tips] [varchar](500) NULL,
     CONSTRAINT [PK_t_user] PRIMARY KEY CLUSTERED 
    (
    	[id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    SET ANSI_PADDING OFF
    GO
    /****** Object:  Table [dbo].[t_relationship]    Script Date: 09/24/2014 13:17:16 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_PADDING ON
    GO
    CREATE TABLE [dbo].[t_relationship](
    	[id] [int] IDENTITY(1,1) NOT NULL,
    	[relation] [varchar](10) NOT NULL,
     CONSTRAINT [PK_t_relationship] PRIMARY KEY CLUSTERED 
    (
    	[id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    SET ANSI_PADDING OFF
    GO
    /****** Object:  Table [dbo].[t_contact]    Script Date: 09/24/2014 13:17:16 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_PADDING ON
    GO
    CREATE TABLE [dbo].[t_contact](
    	[id] [int] IDENTITY(1,1) NOT NULL,
    	[xingMing] [varchar](50) NULL,
    	[gender] [varchar](4) NULL,
    	[birthday] [date] NULL,
    	[iidentityNumber] [char](18) NULL,
    	[nickName] [varchar](20) NULL,
    	[photo] [varchar](100) NULL,
    	[originalPlace] [varchar](50) NULL,
    	[email] [varchar](100) NULL,
    	[mobileNumber] [char](11) NULL,
    	[address] [varchar](500) NULL,
    	[education] [varchar](50) NULL,
    	[company] [varchar](100) NULL,
    	[QQ] [varchar](20) NULL,
    	[wechat] [varchar](50) NULL,
    	[weibo] [varchar](50) NULL,
    	[twitter] [varchar](50) NULL,
    	[facebook] [varchar](50) NULL,
    	[contactOf] [int] NOT NULL,
    	[relationship] [int] NOT NULL,
     CONSTRAINT [PK_t_contact] PRIMARY KEY CLUSTERED 
    (
    	[id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    SET ANSI_PADDING OFF
    GO
    /****** Object:  ForeignKey [FK_t_contact_t_relationship]    Script Date: 09/24/2014 13:17:16 ******/
    ALTER TABLE [dbo].[t_contact]  WITH CHECK ADD  CONSTRAINT [FK_t_contact_t_relationship] FOREIGN KEY([relationship])
    REFERENCES [dbo].[t_relationship] ([id])
    GO
    ALTER TABLE [dbo].[t_contact] CHECK CONSTRAINT [FK_t_contact_t_relationship]
    GO
    /****** Object:  ForeignKey [FK_t_contact_t_user1]    Script Date: 09/24/2014 13:17:16 ******/
    ALTER TABLE [dbo].[t_contact]  WITH CHECK ADD  CONSTRAINT [FK_t_contact_t_user1] FOREIGN KEY([contactOf])
    REFERENCES [dbo].[t_user] ([id])
    GO
    ALTER TABLE [dbo].[t_contact] CHECK CONSTRAINT [FK_t_contact_t_user1]
    GO
    

    
    
    下一个阶段就准备用Java Swing做出一个demo版本。一个星期完成吧。10月1日续写博客。

    展开全文
  • Android通讯录数据库介绍与基本操作(增删改查) 2014年2月21日 Android通讯录管理总结 这几天导师安排我一个任务就是研究一下Android通讯录获取联系人、通话记录、短信的方法,还有看看不同Android...

    Android通讯录数据库介绍与基本操作(增删改查)


    2014年2月21日 Android通讯录管理总结

    这几天导师安排我一个任务就是研究一下Android通讯录获取联系人、通话记录、短信的方法,还有看看不同Android版本之间的异同是否能做到兼容之类的事情。Android通讯录这一块,我个人感觉是挺乱的,网上一堆关于查询本地数据库获取联系人的方法,但似乎都没有仔细说明数据有哪些重要的表,它们之间有什么联系。下面是本人查询资料总结的一下知识点,方便童鞋们以后用到。



    Android联系人数据库文件(contact2.db)

    有研究过手机通讯录数据的童鞋肯定知道一个数据库文件:目前是contact2.db(哥的手机是Android4.04的)

    在此路径下可以找到:/data/data/com.android.providers.contacts/databases/contact2.db

    将其导入可视化数据库管理器当中(我这里用的是SQLiteDatabase Browser)

    \

    有以上那么多张表,看到头晕的有木有,我们主要关注一些比较重要的表就行了。

    以上我用红框标志的是比较重要的几个表:

    1、contacts表

    该表保存了所有的手机测联系人,每个联系人占一行,该表保存了联系人的ContactID、联系次数、最后一次联系的时间、是否含有号码、是否被添加到收藏夹等信息。

    2、raw_contacts表

    该表保存了所有创建过的手机测联系人,每个联系人占一行,表里有一列标识该联系人是否被删除,该表保存了两个ID: RawContactID和ContactID,从而将contacts表和raw_contacts表联系起来。该表保存了联系人的RawContactID、ContactID、联系次数、最后一次联系的时间、是否被添加到收藏夹、显示的名字、用于排序的汉语拼音等信息。

    3、 mimetypes 表

    该表定义了所有的MimeTypeID,即联系人的各个字段的唯一标志。

    \

    4、data表

    ? 该表保存了所有创建过的手机测联系人的所有信息,每个字段占一行 ,该表保存了两个ID: MimeTypeID和RawContactID,从而将data表和raw_contacts表联系起来。

    ? 联系人的所有信息保存在列data1至data15中,各列中保存的内容根据MimeTypeID的不同而不同。如保存号码(MimeTypeID=5)的那行数据中,data1列保存号码,data2列保存号码类型(手机号码/家庭号码/工作号码等)。

    \


    对联系人的基本操作(增删改查)

    权限设置


    读取联系人

    分为以下步骤:

    1、先读取contacts表,获取ContactsID;

    2、再在raw_contacts表中根据ContactsID获取RawContactsID;

    3、然后就可以在data表中根据RawContactsID获取该联系人的各数据了。


    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    private void queryContacts() {
            // 获取用来操作数据的类的对象,对联系人的基本操作都是使用这个对象
            ContentResolver cr = getContentResolver();
            // 查询contacts表的所有记录
            Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
                    null, null, null);
            // 如果记录不为空
            if (cursor.getCount() > 0) {
                // 游标初始指向查询结果的第一条记录的上方,执行moveToNext函数会判断
                // 下一条记录是否存在,如果存在,指向下一条记录。否则,返回false。
                while (cursor.moveToNext()) {
                    String rawContactId = "";
                    // 从Contacts表当中取得ContactId
                    String id = cursor.getString(cursor
                            .getColumnIndex(ContactsContract.Contacts._ID));
                    Log.v("contactID", id);
     
                    // 获取RawContacts表的游标
                    Cursor rawContactCur = cr.query(RawContacts.CONTENT_URI, null,
                            RawContacts._ID + "=?", new String[] { id }, null);
                    // 该查询结果一般只返回一条记录,所以我们直接让游标指向第一条记录
                    if (rawContactCur.moveToFirst()) {
                        // 读取第一条记录的RawContacts._ID列的值
                        rawContactId = rawContactCur.getString(rawContactCur
                                .getColumnIndex(RawContacts._ID));
                        Log.v("rawContactID", rawContactId);
     
                    }
                    // 关闭游标
                    rawContactCur.close();
                    // 读取号码
                    if (Integer
                            .parseInt(cursor.getString(cursor
                                    .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                        // 根据查询RAW_CONTACT_ID查询该联系人的号码
                        Cursor phoneCur = cr
                                .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                        null,
                                        ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID
                                                + "=?",
                                        new String[] { rawContactId }, null);
                        // 上面的ContactsContract.CommonDataKinds.Phone.CONTENT_URI
                        // 可以用下面的phoneUri代替
                        // Uri
                        // phoneUri=Uri.parse("content://com.android.contacts/data/phones");
     
                        // 一个联系人可能有多个号码,需要遍历
                        while (phoneCur.moveToNext()) {
                            // 获取号码
                            String number = phoneCur
                                    .getString(phoneCur
                                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                            Log.v("number", number);
                            // 获取号码类型
                            String type = phoneCur
                                    .getString(phoneCur
                                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                            Log.v("type", type);
     
                        }
                        phoneCur.close();
     
                    }
                }
                cursor.close();
            }
        }



    新建联系人

    新建联系人时, 根据contacts、raw_ contacts两张表中ID的使用情况,自动生成ContactID和RawContactID。

    Android源码新建重复姓名的联系人的ContactID是不重复的,所以会重复显示。

    用下面的代码新建联系人,如果多次新建的联系人的姓名是一样的,生成的ContactID也会重复, RawContactID不会重复,我们在读取联系人的时候可以获取所有同姓名联系人的号码等信息,在显示联系人的时候,重复姓名的联系人的所有字段信息都会合并起来显示为一个联系人。

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public void addContact(String name, String phoneNum) {
            ContentValues values = new ContentValues();
            Uri rawContactUri = getContentResolver().insert(
                    RawContacts.CONTENT_URI, values);
            long rawContactId = ContentUris.parseId(rawContactUri);
            // 向data表插入数据
            if (name != "") {
                values.clear();
                values.put(Data.RAW_CONTACT_ID, rawContactId);
                values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
                values.put(StructuredName.GIVEN_NAME, name);
                getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
                        values);
            }
            // 向data表插入电话号码
            if (phoneNum != "") {
                values.clear();
                values.put(Data.RAW_CONTACT_ID, rawContactId);
                values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
                values.put(Phone.NUMBER, phoneNum);
                values.put(Phone.TYPE, Phone.TYPE_MOBILE);
                getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
                        values);
            }
        }

    删除联系人

    Android帮助文档:When a raw contact is deleted, all of its Data rows as well asStatusUpdates, AggregationExceptions, PhoneLookup rows are deleted automatically.

    所以,要删除联系人,我们只需要将raw_contacts表中指定RawContactID的行删除,其他表中与之关联的数据都会自动删除。

    ?
    1
    2
    3
    4
    5
    6
    // 删除联系人
        public void deleteContact(long rawContactId) {
            getContentResolver().delete(
                    ContentUris.withAppendedId(RawContacts.CONTENT_URI,
                            rawContactId), null, null);
        }

    更新联系人

    联系人的所有信息都是保存在data表中,所以要更新联系人,我们只需要根据RawContactID和MIMETYPE修改data表中的内容。

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 更新联系人
        public void updataCotact(long rawContactId) {
            ContentValues values = new ContentValues();
            values.put(Phone.NUMBER, "13800138000");
            values.put(Phone.TYPE, Phone.TYPE_MOBILE);
            String where = ContactsContract.Data.RAW_CONTACT_ID + "=? AND "
                    + ContactsContract.Data.MIMETYPE + "=?";
            String[] selectionArgs = new String[] { String.valueOf(rawContactId),
                    Phone.CONTENT_ITEM_TYPE };
            getContentResolver().update(ContactsContract.Data.CONTENT_URI, values,
                    where, selectionArgs);
        }

    以上就是本篇博客的所有内容,不知道小巫说清楚了没有?关于Android相关的知识点,还是需要多查资料和总结才能比较熟悉,查看官方文档是最直接的方式,如果阅读全英文有困难的话就看看别人总结的东西吧。下篇博客会做一个demo来提供一种方法查询所有联系人、通话记录、短信。

    展开全文
  • 功能:查找显示联系人信息,删除,添加联系人,修改联系人信息; 联系有信息有:电话号码,姓名,Email,地址
  • android手机通讯录数据库重要表介绍

    千次阅读 2016-05-25 21:48:17
    该表用于保存手机通讯录中每个联系人的id,每添加一个联系人,就会出现一个id。该表只显示联系人的id号,并且每个联系人只有一个id。 二、data表 该表用于存放手机通讯录中联系人的所有数据,在该表下,手机通讯录...
  • 转自:http://www.2cto.com/kf/201402/280583.html2014年2月21日 Android通讯录管理总结这几天导师安排我一个任务就是研究一下Android通讯录获取联系人、通话记录、短信的方法,还有看看不同Android版本之间的异同...
  • 总结介绍:本次个人通讯录数据库系统主要目的是为了做出一个功能齐全、简单易用的信息管理系统提高保存联系人效率,由于能力有限,界面做的有点不好看,还有在登录的编程只做到将登录名和密码设为固定的字符值,修改...
  • 2、创建数据库 3、创建数据表 4、编辑列(属性) 5、插入元组(条信息) 6、查询 总结:经过和小组成员一番推敲,历经10分钟左右,终于完美地创建出一张数据表,也巩固了SQL查询语句的使用以及...
  • //数据库类型的枚举值 //可以对此枚举进行拓展,但是在响应使用的函数里都要进行拓展 enum { PRO_STRING = 0x00000001, //字符串类型 TCHAR PRO_TIME, //日期型 systime PRO_NUMBER //整型 int }; /
  • 无数据,不应用。现实生活中的很多系统都离不开数据库,而数据的增删... 直接使用Oracle Express Edition创建示例数据库应用程序 (好像用的是.NET) b. 用Java连接MySQL和Derby (JavaDB) 2. 在JHTP教材示例的基
  • ACCESS数据库通讯录

    2013-11-02 14:39:59
    用access做的通讯录,就是乱传的,没必要下载。空的文件
  • 数据库通讯录

    2016-11-17 20:09:33
    写的一个简单的通讯录,主要自己比较low,感谢给我找错的亲们! #include #include #include #include void create_table(sqlite3 *db); void insert_record(sqlite3 *db); void contact_list(sqlite3 ...
  • 工具类:数据库SQLite的创建及增删改查方法的规范MySQLiteOpenHelper public class MySQLiteOpenHelper extends SQLiteOpenHelper { //数据库版本 private static final int VERSION = 1; private ...
  • 电子通讯录数据库版存储)

    千次阅读 2017-08-21 09:00:59
    制作一个电子通讯录,通过该通讯录能存入好友ID号、姓名(英文)、手机号码、家庭住址、公司电话。 模块  主界面:主要显示软件功能。 A) 添加好友信息。 // id为唯一标识 B) 列表好友信息。(包含排序功能) C) ...
  • 然后再考虑有几个activity(3个,一个UserListActivity,一个AddActivity,一个UpdateActivity),预览图是这样的 点击左上方加号出现以下 上代码: 布局文件: user_list.xml ...
  •  Android 绿豆通讯录( SQLite数据库 + ListView数据展示控件 ) https://blog.csdn.net/weixin_44949135/article/details/106029404 采用 SQLite数据库 + ListView数据展示控件,可将用户添加的所有信息,分条...
  • 目录 系统功能要求 相关软件要求 设计思路 程序功能图 ...3、用户登录后可以对个人通讯录进行增、删、改、查的功能 4、不能对别的用户的通讯录进行任何操作 相关软件要求 编程语言:C语言,并...
  • 编写个通讯录,估计不会超过1万联系人,hoho,这么多。想自己做结构写入文件中,还是使用现成的数据库,如Access、DBF、或者CVS为了程序有更好的移植性,所以不太想用access。各位XD给建议吧?
  • 个人通讯录系统——数据库课程设计

    千次阅读 多人点赞 2020-06-20 15:02:20
    课 程 设 计 课 程 数据库原理及应用课程设计 题 目 个人通讯录系统 学 院 信息工程学院 专 业 计算机科学与技术 班 级 18计科本科2班 姓 名 ****** ...
  • 主要为大家详细介绍了python数据库编程,Mysql实现通讯录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 通过数据库建立的通讯录

    千次阅读 2018-01-22 11:02:58
    之前写过一个用C语言建立的通讯录,但是在学习了数据库后,我发现用数据库来建立通讯录更加简洁方便,因为在数据库中,你每输入一个联系人的相应信息,数据库都会自动的将联系人的相关信息保存到表里面,而不用通过...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,644
精华内容 4,257
关键字:

创建一个通讯录的数据库