本文以mtk android5.1为研究对象。

Android的系统服务都是托管给ServiceManager管理的,我们可以自定义一个自己的服务,并将其添加到ServiceManager中,本文以添加一个Tts语音服务为例,供应用层调用。

1、首先,在frameworks/base/core/Java/android/app中新建一个aidl文件 ITtsManager.aidl,内容如下:

[java] view plain copy 在CODE上查看代码片派生到我的代码片

package android.app;  interface ITtsManager {      int speak(String message, String from);      int stop();  }  

2、将此aidl文件加入编译列表frameworks/base/Android.mk:

[java] view plain copy 在CODE上查看代码片派生到我的代码片

LOCAL_SRC_FILES += \      ....      core/java/android/app/ITtsManager.aidl \      ....  

3、在frameworks/base/services/core/java/com/android/server/tts路径下(路径可以自己改变)新建一个TtsManagerService.java类,该类继承了TtsManager.Stub,

[java] view plain copy 在CODE上查看代码片派生到我的代码片

package com.android.server.tts;  import android.content.Context;  import android.speech.tts.TtsEngines;  import android.speech.tts.TextToSpeech;  import android.os.Handler;  import android.util.Log;  import android.app.ITtsManager;  public final class TtsManagerService extends ITtsManager.Stub {      private static final String TAG = "TtsManagerService";      final Context mContext;      private final TextToSpeech mTts;      public TtsManagerService(Context context) {          Log.d(TAG, "Tts init complete");      }      @Override      public int speak(String message, String from) {          //TODO:                  return 0;      }      @Override      public int stop() {
     //TODO:                  return 0;  

}}
4、还得在frameworks/base/core/java/android/app创建一个管理器类TtsManager.java,

[java] view plain copy 在CODE上查看代码片派生到我的代码片

package android.os;  import android.content.Context;  public class TtsManager {      final ITtsManager mService;      final Context mContext;      public TtsManager(Context context, ITtsManager service) {          mContext = context;          mService = service;      }      public int speak(String message, String from) {          try {              return mService.speak(message, from);          } catch (RemoteException e) {              e.printStackTrace();              return -1;          }      }      public int stop() {          try {              return mService.stop();          } catch (RemoteException e) {              e.printStackTrace();              return -1;          }      }  }  

5、为了让应用层可以使用getSystemService接口获得服务,现在需要在ContextImpl.java的static代码块将TtsManager创建起来,
[java] view plain copy 在CODE上查看代码片派生到我的代码片

/// M: comment @{ add TtsManagerService by Lee      if ("1".equals(SystemProperties.get("ro.qxt.tts.support"))) {         registerService("qxttts", new ServiceFetcher() {                 public Object createService(ContextImpl ctx) {                     IBinder b = ServiceManager.getService("qxttts"); //注意:qxttts 是服务名称                     return new TtsManager(ctx, ITtsManager.Stub.asInterface(b));                 } });      }      /// @}  

6、现在可以将这个服务加入到ServiceManager中了,

[java] view plain copy 在CODE上查看代码片派生到我的代码片

try {      Slog.i(TAG, "Tts Manager");      ServiceManager.addService("qxttts", new TtsManagerService(context)); //服务名称qxttts与上面对应  } catch (Throwable e) {      Slog.e(TAG, "Failure starting Tts Manager", e);  }  

7、然后你可以在某个app的activity上获得这个服务,

[java] view plain copy 在CODE上查看代码片派生到我的代码片

((TtsManager)getSystemService("qxttts")).speak("测试用语", "activity");  

编译(先用update-api命令更新sdk),将相应模块push到手机上。。。

现在你可能会出现app启动报错的提示。。错误类似于speak方法处出现空指针,这是服务没起来,出现类似如下错误,

[java] view plain copy 在CODE上查看代码片派生到我的代码片

ServiceManager(  232): add_service('qxttts',45) uid=1000 - PERMISSION DENIED  

这是因为SELinux Policy限制,新加一个系统服务,你得先在device/mediatek/common/sepolicy/service_contexts注册你的服务,

[plain] view plain copy 在CODE上查看代码片派生到我的代码片

#Lee add begin  qxttts       u:object_r:system_server_service:s0  #Lee add end  

此处是vendor自己加的文件,android原生的服务在external/sepolicy/service_contexts中注册,external/sepolicy/service.te定义了各种类型如system_server_service。

重新编译,可以验证了。。。

未完待续,有不对的地方,请指正。

本人修复:
service_contexts:中
qxttts u:object_r:qxttts_service:s0

service.te中:
type qxttts_service, app_api_service, system_server_service, service_manager_type;

更多相关文章

  1. tcping测试服务器TCP端口
  2. Android(安卓)studio把一段代码快速提取,放在自己定义方法里面的
  3. Android通过编译源代码提供系统服务-android学习之旅(85)
  4. Android(安卓)CPU监控想法,思路,核心技术和代码
  5. Android(安卓)通过系统使用NotificationListenerService 监听各
  6. Android-传递数据的一些讨论
  7. android之应用程序LED
  8. onStartCommand 的返回值
  9. android中bitmap和drawable之间的转换

随机推荐

  1. ListView之setEmptyView的问题
  2. ActionBar
  3. Android(安卓)UmengShareSDK第三方登录
  4. 【Android】Android的JNI基础编程
  5. android开发初学建议
  6. Android(安卓)Push 开源方案解析
  7. Android初级教程小案例之单选框RadioGrou
  8. 使用Beetle.NetPackage简单实现android和
  9. Android豆瓣图书查询Demo
  10. Android构建时报错: java.io.IOException: