Android系统本身提供了很多系统服务,如WindowManagerService,PowerManagerService等。下面描述一下添加一个系统服务的具体步骤。
1、 撰写一个aidl文件,定义服务的接口,将在编译过程中通过aidl工具生成对应的java接口。一般系统服务的aidl文件都放在framework\base\core\java\android\os目录中。
以我所写的IMyTool.aidl为例。在.aidl中定义自己需要加入的方法,编写规则和java接口差不多,这里不多说。
2、 将aidl文件名添加到frameworks\base\目录下的Android.mk编译脚本文件中。
如:
LOCAL_SRC_FILES += \
core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl\
…\
core/java/android/os/IMyTool.aidl\
…
IMyTool.aidl即我加进去的aidl文件,加入后才能在make过程中编译到,否则将在后面的SystemServer添加系统服务时会报错提示找不到对应类。
3、 编写真正工作的服务类,继承IMyTool.Stub类(AIDL文件名.Stub,aidl生成的接口中的内部类,是一个Binder)。
服务类一般都放在framework\base\services\java\com\android\server目录中。
例如:
public class MyToolService extends IMyTool.Stub {
实现IMyTool.aidl中定义的接口。
}
4、 将自定义服务注册到SystemServer,使得开机过程中被添加。
在framework\base\services\java\com\android\server目录中的SystemServer中启动服务代码处加入:
try {
Slog.i(TAG, "MyToolService");
ServiceManager.addService(Context.MY_TOOL_SERVICE,new MyToolService(context));// MyToolService构造函数自己定义,一般都会用到Context
} catch(Throwable e) {
Slog.e(TAG, "Failure startingMyToolService", e);
}
上面代码中Context.MY_TOOL_SERVICE是自己在Context类中定义的常量,也就是给服务定义的名字,使用常量方便获取服务,而不需要记住注册服务时用的名字,且想换名字时只需改一个常量的值。
5、 由于在工程中添加了自己定义的类及常量,系统的api没有更新,因此需要先在工程中make clean然后make update-api,执行完后会发现frameworks\base\api\current.xml文件中多出自己定义的一些东西。 current.xml这个文件包含了所有系统所有能被应用层使用的类及其方法等。
之后再使用make编出来的固件及jar包就能包含自定义的接口。
编译后如何使用:
将编出来的jar包通过lib方式导入工程。jar包位置:out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\classes.jar
调用以下代码获取自定义服务:
IMyTool myTool = IMyTool.Stub.asInterface(ServiceManager.getService(MY_TOOL_SERVICE));
MY_TOOL_SERVICE即在Context中定义的常量。获取到myTool后就可以调用在aidl文件中定义的接口了。
我们知道Android系统服务挺多的,做程序时经常会用到,要想把这么多的 服务都了解透彻还真不是一两天就能搞定的,首先我们得又有一个框架,脑海里要形成这样的模型,android到底有哪些服务,针对这些服务分类去学习他 们,今天发点时间把Android中的一些系统服务整理一下,大部分都是收集网络上的资料。自己也当作是一次学习机会,好了废话不多说了,请看下文:
getSystemService(String name)是Android很重要的一个API,根据NAME来取得对应的Object,然后转换成相应的服务对象。以下介绍系统相应的服务。
===============================================================
name 返回的对象 说明
WINDOW_SERVICE WindowManager 管理打开的窗口程序
LAYOUT_INFLATER_SERVICE LayoutInflater 取得xml里定义的view
ACTIVITY_SERVICE ActivityManager 管理应用程序的系统状态
POWER_SERVICE PowerManger 电源的服务
ALARM_SERVICE AlarmManager 闹钟的服务
NOTIFICATION_SERVICE NotificationManager 状态栏的服务
KEYGUARD_SERVICE KeyguardManager 键盘锁的服务
LOCATION_SERVICE LocationManager 位置的服务,如GPS
SEARCH_SERVICE SearchManager 搜索的服务
VIBRATOR_SERVICE Vibrator 手机震动的服务
CONNECTIVITY_SERVICE Connectivity 网络连接的服务
WIFI_SERVICE WifiManager Wi-Fi服务
TELEPHONY_SERVICE TeleponyManager 电话服务
==================================================================================
package com.eyu.screen.util;
import android.content.Context;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
public class PowerManagerWakeLock {
private static WakeLock wakeLock;
/**开启 保持屏幕唤醒*/
public static void acquire(Context context) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE, "PowerManagerWakeLock");
wakeLock.acquire();
}
/**关闭 保持屏幕唤醒*/
public static void release() {
if (wakeLock != null) {
wakeLock.release();
wakeLock = null;
}
}
}
private Vibrator vibrator;
取得震动服务的句柄
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
或者 vibrator = (Vibrator)getApplication().getSystemService(Service.VIBRATOR_SERVICE);
开始震动有两个接口
1 . vibrator.vibrate(2000);//震动指定时间 ,数据类型long,单位为毫秒,一毫秒为1/1000秒
2. vibrator.vibrate(new long[]{100,10,100,1000}, -1);//按照指定的模式去震动。
数组参数意义:第一个参数为等待指定时间后开始震动,震动时间为第二个参数。后边的参数依次为等待震动和震动的时间
第二个参数为重复次数,-1为不重复,0为一直震动
取消震动
vibrator.cancel();//取消震动,立即停止震动
震动为一直震动的话,如果不取消震动,就算退出,也会一直震动
最重要的,增加权限,否则运行时出错
<uses-permission android:name="android.permission.VIBRATE"/>
public class MainActivity extends Activity {
private Button btnOpen=null;
private Button btnClose=null;
private Button btnState=null;
private WifiManager wifi=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnOpen=(Button)super.findViewById(R.id.openwifi);
btnClose=(Button)super.findViewById(R.id.closewifi);
btnState=(Button)super.findViewById(R.id.wifistate);
//获取Wifi服务
wifi=(WifiManager)super.getSystemService(Context.WIFI_SERVICE);
//开启
btnOpen.setOnClickListener(new OnClickListener(){
public void onClick(View v)
{
wifi.setWifiEnabled(true);
Toast.makeText(getApplicationContext(), "开启Wifi服务!", Toast.LENGTH_LONG).show();
}
});
//关闭
btnClose.setOnClickListener(new OnClickListener(){
public void onClick(View v)
{
wifi.setWifiEnabled(false);
Toast.makeText(getApplicationContext(), "关闭Wifi服务!", Toast.LENGTH_LONG).show();
}
});
//状态
btnState.setOnClickListener(new OnClickListener(){
public void onClick(View v)
{
Toast.makeText(getApplicationContext(), "Wifi状态:"+String.valueOf(wifi.getWifiState()), Toast.LENGTH_LONG).show();
}
});
}
}
注意:需要在AndroidManifest.xml文件中添加权限:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
扫描二维码,一起学习