android7.0如何自定义添加系统服务
由于项目需要,我这边需要在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如何自定义添加系统服务相关推荐
- Android开发之下载Apk安装的方法兼容Android7.0和8.0及以上
具体查看代码: 首先在清单文件配置三个权限读写权限和请求安装权限(兼容Android8.0手机)如下: <!--安装apk权限--><uses-permission android: ...
- Android - 更换头像及图片裁剪(适配Android7.0)
我的CSDN: ListerCi 我的简书: 东方未曦 一.概述 相信大家都用过 Android 应用中更换头像的功能,在这个功能中,用户可以拍照或者选择相册图片,然后裁剪出头像所需要的图案. 那么你 ...
- 【Android】Android7.0和Android2.1源生代码目录及框架分析
Android源代码结构: Android7.0整体结构 各个版本的源码目录基本类似,编译后的源码目录会生成out文件夹,用来存储编译产生的文件(例如.img等文件). Android7.0的根目录结 ...
- Android踩坑日记:android7.0动态相机权限
前提: 项目中使用的动态权限开源库github:https://github.com/yanzhenjie/AndPermission. 转载必须注明本文转自严振杰的博客:http://blog.cs ...
- Android Binder机制----实现自定义的系统服务
一.基于源码分析Binder机制: Binder机制是Android系统中实现跨进程通信(IPC)的一种重要机制.可以说,Binder机制在android系统中无处不在,所以,要研究android源码 ...
- Android7.0新特性、新功能
[本文转载来自http://blog.csdn.net/hao54216/article/details/52388755] 前言: 总想写点自己的东西,因为很多Android知识网上大部分都有教程, ...
- [转]快速使用FileProvider解决Android7.0文件权限问题
升级到Android7.0之后,启动系统相机或者截图,传入URI的时候可能会导致程序闪退崩溃.这是因为7.0的新的文件权限导致的.下面是解决这个问题的快速解决方案. 问题代码 在7.0可能会出问题的代 ...
- Android7.0下载Apk自动安装
Android7.0下载Apk自动安装 1. 整体需求 下载APK文件 使用DownloadManager来下载 在应用界面中展示下载进度 安装下载后的APK文件 root模式: 可以自动安装,不需要 ...
- 华为android7.0 root,android7.0更新安装apk的方法
StrictMode模式 从android7.0开始强制启用StrictMode"严苛模式".StrictMode是在android2.3引进的类.当时它的作用是作为一个开发工具用 ...
最新文章
- vibe前景提取算法示例代码
- 【深度学习】高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力
- 大容量磁盘分区表、文件系统、分区工具的选择
- Python Django 生成随机字符串UUID的使用示例
- dojo中的this.own()
- 大便的离去,是马桶的追求?还是肛门的不挽留?
- sql2012 ssrs_您必须在SQL Server Reporting Services(SSRS)中记录的十件事
- Lucene的索引不跨平台
- 2021年中国单一麦芽的威士忌市场趋势报告、技术动态创新及2027年市场预测
- Redis 概述、Win 10 下载安装、redis.conf 配置文件详解
- Struts标记库与JSTL标记库
- LM4871(3W音频功放芯片)中文资料
- 四分位数算法记录(含java代码实现)
- 分布式对象存储服务器minio
- linux系统(Centos7)安装VScode笔记
- ROS(indigo) turtlebot2 + android一些有趣应用
- 中国不投美国国债还能投什么?
- AC自动机模板(【洛谷3808】)
- 风影墙纸,一天看N回。
- IT技术外包公司值得去吗?