23.号码归属地查询(其他用到数据库的都参考该方法)
查询数据库的方法,一般是写一个工具类放在程序包名.db.dao里面做实现。
外部的数据库通常放在assets目录下,访问该目录下的文件用file:///android_asset/icon.png方法是访问不到的。所以我们需要把该目录下的数据库复制到我们能读取到的目录data/data/包名/files中。复制数据库应该在程序启动的时候完成,复制一次就可以了,所以复制前判断是否已经复制过了。复制数据库:
<span style="font-size:18px;">File file = new File(getFilesDir(), "address.db");
if(file.exists() && file.length() > 0){
//已经复制过,不用复制
}else{
InputStream is = getAssets().open("address.db");
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while((len = is.read(buffer))!= -1){
fos.write(buffer, 0, len);
}
is.close();
fos.close();
}</span>
访问数据库用:SQLiteDatabase db = SQLiteDatabase.openDatabase(path,factory,flags);方法,其中,第一个参数是数据库的要打开数据库的位置或要创建数据库的位置;第二个参数是游标工厂,一般为null;第三个参数是控制数据库访问的模式:SQLiteDatabase.OPEN_READONLY为只读模式。然后db.rawQuery();即可。
增加输入框变化的事件监听:addTextChangedListener(实现接口);
24.模拟器中APIDemo中效果的实现。
从sdk/samples/adnroid-16/ApiDemos导入工程,查找某个功能的代码:
先根据要实现功能的布局文件中的信息,如:布局中的一个TextView内容:Please enter your password,Ctrl+H,输入查找,根据name属性继续Ctrl+H查找,看是哪个布局文件引用了该内容,然后再根据布局文件名Ctrl+H查看是那个文件引用了该布局文件。再看该文件是怎样实现的就OK啦!
25.手机震动效果的实现
实现手机震动需要用到系统服务:Vibrator,用getSystemService();方法获服务。震动也需要添加权限:
VIBRATE
通过vibrator.vibrate(震动时长,单位ms);方法或者vibrator.vibrate(pattern, repeat)方法实现震动。
其中pattern是个long型的数组{停顿时长,震动时长,停顿时长,震动时长,。。。},如{200,200,300,300,1000,2000},该数组的意思是:先停顿200毫秒,再震动200毫秒,再停顿300毫秒,再震动300毫秒。。。
repeat是循环震动,若为-1则不循环,若为0则从数组的0位置开始循环震动,若为1则从数组的1位置开始循环震动。。。
26.判断服务是否还在运行中
判断服务是否还在运行中需要用到系统的Activity管理器:ActivityManager,通过getSystemService()方法获得。
通过am.getRunningServices(maxNum);获得正在运行的服务,若手机中正在运行的服务数大于maxNum,则只返回maxNum个正在运行的服务;若手机中正在运行的服务小于maxNum,则返回所有正在运行的服务。返回的是正在运行的服务的信息列表List<RunningServiceInfo>。可以for循环判断正在运行的服务是否与目标服务相同。循环中得到当前服务的名字的方法是:服务名.service.getClassName();
<span style="font-size:18px;">public static boolean isServiceRunning(Context context, String serviceName) {
// 校验服务是否还活着
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> infos = am.getRunningServices(100);
for (RunningServiceInfo info : infos) {
String name = info.service.getClassName();
if(name.equals(serviceName)){
return true;
}
}
return false;
}</span>
传递服务名时,需要传递服务的全路径名。
27.归属地显示
归属地显示包括来电归属地显示和去电归属地显示。
来电归属地显示需要后台监听来电,所以要写到服务里面。可以参考电话窃听器。
去电归属地需要监听电话的呼出,所以要写在广播接收者里面,关心的事件是NEW_OUTGOING_CALL,另外,监听去电还需要添加权限:PROCESS_OUTGOING_CALLS。
在清单文件中注册的广播接收者不能根据用户选择终止而终止,所以,广播接收者也可以在代码中注册,这是其他三大组件所不具有的。
为了能使用户选择终止服务而终止广播接收者,可以把广播接收者放到服务里面,相当于服务的一个内部类。然后在服务的onCreate方法中注册:
先实例化内部类,再用filter.addAction();添加广播接收者关心的事件,最后用registerReceiver(receiver,filter);注册广播接收者。
取消广播接收者可以在onDestory方法中实现:unregisterReceiver(receiver);
切记:用代码注册广播接收者的话,清单文件中的注册信息一定要删除。
28.自定义吐司
自定义吐司可以参考系统吐司的定义,显示。
<span style="font-size:18px;">/**
* 自定义吐司显示归属地
*
* @param location 要显示的内容
*/
public void myToast(String location) {
view = new TextView(getApplicationContext());//1.定义要显示吐司内容的控件TextView
view.setText(location);
view.setTextSize(22);
view.setTextColor(Color.RED);
// 2.定义吐司在窗体中显示位置的参数
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.format = PixelFormat.TRANSLUCENT;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
// 3.把view显示到窗体
wm.addView(view, params);
}</span>
上面代码中wm是窗体管理器的一个实例,取消显示自定义吐司用:wm.remove(view);方法。
另外,还可以自定义显示吐司的布局文件。用View.inflate();方法做第一步操作。