Android GPIO 控制方案

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

移植驱动与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段内增加下面代码:
     
    1. allprojects {

    2. repositories {

    3. google()

    4. jcenter()

    5. }

    6.  
    7. gradle.projectsEvaluated {

    8. tasks.withType(JavaCompile) {

    9. options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\classes.jar')

    10. }

    11. }

    12. }

    1. 修改app/build.gradle,如下:
     
    1. android{

    2. defaultConfig {

    3. multiDexEnabled true

    4. }

    5. }

    6.  
    7. dependencies {

    8. compileOnly files('libs/classes.jar')

    9. }

    10.  
    11. preBuild {

    12. doLast {

    13. def imlFile = file(project.name + ".iml")

    14. println('Change ' + project.name + '.iml order')

    15. try {

    16. def parsedXml = (new XmlParser()).parse(imlFile)

    17. def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }

    18. parsedXml.component[1].remove(jdkNode)

    19. def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"

    20. new groovy.util.Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])

    21. groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))

    22. } catch (FileNotFoundException e) {

    23. // nop, iml not found

    24. }

    25. }

    26. }

  2. 调用
 SystemGpio gpioService = (SystemGpio) context.getSystemService("gpio");

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

  1. 在APP源码src/main目录下新建aidl/android/os/这样的目录结构
  2. 在aidl/android/os/目录下新建IGpioService.aidl文件,内容如下:
 
  1. package android.os;

  2.  
  3. /** {@hide} */

  4. interface IGpioService

  5. {

  6. int gpioWrite(int gpio, int value);

  7. int gpioRead(int gpio);

  8. int gpioDirection(int gpio, int direction, int value);

  9. int gpioRegKeyEvent(int gpio);

  10. int gpioUnregKeyEvent(int gpio);

  11. int gpioGetNumber();

  12. }

  1. 反射调用
 
  1. Method method = null;

  2. try {

  3. method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);

  4. IBinder binder = (IBinder) method.invoke(null, new Object[]{"gpio"});

  5. IGpioService gpioService = IGpioService.Stub.asInterface(binder);

  6. } catch (Exception e) {

  7. e.printStackTrace();

  8. }

API使用说明

获取GPIO数量

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

 
  1. /**

  2. * Get GPIO number

  3. * @return <0: error other: GPIO number

  4. */

  5. public int gpioGetNumber() {

  6. if (null != mGpioService) {

  7. return mGpioService.gpioGetNumber();

  8. }

  9. return -1;

  10. }

设置输入输出模式

 
  1. /**

  2. * GPIO direction

  3. * @param gpio 0~Number

  4. * @param direction 0: input 1: output

  5. * @param value 0: Low 1: High

  6. */

  7. public void gpioDirection(int gpio, int direction, int value) {

  8. if (null != mGpioService) {

  9. mGpioService.gpioDirection(gpio, direction, value);

  10. }

  11. }

控制GPIO输出

 
  1. /**

  2. * GPIO write

  3. * @param gpio 0~Number

  4. * @param value 0: Low 1: High

  5. */

  6. public void gpioWrite(int gpio, int value) {

  7. if (null != mGpioService) {

  8. mGpioService.gpioWrite(gpio, value);

  9. }

  10. }

控制GPIO输入

 
  1. /**

  2. * GPIO read

  3. * @param gpio 0~Number

  4. * @return 0: Low 1: High other:error

  5. */

  6. public int gpioRead(int gpio) {

  7. if (null != mGpioService) {

  8. return mGpioService.gpioRead(gpio);

  9. }

  10. return -1;

  11. }

设置GPIO为按键模式

 
  1. /**

  2. * GPIO register key event

  3. * @param gpio 0~Number

  4. */

  5. public void gpioRegKeyEvent(int gpio) {

  6. if (null != mGpioService) {

  7. mGpioService.gpioRegKeyEvent(gpio);

  8. }

  9. }

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

 
  1. GPIO_0 KeyEvent.KEYCODE_GPIO_0

  2. GPIO_1 KeyEvent.KEYCODE_GPIO_1

  3. GPIO_2 KeyEvent.KEYCODE_GPIO_2

  4. GPIO_3 KeyEvent.KEYCODE_GPIO_3

  5. GPIO_4 KeyEvent.KEYCODE_GPIO_4

  6. GPIO_5 KeyEvent.KEYCODE_GPIO_5

  7. GPIO_6 KeyEvent.KEYCODE_GPIO_6

  8. GPIO_7 KeyEvent.KEYCODE_GPIO_7

  9. GPIO_8 KeyEvent.KEYCODE_GPIO_8

  10. GPIO_9 KeyEvent.KEYCODE_GPIO_9

  • 当GPIO变为低电平将上报:KeyEvent.ACTION_DOWN
  • 当GPIO变为高电平将上报:KeyEvent.ACTION_UP

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

 
  1. /**

  2. * GPIO unregister key event

  3. * @param gpio 0~Number

  4. */

  5. public void gpioUnregKeyEvent(int gpio) {

  6. if (null != mGpioService) {

  7. mGpioService.gpioUnregKeyEvent(gpio);

  8. }

  9. }

