由于项目需要,我这边需要在framework层增加一个语音唤醒服务来实现拉通hal层以及android应用层,实现语音黑屏唤醒以及亮屏唤醒的功能,这里我们只看在android7.0和9.0上是怎么增加一个自定义系统服务,其实对着葫芦画瓢就可以了。

下面主要说基于android7.0的添加系统服务,9.0的编译方式改了,改下bp文件就可以了,没什么大的区别,这里删了些复杂的接口,只留了几个比较简单的接口,方便阅读。

1.编写与声明aidl文件

1.1.编写aidl文件

在frameworks/base/core/java/android/新增ovum/ai/IAIManager.aidl文件

package android.ovum.ai;
/**
* {@hide}
*/
interface IAIManager {byte[] getAudioData();int getWakeupDoa();void stopAudioData();void wakeupAppStarted(String callerPackage);boolean setEnabled(boolean enabled, String callerPackage);boolean isEnabled(String callerPackage);boolean isRecording(String callerPackage);
}

1.2.注册aidl文件

实现完成后需要在frameworks/base/Android.mk 声明我们需要的aidl文件,这个经常忘记了。

core/java/android/ovum/ai/IAIManager.aidl \
core/java/android/ovum/performanceobserver/IPerformanceObserverService.aidl \

1.3.封装aidl的接口实现

实现AIManager的接口封装

package android.ovum.ai;import android.content.Context;
import android.os.RemoteException;
import android.util.Log;/*** {@hide}*/
public class AIManager {private static final String TAG = "AIManager";private final Context mContext;private final IAIManager mService;public AIManager(Context context, IAIManager service) {Log.v(TAG, "AIManager()");mContext = context;mService = service;}public void stopAudioData() {try {mService.stopAudioData();} catch (RemoteException e) {e.printStackTrace();}}public int getWakeupDoa() {try {return mService.getWakeupDoa();} catch (RemoteException e) {e.printStackTrace();}return 0;}public byte[] getAudioData() {try {return mService.getAudioData();} catch (RemoteException e) {e.printStackTrace();}return null;}public void wakeupAppStarted() {try {mService.wakeupAppStarted(mContext.getOpPackageName());} catch (RemoteException e) {e.printStackTrace();}}public boolean setEnabled(boolean enabled) {try {return mService.setEnabled(enabled, mContext.getOpPackageName());} catch (RemoteException e) {e.printStackTrace();}return false;}public boolean isEnabled() {try {return mService.isEnabled(mContext.getOpPackageName());} catch (RemoteException e) {e.printStackTrace();}return false;}public boolean isRecording() {try {return mService.isRecording(mContext.getOpPackageName());} catch (RemoteException e) {e.printStackTrace();}return false;}}

2.实现AIManagerService

package com.android.server.ovum;
import android.content.Context;
import android.media.AudioFormat;
import android.os.RemoteException;
import android.ovum.ai.IAIManager;
import android.util.Slog;
import android.media.MediaRecorder;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.PowerManager;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.app.ActivityManagerInternal;
import com.android.server.LocalServices;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import java.util.concurrent.ArrayBlockingQueue;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.File;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Parcelable;
import android.content.BroadcastReceiver;
import android.provider.Settings;public class AIManagerService extends IAIManager.Stub {private static final String TAG = "AIManagerService";private Context mContext;private static boolean LOG_DEBUG = true;private boolean mIsEnabled = true;public AIManagerService(final Context context) {Slog.d(TAG, "AIManagerService()");mContext = context;}public void handleOnBootPhase() {Slog.d(TAG, "handleOnBootPhase");}@Overridepublic void stopAudioData() throws RemoteException {Slog.d(TAG, "stopAudioData!\n");}@Overridepublic int getWakeupDoa() throws RemoteException {return 0;}@Overridepublic byte[] getAudioData() throws RemoteException {return null;}@Overridepublic void wakeupAppStarted(String callerPackage) throws RemoteException {Slog.d(TAG, "wakeupAppStarted caller=" + callerPackage);return;}@Overridepublic boolean setEnabled(boolean enabled, String callerPackage) throws RemoteException {Slog.d(TAG, "setEnabled=" + enabled + ",caller=" + callerPackage);return false;}@Overridepublic boolean isEnabled(String callerPackage) throws RemoteException {Slog.d(TAG, "isEnabled=" + mIsEnabled + ",caller=" + callerPackage);return mIsEnabled;}@Overridepublic boolean isRecording(String callerPackage) throws RemoteException {return false;}@Overrideprotected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)!= PERMISSION_GRANTED) {pw.println("Permission Denial: can't dump ovum_ai from from pid="+ Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()+ " without permission " + android.Manifest.permission.DUMP);return;}pw.println("AIManagerService");}
}

这里我们为了方便统一管理我们增加的自定义系统服务
在frameworks/base/services/core/java/com/android/server/目录下新增ovum/OvumOvulationService.java ,实现OvumOvulationService 并继承SystemService

