转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47374415
有些Android手机中会带有一些常用号码的功能,比如订餐电话、公共电话、航空机票,等等诸如此类的服务,点击相应的号码会自动弹出拨打电话的界面。那下面我们就一起来实现一个手机常用号码功能的小例子吧。
一、原理
首先,这些常用号码放置在一个SQLite数据库中,我们将这些号码从数据库中读取出来,按照相应的顺序显示到Android系统提供的ExpandableListView中(有关ExpandableListView的详细用法请大家参考Android官方文档,我在这里就不多说了),然后给每个条目设置点击事件,在点击事件中激活拨打电话的界面,并将相应的号码传递到拨打电话的界面。
好了,原理讲完了,是不是很简单呢?下面,我们就一起来实现这些具体的功能吧。
二、实现
1、准备数据库
我们首先将数据库放置在Android项目下的assets目录
如下图:
2、创建数据的操作类CommonNumberService
新建数据操作类CommonNumberService,这个类中主要有4个方法,一个是构造方法,在构造方法中我们将Android上下文对象传递到这个类中,其他3个方法实现了将数据库拷贝到/data/data/应用包名/files目录,然后实现数据的查询操作。
1)构造方法的实现
在构造方法中,我们将上下文对象传递到这个类中
具体实现代码如下:
private Context context;
public CommonNumberService(Context context) {
super();
this.context = context;
}
2)获取常用号码组数据方法
具体代码如下:
/**
* 得到组数据
* @return
*/
public List<Map<String, String>> getGroupData(){
List<Map<String, String>> groupData = new ArrayList<Map<String,String>>();
File file = new File(context.getFilesDir(), "commonnum.db");
SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);
if(db.isOpen()){
Cursor c = db.query("classlist", new String[]{"name", "idx"}, null, null, null, null, null);
while(c.moveToNext()){
Map<String, String> map = new HashMap<String, String>();
String name = c.getString(c.getColumnIndex("name"));
String idx = c.getString(c.getColumnIndex("idx"));
map.put("name", name);
map.put("idx", idx);
groupData.add(map);
}
c.close();
db.close();
}
return groupData;
}
3)获取常用号码子条目数据
具体代码如下:
/**
* 得到子条目的数据
* @return
*/
public List<List<Map<String, String>>> getChildData(){
List<List<Map<String, String>>> childData = new ArrayList<List<Map<String,String>>>();
List<Map<String, String>> groupData = this.getGroupData();
File file = new File(context.getFilesDir(), "commonnum.db");
SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);
if(db.isOpen()){
for(int i = 0; i < groupData.size(); i++){
String idx = groupData.get(i).get("idx");
List<Map<String, String>> list = new ArrayList<Map<String,String>>();
Cursor c = db.query("table" + idx, new String[]{"_id", "number", "name"}, null, null, null, null, null);
while(c.moveToNext()){
Map<String, String> map = new HashMap<String, String>();
String name = c.getString(c.getColumnIndex("name"));
String number = c.getString(c.getColumnIndex("number"));
map.put("name", name);
map.put("number", number);
list.add(map);
}
c.close();
childData.add(list);
}
db.close();
}
return childData;
}
4)整体代码
具体实现代码如下:
package cn.lyz.mobilesafe.engine;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
/**
* 获取常用号码
* @author liuyazhuang
*
*/
public class CommonNumberService {
private Context context;
public CommonNumberService(Context context) {
super();
this.context = context;
}
/**
* 将数据类拷贝到files目录
*/
public void copyDbToFilesDir(){
//将数据库拷贝到files目录
File file = new File(context.getFilesDir(), "commonnum.db");
if(!file.exists()){
try {
InputStream in = context.getAssets().open("commonnum.db");
OutputStream out = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while((len = in.read(buffer)) != -1){
out.write(buffer, 0, len);
}
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 得到组数据
* @return
*/
public List<Map<String, String>> getGroupData(){
List<Map<String, String>> groupData = new ArrayList<Map<String,String>>();
File file = new File(context.getFilesDir(), "commonnum.db");
SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);
if(db.isOpen()){
Cursor c = db.query("classlist", new String[]{"name", "idx"}, null, null, null, null, null);
while(c.moveToNext()){
Map<String, String> map = new HashMap<String, String>();
String name = c.getString(c.getColumnIndex("name"));
String idx = c.getString(c.getColumnIndex("idx"));
map.put("name", name);
map.put("idx", idx);
groupData.add(map);
}
c.close();
db.close();
}
return groupData;
}
/**
* 得到子条目的数据
* @return
*/
public List<List<Map<String, String>>> getChildData(){
List<List<Map<String, String>>> childData = new ArrayList<List<Map<String,String>>>();
List<Map<String, String>> groupData = this.getGroupData();
File file = new File(context.getFilesDir(), "commonnum.db");
SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);
if(db.isOpen()){
for(int i = 0; i < groupData.size(); i++){
String idx = groupData.get(i).get("idx");
List<Map<String, String>> list = new ArrayList<Map<String,String>>();
Cursor c = db.query("table" + idx, new String[]{"_id", "number", "name"}, null, null, null, null, null);
while(c.moveToNext()){
Map<String, String> map = new HashMap<String, String>();
String name = c.getString(c.getColumnIndex("name"));
String number = c.getString(c.getColumnIndex("number"));
map.put("name", name);
map.put("number", number);
list.add(map);
}
c.close();
childData.add(list);
}
db.close();
}
return childData;
}
}
2、界面显示类CommonNumberActivity
在这个类中我们主要实现了,获取界面控件,然后调用CommonNumberService类中方法,给界面封装数据,同时设置ExpandableListView子条目的点击事件,激活拨打电话接界面,并将选择的电话号码传递到拨打电话界面。
具体实现代码如下:
package cn.lyz.mobilesafe.activity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.SimpleExpandableListAdapter;
import cn.lyz.mobilesafe.R;
import cn.lyz.mobilesafe.engine.CommonNumberService;
/**
* 常用号码
* @author liuyazhuang
*
*/
public class CommonNumberActivity extends Activity {
private ExpandableListView elv_common_number;
private CommonNumberService service;
private SimpleExpandableListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.common_number);
elv_common_number = (ExpandableListView) findViewById(R.id.elv_common_number);
this.service = new CommonNumberService(this);
//将数据库拷贝到files目录
service.copyDbToFilesDir();
//获取组数据
List<Map<String, String>> groupData = service.getGroupData();
//获取子条目数据
List<List<Map<String, String>>> childData = service.getChildData();
adapter = new SimpleExpandableListAdapter(
this,
groupData,
android.R.layout.simple_expandable_list_item_1,
new String[]{"name"},
new int[]{android.R.id.text1},
childData,
android.R.layout.simple_expandable_list_item_2,
new String[]{"name", "number"},
new int[]{android.R.id.text1, android.R.id.text2});
elv_common_number.setAdapter(adapter);
elv_common_number.setOnChildClickListener(new MyOnChildClickListener());
}
/**
* 点击事件
* @author liuyazhuang
*
*/
private class MyOnChildClickListener implements OnChildClickListener{
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Map<String, String> map = (Map<String, String>) adapter.getChild(groupPosition, childPosition);
String number = map.get("number");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:"+number));
startActivity(intent);
return false;
}
}
}
3、界面布局common_number.xml
这个布局很简单,就是放置了一个ExpandableListView
具体实现如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ExpandableListView
android:id="@+id/elv_common_number"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
三、运行效果
四、温馨提示
大家可以到链接http://download.csdn.net/detail/l1028386804/8980263下载实例中用到的数据库commonnum.db文件
本实例中,为了方面,我把一些文字直接写在了布局文件中和相关的类中,大家在真实的项目中要把这些文字写在string.xml文件中,在外部引用这些资源,切记,这是作为一个Android程序员最基本的开发常识和规范,我在这里只是为了方便直接写在了类和布局文件中。