依赖Framework jar方式参考源码:

 
  1. package com.ayst.item;

  2.  
  3. import android.annotation.SuppressLint;

  4. import android.content.Context;

  5. import android.os.SystemGpio;

  6.  
  7. /**

  8. * Created by Administrator on 2018/11/6.

  9. */

  10.  
  11. public class GpioTest {

  12. private SystemGpio mGpioService;

  13.  
  14. @SuppressLint("WrongConstant")

  15. public GpioTest(Context context) {

  16. mGpioService = (SystemGpio) context.getSystemService("gpio");

  17. }

  18.  
  19. /**

  20. * GPIO write

  21. * @param gpio 0~Number

  22. * @param value 0: Low 1: High

  23. */

  24. public void gpioWrite(int gpio, int value) {

  25. if (null != mGpioService) {

  26. mGpioService.gpioWrite(gpio, value);

  27. }

  28. }

  29.  
  30. /**

  31. * GPIO read

  32. * @param gpio 0~Number

  33. * @return 0: Low 1: High other:error

  34. */

  35. public int gpioRead(int gpio) {

  36. if (null != mGpioService) {

  37. return mGpioService.gpioRead(gpio);

  38. }

  39. return -1;

  40. }

  41.  
  42. /**

  43. * GPIO direction

  44. * @param gpio 0~Number

  45. * @param direction 0: input 1: output

  46. * @param value 0: Low 1: High

  47. */

  48. public void gpioDirection(int gpio, int direction, int value) {

  49. if (null != mGpioService) {

  50. mGpioService.gpioDirection(gpio, direction, value);

  51. }

  52. }

  53.  
  54. /**

  55. * GPIO register key event

  56. * @param gpio 0~Number

  57. */

  58. public void gpioRegKeyEvent(int gpio) {

  59. if (null != mGpioService) {

  60. mGpioService.gpioRegKeyEvent(gpio);

  61. }

  62. }

  63.  
  64. /**

  65. * GPIO unregister key event

  66. * @param gpio 0~Number

  67. */

  68. public void gpioUnregKeyEvent(int gpio) {

  69. if (null != mGpioService) {

  70. mGpioService.gpioUnregKeyEvent(gpio);

  71. }

  72. }

  73.  
  74. /**

  75. * Get GPIO number

  76. * @return <0: error other: GPIO number

  77. */

  78. public int gpioGetNumber() {

  79. if (null != mGpioService) {

  80. return mGpioService.gpioGetNumber();

  81. }

  82. return -1;

  83. }

  84. }

  85.  

反射方式参考源码:

 
  1. package com.ayst.item;

  2.  
  3. import android.annotation.SuppressLint;

  4. import android.content.Context;

  5. import android.os.IBinder;

  6. import android.os.IGpioService;

  7. import android.os.RemoteException;

  8.  
  9. import java.lang.reflect.Method;

  10.  
  11. /**

  12. * Created by Administrator on 2018/11/6.

  13. */

  14.  
  15. public class GpioTest {

  16. private IGpioService mGpioService;

  17.  
  18. @SuppressLint("WrongConstant")

  19. public GpioTest(Context context) {

  20. Method method = null;

  21. try {

  22. method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);

  23. IBinder binder = (IBinder) method.invoke(null, new Object[]{"gpio"});

  24. mGpioService = IGpioService.Stub.asInterface(binder);

  25. } catch (Exception e) {

  26. e.printStackTrace();

  27. }

  28. }

  29.  
  30. /**

  31. * GPIO write

  32. *

  33. * @param gpio 0~Number

  34. * @param value 0: Low 1: High

  35. */

  36. public void gpioWrite(int gpio, int value) {

  37. if (null != mGpioService) {

  38. try {

  39. mGpioService.gpioWrite(gpio, value);

  40. } catch (RemoteException e) {

  41. e.printStackTrace();

  42. }

  43. }

  44. }

  45.  
  46. /**

  47. * GPIO read

  48. *

  49. * @param gpio 0~Number

  50. * @return 0: Low 1: High other:error

  51. */

  52. public int gpioRead(int gpio) {

  53. if (null != mGpioService) {

  54. try {

  55. return mGpioService.gpioRead(gpio);

  56. } catch (RemoteException e) {

  57. e.printStackTrace();

  58. }

  59. }

  60. return -1;

  61. }

  62.  
  63. /**

  64. * GPIO direction

  65. *

  66. * @param gpio 0~Number

  67. * @param direction 0: input 1: output

  68. * @param value 0: Low 1: High

  69. */

  70. public void gpioDirection(int gpio, int direction, int value) {

  71. if (null != mGpioService) {

  72. try {

  73. mGpioService.gpioDirection(gpio, direction, value);

  74. } catch (RemoteException e) {

  75. e.printStackTrace();

  76. }

  77. }

  78. }

  79.  
  80. /**

  81. * GPIO register key event

  82. *

  83. * @param gpio 0~Number

  84. */

  85. public void gpioRegKeyEvent(int gpio) {

  86. if (null != mGpioService) {

  87. try {

  88. mGpioService.gpioRegKeyEvent(gpio);

  89. } catch (RemoteException e) {

  90. e.printStackTrace();

  91. }

  92. }

  93. }

  94.  
  95. /**

  96. * GPIO unregister key event

  97. *

  98. * @param gpio 0~Number

  99. */

  100. public void gpioUnregKeyEvent(int gpio) {

  101. if (null != mGpioService) {

  102. try {

  103. mGpioService.gpioUnregKeyEvent(gpio);

  104. } catch (RemoteException e) {

  105. e.printStackTrace();

  106. }

  107. }

  108. }

  109.  
  110. /**

  111. * Get GPIO number

  112. *

  113. * @return <0: error other: GPIO number

  114. */

  115. public int gpioGetNumber() {

  116. if (null != mGpioService) {

  117. try {

  118. return mGpioService.gpioGetNumber();

  119. } catch (RemoteException e) {

  120. e.printStackTrace();

  121. }

  122. }

  123. return -1;

  124. }

  125. }

转自:https://blog.csdn.net/weixin_34115824/article/details/88488990

猜你喜欢

转载自blog.csdn.net/WXXGoodJob/article/details/90599925
今日推荐