package com.android.server.ovum;import android.content.Context;
import android.util.Slog;import com.android.server.am.ActivityManagerService;import com.android.server.SystemService;public class OvumOvulationService extends SystemService {private final static String TAG = "OvumOvulationService";private Context mContext;private AIManagerService mAiManagerService;public OvumOvulationService(Context context) {super(context);mContext = context;mAiManagerService = new AIManagerService(context);}@Overridepublic void onStart() {Slog.d(TAG, "onStart ------");}@Overridepublic void onBootPhase(int phase) {Slog.d(TAG, "onBootPhase ------ " + phase);if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {publishBinderService(Context.OVUM_AI_SERVICE, mAiManagerService);mAiManagerService.handleOnBootPhase();}}
}

修改frameworks/base/services/java/com/android/server/SystemServer.java 实现启动我们的服务

import com.android.server.ovum.OvumOvulationService;private OvumOvulationService mOvumOvulationService;...mSystemServiceManager.startService(OvumOvulationService.class);

同时修改frameworks/base/core/java/android/content/Context.java 新增 OVUM_AI_SERVICE,方便dump信息查看

/*** @hide*/ public static final String OVUM_AI_SERVICE = "ovum_ai";

修改system/sepolicy/service_contexts文件,修改权限

ovum_ai                                   u:object_r:ovum_service:s0

这样整个系统服务就声明和实现完成了。编译替换后,重启系统我们就可以看到system log了

01-11 01:53:29.183742   708   708 D AIManagerService: AIManagerService()
01-11 01:53:29.184836   708   708 D OvumOvulationService: onStart ------
01-01 00:00:01.628209   708   748 D OvumOvulationService: onBootPhase ------ 1000
01-01 00:00:01.628901   708   748 D AIManagerService: handleOnBootPhase

说明我们的服务正常起来了

2.使用自定义系统服务

这里我们不做注册监听系统服务这些操作,直接通过反射并封装一个jar包提供给应用使用,这里直接使用反射的方式。

public class AIManager {private static final String TAG = "AIManager.jar";private static final boolean DEBUG = true;private static AIManager sAIManager;private static Object mSysAIManagerObject;private static Class mSysAIManagerClass;private static Method mMethodSwitchToWakeupMode;private static Method mMethodSwitchToRecordMode;private static Method mMethodWakeupAppStarted;private static Method mMethodOneshotRecordStarted0;private static Method mMethodOneshotRecordStarted;private static Method mMethodSetEnabled;private static Method mMethodIsEnabled;private static Method mMethodIsRecording;private static Method mMethodCallback;private static Method mMethodUnCallback;private static Method mMethodgetAudioData;private static Method mMethodgetWakeupDoa;private static Method mMethodstopAudiodata;private static Method mMethodauthDuiTest;public AIManager(Context context) {if (DEBUG) {Log.d(TAG, "new AIManager from package " + context.getPackageName());}}public static AIManager getInstance(Context context) {if (sAIManager == null) {sAIManager = new AIManager(context);mSysAIManagerObject = context.getApplicationContext().getSystemService("ovum_ai");if (DEBUG) {Log.d(TAG, "mSysAIManagerObject=" + mSysAIManagerObject);}if (mSysAIManagerObject != null) {mSysAIManagerClass = mSysAIManagerObject.getClass();}try {mMethodSetEnabled = mSysAIManagerClass.getMethod("setEnabled", boolean.class);mMethodSetEnabled.setAccessible(true);} catch (NoSuchMethodException e) {Log.e(TAG, e.getMessage());}try {mMethodIsEnabled = mSysAIManagerClass.getMethod("isEnabled");mMethodIsEnabled.setAccessible(true);} catch (NoSuchMethodException e) {Log.e(TAG, e.getMessage());}try {mMethodIsRecording = mSysAIManagerClass.getMethod("isRecording");mMethodIsRecording.setAccessible(true);} catch (NoSuchMethodException e) {Log.e(TAG, e.getMessage());}try {mMethodgetAudioData = mSysAIManagerClass.getMethod("getAudioData");mMethodgetAudioData.setAccessible(true);} catch (NoSuchMethodException e) {Log.e(TAG, e.getMessage());}try {mMethodgetWakeupDoa = mSysAIManagerClass.getMethod("getWakeupDoa");mMethodgetWakeupDoa.setAccessible(true);} catch (NoSuchMethodException e) {Log.e(TAG, e.getMessage());}try {mMethodstopAudiodata = mSysAIManagerClass.getMethod("stopAudioData");mMethodstopAudiodata.setAccessible(true);} catch (NoSuchMethodException e) {Log.e(TAG, e.getMessage());}}return sAIManager;}public void stopAudiodata() {if (sAIManager == null || mMethodstopAudiodata == null || mSysAIManagerObject == null)return;try {mMethodstopAudiodata.invoke(mSysAIManagerObject);} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}public byte[] getAudioData() {if (sAIManager == null || mMethodgetAudioData == null || mSysAIManagerObject == null)return null;try {return (byte[]) mMethodgetAudioData.invoke(mSysAIManagerObject);} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return null;}public int getWakeupDoa() {if (sAIManager == null) return -1;try {return (int) mMethodgetWakeupDoa.invoke(mSysAIManagerObject);} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return -1;}public void wakeupAppStarted() {if (sAIManager == null) return;try {mMethodWakeupAppStarted.invoke(mSysAIManagerObject);} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}public boolean setEnabled(boolean enabled) {if (sAIManager == null) return false;try {return (boolean) mMethodSetEnabled.invoke(mSysAIManagerObject, enabled);} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return false;}public boolean isEnabled() {if (sAIManager == null) return false;try {return (boolean) mMethodIsEnabled.invoke(mSysAIManagerObject);} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return false;}public boolean isRecording() {if (sAIManager == null) return false;try {return (boolean) mMethodIsRecording.invoke(mSysAIManagerObject);} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return false;}}

