Android应用程序读写/dev下设备

一丶简介

平台:msm8953

环境:ubuntu16.04

Android app对/dev下的设备是不具有读写权限的,应用程序怎样才能读写/dev下设备呢?本文以spi设备为例,应用程序通过jni的方法去访问/dev下的spi设备。

配置好spi后,在dev下出现了spidev6.0的设备节点,通过ls -l -Z /dev/spidev6.0,可见:

crw------- 1 root root u:object_r:device:s0 226

此设备拥有者为root,其他用户或用户组不具有读写权限。

二丶步骤

1. 给spidev6.0读写权限:

位置:device/qcom/common/rootdir/etc/init.qcom.rc

添加,

chmod 777 /dev/spidev6.0

编译boot烧写后,运行测试程序:

打开失败,android具有selinux机制,不允许未知来源的app读写设备。所以我们得配置/dev/spidev6.0允许未知来源app读写。

2.添加设备:

位置:device/qcom/sepolicy/common/file_contexts

Dev nodes下添加,

/dev/spidev6.0               u:object_r:spidev_device:s0

3.自定义设备类型

位置:device/qcom/sepolicy/common/device.te

添加,

type spidev_device, dev_type, mlstrustedobject;

4.允许未知来源app操作spi

未知:device/qcom/sepolicy/common/untrusted_app.te

allow untrusted_app spidev_device:chr_file rw_file_perms;

此时运行应用程序,打开spidev成功!

附源码:

MainActivity.java:



import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    private final static String TAG = "MainActivity";
    public final static String SPIDEV = "/dev/spidev6.0";
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Spi spi = new Spi();
        int ret = spi.open(SPIDEV);
        if(ret == -1)
            Log.e(TAG,"open spidev failed :"+ SPIDEV);
        else
            Log.e(TAG,"success,fd :"+ ret);
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

Spi.java



public class Spi {
    int fd;
    private final static String TAG = "Spi";
    private String spiName;

    public Spi() {}
    public Spi(String spiName){
        this.spiName = spiName;
    }

    public int open(String spiName){
       fd = open_native(spiName);
       return fd > 0 ? fd :-1;
    }

    private native int open_native(String spiName);
}

spi.cpp

//
// Created by liujian on 2019/10/9.
//

#include 
#include 
#include "jni.h"

/**
 * @author liujian
 * @date 2019-07-02
 * @brief open spi
 * @param deviceName:index
 * @return file descriptor
 */
static int spiOpen(char const* deviceName){
    int fd=open(deviceName,O_RDWR);//读写方式 int fd=open(deviceName,O_RDWR|O_NONBLOCK);
    if(fd<0){
        return -1;
    }

    return fd;
}

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_sc60devicesutils_Spi_open_1native(JNIEnv *env, jobject instance,
                                                       jstring spiName_) {
    const char *spiName = env->GetStringUTFChars(spiName_, 0);

    char item_value[128];
    strcpy(item_value, spiName);
    env->ReleaseStringUTFChars(spiName_, spiName);

    return spiOpen(item_value);
}

别忘了在CMakeList里面加入spi.cpp:

add_library( # Sets the name of the library.
        native-lib

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        native-lib.cpp
        spi.cpp)

 

你可能感兴趣的:(Android应用程序读写/dev下设备)