此方案实现Android APP控制CPU GPIO,支持设置IO方向、输出、输入、按键功能。

[toc]

移植驱动与Framework gpio service

源码

API调用方法

demo

方法1 依赖Framework jar包(不推荐)

  1. 引入Android定制后的Framework jar包,out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
    1. 将classes.jar拷贝到app/libs/目录下
    2. 修改项目根目录build.gradle,在allprojects段内增加下面代码:
    allprojects {    repositories {        google()        jcenter()    }    gradle.projectsEvaluated {        tasks.withType(JavaCompile) {            options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\classes.jar')        }    }}
    1. 修改app/build.gradle,如下:
    android{    defaultConfig {        multiDexEnabled true    }}dependencies {    compileOnly files('libs/classes.jar')}preBuild {    doLast {        def imlFile = file(project.name + ".iml")        println('Change ' + project.name + '.iml order')        try {            def parsedXml = (new XmlParser()).parse(imlFile)            def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }            parsedXml.component[1].remove(jdkNode)            def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"            new groovy.util.Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])            groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))        } catch (FileNotFoundException e) {            // nop, iml not found        }    }}
  2. 调用
 SystemGpio gpioService = (SystemGpio) context.getSystemService("gpio");

方法二 反射调用(==推荐==)

  1. 在APP源码src/main目录下新建aidl/android/os/这样的目录结构
  2. 在aidl/android/os/目录下新建IGpioService.aidl文件,内容如下:
package android.os; /** {@hide} */interface IGpioService{    int gpioWrite(int gpio, int value);    int gpioRead(int gpio);    int gpioDirection(int gpio, int direction, int value);    int gpioRegKeyEvent(int gpio);    int gpioUnregKeyEvent(int gpio);    int gpioGetNumber();}
  1. 反射调用
Method method = null;try {    method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);    IBinder binder = (IBinder) method.invoke(null, new Object[]{"gpio"});    IGpioService gpioService = IGpioService.Stub.asInterface(binder);} catch (Exception e) {    e.printStackTrace();}

API使用说明

获取GPIO数量

在使用GPIO前建议先获取GPIO数量,当调用其它方法需要传入参数“gpio”时可以使用0~Number之间的值。
如:gpioGetNumber()返回7,说明一共有7个GPIO,那么传入参数可以为:0、1、2、3、4、5、6。

/** * Get GPIO number * @return <0: error other: GPIO number */public int gpioGetNumber() {    if (null != mGpioService) {        return mGpioService.gpioGetNumber();    }    return -1;}

设置输入输出模式

/** * GPIO direction * @param gpio 0~Number * @param direction 0: input 1: output * @param value 0: Low 1: High */public void gpioDirection(int gpio, int direction, int value) {    if (null != mGpioService) {        mGpioService.gpioDirection(gpio, direction, value);    }}

控制GPIO输出

/** * GPIO write * @param gpio 0~Number * @param value 0: Low 1: High */public void gpioWrite(int gpio, int value) {    if (null != mGpioService) {        mGpioService.gpioWrite(gpio, value);    }}

控制GPIO输入

/** * GPIO read * @param gpio 0~Number * @return 0: Low 1: High other:error */public int gpioRead(int gpio) {    if (null != mGpioService) {        return mGpioService.gpioRead(gpio);    }    return -1;}

设置GPIO为按键模式

 /** * GPIO register key event * @param gpio 0~Number */public void gpioRegKeyEvent(int gpio) {    if (null != mGpioService) {        mGpioService.gpioRegKeyEvent(gpio);    }}

设置为按键模式后,当GPIO有电平翻转时会上报按键事件,GPIO与KeyCode对应关系如下:

GPIO_0            KeyEvent.KEYCODE_GPIO_0GPIO_1            KeyEvent.KEYCODE_GPIO_1GPIO_2            KeyEvent.KEYCODE_GPIO_2GPIO_3            KeyEvent.KEYCODE_GPIO_3GPIO_4            KeyEvent.KEYCODE_GPIO_4GPIO_5            KeyEvent.KEYCODE_GPIO_5GPIO_6            KeyEvent.KEYCODE_GPIO_6GPIO_7            KeyEvent.KEYCODE_GPIO_7GPIO_8            KeyEvent.KEYCODE_GPIO_8GPIO_9            KeyEvent.KEYCODE_GPIO_9
  • 当GPIO变为低电平将上报:KeyEvent.ACTION_DOWN
  • 当GPIO变为高电平将上报:KeyEvent.ACTION_UP

如果要取消按键模式则调用如下方法:

/** * GPIO unregister key event * @param gpio 0~Number */public void gpioUnregKeyEvent(int gpio) {    if (null != mGpioService) {        mGpioService.gpioUnregKeyEvent(gpio);    }}

依赖Framework jar方式参考源码:

package com.ayst.item;import android.annotation.SuppressLint;import android.content.Context;import android.os.SystemGpio;/** * Created by Administrator on 2018/11/6. */public class GpioTest {    private SystemGpio mGpioService;    @SuppressLint("WrongConstant")    public GpioTest(Context context) {        mGpioService = (SystemGpio) context.getSystemService("gpio");    }    /**     * GPIO write     * @param gpio 0~Number     * @param value 0: Low 1: High     */    public void gpioWrite(int gpio, int value) {        if (null != mGpioService) {            mGpioService.gpioWrite(gpio, value);        }    }    /**     * GPIO read     * @param gpio 0~Number     * @return 0: Low 1: High other:error     */    public int gpioRead(int gpio) {        if (null != mGpioService) {            return mGpioService.gpioRead(gpio);        }        return -1;    }    /**     * GPIO direction     * @param gpio 0~Number     * @param direction 0: input 1: output     * @param value 0: Low 1: High     */    public void gpioDirection(int gpio, int direction, int value) {        if (null != mGpioService) {            mGpioService.gpioDirection(gpio, direction, value);        }    }    /**     * GPIO register key event     * @param gpio 0~Number     */    public void gpioRegKeyEvent(int gpio) {        if (null != mGpioService) {            mGpioService.gpioRegKeyEvent(gpio);        }    }    /**     * GPIO unregister key event     * @param gpio 0~Number     */    public void gpioUnregKeyEvent(int gpio) {        if (null != mGpioService) {            mGpioService.gpioUnregKeyEvent(gpio);        }    }    /**     * Get GPIO number     * @return <0: error other: GPIO number     */    public int gpioGetNumber() {        if (null != mGpioService) {            return mGpioService.gpioGetNumber();        }        return -1;    }}

反射方式参考源码:

package com.ayst.item;import android.annotation.SuppressLint;import android.content.Context;import android.os.IBinder;import android.os.IGpioService;import android.os.RemoteException;import java.lang.reflect.Method;/** * Created by Administrator on 2018/11/6. */public class GpioTest {    private IGpioService mGpioService;    @SuppressLint("WrongConstant")    public GpioTest(Context context) {        Method method = null;        try {            method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);            IBinder binder = (IBinder) method.invoke(null, new Object[]{"gpio"});            mGpioService = IGpioService.Stub.asInterface(binder);        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * GPIO write     *     * @param gpio  0~Number     * @param value 0: Low 1: High     */    public void gpioWrite(int gpio, int value) {        if (null != mGpioService) {            try {                mGpioService.gpioWrite(gpio, value);            } catch (RemoteException e) {                e.printStackTrace();            }        }    }    /**     * GPIO read     *     * @param gpio 0~Number     * @return 0: Low 1: High other:error     */    public int gpioRead(int gpio) {        if (null != mGpioService) {            try {                return mGpioService.gpioRead(gpio);            } catch (RemoteException e) {                e.printStackTrace();            }        }        return -1;    }    /**     * GPIO direction     *     * @param gpio      0~Number     * @param direction 0: input 1: output     * @param value     0: Low 1: High     */    public void gpioDirection(int gpio, int direction, int value) {        if (null != mGpioService) {            try {                mGpioService.gpioDirection(gpio, direction, value);            } catch (RemoteException e) {                e.printStackTrace();            }        }    }    /**     * GPIO register key event     *     * @param gpio 0~Number     */    public void gpioRegKeyEvent(int gpio) {        if (null != mGpioService) {            try {                mGpioService.gpioRegKeyEvent(gpio);            } catch (RemoteException e) {                e.printStackTrace();            }        }    }    /**     * GPIO unregister key event     *     * @param gpio 0~Number     */    public void gpioUnregKeyEvent(int gpio) {        if (null != mGpioService) {            try {                mGpioService.gpioUnregKeyEvent(gpio);            } catch (RemoteException e) {                e.printStackTrace();            }        }    }    /**     * Get GPIO number     *     * @return <0: error other: GPIO number     */    public int gpioGetNumber() {        if (null != mGpioService) {            try {                return mGpioService.gpioGetNumber();            } catch (RemoteException e) {                e.printStackTrace();            }        }        return -1;    }}

更多相关文章

  1. ContentProvider实现数据共享1
  2. Android8.0 PackageManagerService相关 -- APK安装和install 的
  3. android 中的一些小case
  4. fanfou(饭否) android客户端 代码学习2
  5. Android调用摄像头拍照(兼容7.0)
  6. Android学习整理-2-TabLayout的学习
  7. android下调用隐藏源码的问题
  8. Android(安卓)-- 自定义 View XML属性详解
  9. Android(安卓)隐藏底部虚拟键

随机推荐

  1. 再次为王!Python 是 2020 年度编程语言
  2. android用jdbc多线程操作sqlite小结
  3. C语言的一些练习以及自己写一个猜数字小
  4. 算法面试专题课(Java版)
  5. centos LVM(逻辑卷管理)
  6. Android(安卓)NDK开发之旅(5):Android(安
  7. Unity3D之坐标系的转换
  8. 数据结构之哈希表
  9. 基于业务和平台理解数字营销概念
  10. 打卡学习