安卓多个应用程序的时候 同时访问硬件 会造成冲突 所以就是用 server框架
写server的框架 有些复杂 就用流程图 表示出来
大概开发应用程序的时候 就是这个流程图 后面 有详细开发按按理-----led server框架开发
根据流程图编写代码
写一个 AIDL 文件
把文件放入 /home/book/Desktop/android-5.0.2/frameworks/base/core/java/android/os
在
book@ubuntu:~/Desktop/android-5.0.2/frameworks/base$ ls Android.mk
找到 Andriod.mk 文件 修改
添加 自己的 aidl文佳
在源码 根目录下执行
. build/envsetup.sh
脚本设置环境
在 此目录 cd ./frameworks/base 执行
mmm .
mmm:编译指定路径下的模块,指定路径下要有Android.mk文件
如果编译出错
在根目录
. setenv
lunch
选择你的模块 我的是20
app 的使用方法
此时写出第一张图片的4 写出 LedService.java
package com.android.server;
import android.os.ILedService;
public class LedService extends ILedService.Stub {
private static final String TAG = "LedService";
/* call native c function to access hardware */
public int ledCtrl(int which, int status) throws android.os.RemoteException
{
return native_ledCtrl(which, status);
}
public LedService() {
native_ledOpen();
}
public static native int native_ledOpen();
public static native void native_ledClose();
public static native int native_ledCtrl(int which, int status);
}
实现第三部 修改 systemserver.java
实现第一步,修改之前的JNI文件 变成com_android_server_LedService.cpp
#define LOG_TAG "LedService"
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <hardware/led_hal.h>
namespace android
{
static led_device_t* led_device;
jint ledOpen(JNIEnv *env, jobject cls)
{
jint err;
hw_module_t* module;
hw_device_t* device;
ALOGI("native ledOpen ...");
/* 1. hw_get_module */
err = hw_get_module("led", (hw_module_t const**)&module);
if (err == 0) {
/* 2. get device : module->methods->open */
err = module->methods->open(module, NULL, &device);
if (err == 0) {
/* 3. call led_open */
led_device = (led_device_t *)device;
return led_device->led_open(led_device);
} else {
return -1;
}
}
return -1;
}
void ledClose(JNIEnv *env, jobject cls)
{
//ALOGI("native ledClose ...");
//close(fd);
}
jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
ALOGI("native ledCtrl %d, %d", which, status);
return led_device->led_ctrl(led_device, which, status);
}
static const JNINativeMethod methods[] = {
{"native_ledOpen", "()I", (void *)ledOpen},
{"native_ledClose", "()V", (void *)ledClose},
{"native_ledCtrl", "(II)I", (void *)ledCtrl},
};
int register_android_server_LedService(JNIEnv *env)
{
return jniRegisterNativeMethods(env, "com/android/server/LedService",
methods, NELEM(methods));
}
}
打开 onload.cpp 添加
JNI : com_android_server_LedService.cpp
onload.cpp
把新文件上传到服务器, 所在目录:
frameworks/base/services/core/jni/onload.cpp
frameworks/base/services/core/jni/com_android_server_LedService.cpp
修改 frameworks/base/services/core/jni/Android.mk :
$(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \
- $(LOCAL_REL_DIR)/com_android_server_LedService.cpp
Server : LedService.java
SystemServer.java
把新文件上传到服务器, 所在目录:
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/LedService.java
不需要修改 frameworks/base/services/core/Android.mk
它的内容里已经把该目录下所有JAVA文件自动包含进去了:
LOCAL_SRC_FILES +=
$(call all-java-files-under,java)
在安卓根目录编译:
. build/envsetup.sh
$ mmm frameworks/base/services
$ make snod //生成映像文件
$ ./gen-img.sh //报错就算了 直接 用out目录里的system.img
在/home/book/Desktop/android-5.0.2/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates 里面 找到classes.jar
在Android studio 添加
程序 要突破 64k限制 找到大象
加入这三个
完善app代码`package com.example.myapplication;
import android.os.Bundle;
import android.os.RemoteException;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;
import android.os.ILedService;
import android.os.ServiceManager;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private boolean ledon = false;
private Button button = null;
private CheckBox checkBoxLed1 = null;
private CheckBox checkBoxLed2 = null;
private CheckBox checkBoxLed3 = null;
private CheckBox checkBoxLed4 = null;
private ILedService iLedService = null;
class MyButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
ledon = !ledon;
if (ledon) {
button.setText("ALL OFF");
checkBoxLed1.setChecked(true);
checkBoxLed2.setChecked(true);
checkBoxLed3.setChecked(true);
checkBoxLed4.setChecked(true);
try {
iLedService.ledCtrl(0,1);
iLedService.ledCtrl(1,1);
iLedService.ledCtrl(2,1);
iLedService.ledCtrl(3 ,1);
} catch (RemoteException e) {
e.printStackTrace();
}
}
else {
button.setText("ALL ON");
checkBoxLed1.setChecked(false);
checkBoxLed2.setChecked(false);
checkBoxLed3.setChecked(false);
checkBoxLed4.setChecked(false);
try {
iLedService.ledCtrl(0,0);
iLedService.ledCtrl(1,0);
iLedService.ledCtrl(2,0);
iLedService.ledCtrl(3 ,0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
public void onCheckboxClicked(View view) {
// Is the view now checked?
boolean checked = ((CheckBox) view).isChecked();
// Check which checkbox was clicked
switch(view.getId()) {
case R.id.LED1:
if (checked) {
// Put some meat on the sandwich
Toast.makeText(getApplicationContext(), "LED1 on", Toast.LENGTH_SHORT).show();
try {
iLedService.ledCtrl(0,1);
} catch (RemoteException e) {
e.printStackTrace();
}
}
else {
// Remove the meat
Toast.makeText(getApplicationContext(), "LED1 off", Toast.LENGTH_SHORT).show();
try {
iLedService.ledCtrl(0,0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
case R.id.LED2:
if (checked) {
// Put some meat on the sandwich
Toast.makeText(getApplicationContext(), "LED2 on", Toast.LENGTH_SHORT).show();
try {
iLedService.ledCtrl(1,1);
} catch (RemoteException e) {
e.printStackTrace();
}
}
else {
// Remove the meat
Toast.makeText(getApplicationContext(), "LED2 off", Toast.LENGTH_SHORT).show();
try {
iLedService.ledCtrl(1,0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
case R.id.LED3:
if (checked) {
// Put some meat on the sandwich
Toast.makeText(getApplicationContext(), "LED3 on", Toast.LENGTH_SHORT).show();
try {
iLedService.ledCtrl(2,1);
} catch (RemoteException e) {
e.printStackTrace();
}
}
else {
// Remove the meat
Toast.makeText(getApplicationContext(), "LED3 off", Toast.LENGTH_SHORT).show();
try {
iLedService.ledCtrl(2,0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
case R.id.LED4:
if (checked) {
// Put some meat on the sandwich
Toast.makeText(getApplicationContext(), "LED4 on", Toast.LENGTH_SHORT).show();
try {
iLedService.ledCtrl(3,1);
} catch (RemoteException e) {
e.printStackTrace();
}
}
else {
// Remove the meat
Toast.makeText(getApplicationContext(), "LED4 off", Toast.LENGTH_SHORT).show();
try {
iLedService.ledCtrl(3,0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
// TODO: Veggie sandwich
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.BUTTON);
iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));
checkBoxLed1 = (CheckBox) findViewById(R.id.LED1);
checkBoxLed2 = (CheckBox) findViewById(R.id.LED2);
checkBoxLed3 = (CheckBox) findViewById(R.id.LED3);
checkBoxLed4 = (CheckBox) findViewById(R.id.LED4);
button.setOnClickListener(new MyButtonListener());}
}
`
此时可以成功运行
完善流程图
代码和生成的文件