应用只需要集成jar包,然后如下这样调用就可以了

AIManager.getInstance(MainActivity.this).setEnabled(true);

android7.0如何自定义添加系统服务相关推荐

  1. Android开发之下载Apk安装的方法兼容Android7.0和8.0及以上

    具体查看代码: 首先在清单文件配置三个权限读写权限和请求安装权限(兼容Android8.0手机)如下: <!--安装apk权限--><uses-permission android: ...

  2. Android - 更换头像及图片裁剪(适配Android7.0)

    我的CSDN: ListerCi 我的简书: 东方未曦 一.概述 相信大家都用过 Android 应用中更换头像的功能,在这个功能中,用户可以拍照或者选择相册图片,然后裁剪出头像所需要的图案. 那么你 ...

  3. 【Android】Android7.0和Android2.1源生代码目录及框架分析

    Android源代码结构: Android7.0整体结构 各个版本的源码目录基本类似,编译后的源码目录会生成out文件夹,用来存储编译产生的文件(例如.img等文件). Android7.0的根目录结 ...

  4. Android踩坑日记:android7.0动态相机权限

    前提: 项目中使用的动态权限开源库github:https://github.com/yanzhenjie/AndPermission. 转载必须注明本文转自严振杰的博客:http://blog.cs ...

  5. Android Binder机制----实现自定义的系统服务

    一.基于源码分析Binder机制: Binder机制是Android系统中实现跨进程通信(IPC)的一种重要机制.可以说,Binder机制在android系统中无处不在,所以,要研究android源码 ...

  6. Android7.0新特性、新功能

    [本文转载来自http://blog.csdn.net/hao54216/article/details/52388755] 前言: 总想写点自己的东西,因为很多Android知识网上大部分都有教程, ...

  7. [转]快速使用FileProvider解决Android7.0文件权限问题

    升级到Android7.0之后,启动系统相机或者截图,传入URI的时候可能会导致程序闪退崩溃.这是因为7.0的新的文件权限导致的.下面是解决这个问题的快速解决方案. 问题代码 在7.0可能会出问题的代 ...

  8. Android7.0下载Apk自动安装

    Android7.0下载Apk自动安装 1. 整体需求 下载APK文件 使用DownloadManager来下载 在应用界面中展示下载进度 安装下载后的APK文件 root模式: 可以自动安装,不需要 ...

  9. 华为android7.0 root,android7.0更新安装apk的方法

    StrictMode模式 从android7.0开始强制启用StrictMode"严苛模式".StrictMode是在android2.3引进的类.当时它的作用是作为一个开发工具用 ...

最新文章

  1. vibe前景提取算法示例代码
  2. 【深度学习】高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力
  3. 大容量磁盘分区表、文件系统、分区工具的选择
  4. Python Django 生成随机字符串UUID的使用示例
  5. dojo中的this.own()
  6. 大便的离去,是马桶的追求?还是肛门的不挽留?
  7. sql2012 ssrs_您必须在SQL Server Reporting Services(SSRS)中记录的十件事
  8. Lucene的索引不跨平台
  9. 2021年中国单一麦芽的威士忌市场趋势报告、技术动态创新及2027年市场预测
  10. Redis 概述、Win 10 下载安装、redis.conf 配置文件详解
  11. Struts标记库与JSTL标记库
  12. LM4871(3W音频功放芯片)中文资料
  13. 四分位数算法记录(含java代码实现)
  14. 分布式对象存储服务器minio
  15. linux系统(Centos7)安装VScode笔记
  16. ROS(indigo) turtlebot2 + android一些有趣应用
  17. 中国不投美国国债还能投什么?
  18. AC自动机模板(【洛谷3808】)
  19. 风影墙纸,一天看N回。
  20. IT技术外包公司值得去吗?

热门文章

  1. 控制图纸多线相交交点凸起(Control PolyLine Bulge open and close )
  2. 2008年度最佳开源CMS大奖赛开幕
  3. UVA1226 LA3997 Numerical surprises【大数】
  4. Bailian4022 买房子【迭代】
  5. Bailian2909 字符串加空格【指针】
  6. 《程序设计技术》第八章例程
  7. 优先队列(priority queue)的实现(java,jdk接口)
  8. 博弈论与逻辑思维(传教士与妻子忠贞的问题)
  9. 域名与DNS(域名解析服务器)
  10. WinEdt LaTex(二)—— 空心中括号