【问题标题】:Andriod app crashes while calling Java.IO.FileDescriptor Open(String path, int baudrate, int flags);Andriod 应用程序在调用 Java.IO.FileDescriptor Open(String path, int baudrate, int flags) 时崩溃;
【发布时间】:2021-04-15 17:02:56
【问题描述】:

我是 xamarin 的新手。 为 ProDVX android 8.1.0 开发应用程序来切换 LED 灯 我正在关注一个用 java 编写的示例。

package android_serialport_api;

import android.util.Log;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class SerialPort {

    private static final String TAG = "SerialPort";

    /*
     * Do not remove or rename the field mFd: it is used by native method close();
     */
    private FileDescriptor mFd;
    private FileInputStream mFileInputStream;
    private FileOutputStream mFileOutputStream;

    public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {

        /* Check access permission */
        if (!device.canRead() || !device.canWrite()) {
            try {
                /* Missing read/write permission, trying to chmod the file */
                Process su;
                su = Runtime.getRuntime().exec("/system/bin/su");
                String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
                        + "exit\n";
                su.getOutputStream().write(cmd.getBytes());
                if ((su.waitFor() != 0) || !device.canRead()
                        || !device.canWrite()) {
                    throw new SecurityException();
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new SecurityException();
            }
        }

        mFd = open(device.getAbsolutePath(), baudrate, flags);
        if (mFd == null) {
            Log.e(TAG, "native open returns null");
            throw new IOException();
        }
        mFileInputStream = new FileInputStream(mFd);
        mFileOutputStream = new FileOutputStream(mFd);
    }

    // Getters and setters
    public FileInputStream getFileInputStream() {
        return mFileInputStream;
    }

    public FileOutputStream getFileOutputStream() {
        return mFileOutputStream;
    }

    // JNI
    private native static FileDescriptor open(String path, int baudrate, int flags);
    public native void close();
    static {
        System.loadLibrary("serial_port");
    }

}

现在调用这些函数来切换 LED

public void AllGreenOn() {                   //All Green the lights
        try {
            sp = new SerialPort(new File("/dev/ttyS1"), 115200, 0);
        } catch (IOException e) {
            e.printStackTrace();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (lock == null) {
                    System.out.println("lock = null");
                } else {
                    try {
                        synchronized (lock) {
                            out = sp.getFileOutputStream();
                            AllGOnLamps();
                            out.close();
                            sp.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).run();
    }
private void AllGOnLamps() throws IOException {                   //All the Green lights
int num1 = 0x55;
int num2 = 0xaa;        
int numL = 0xfb;
        int numR = 0;
        int numB = 0;
        int numG = 0x70;
int num7 = 0x88;
        out.write(intToByteArray(num1));
        out.write(intToByteArray(num2));
        for (int i = 0; i < 52; i++) {
            out.write(intToByteArray(numL));
            out.write(intToByteArray(numB));
            out.write(intToByteArray(numR));
            out.write(intToByteArray(numG));
        }
        out.write(intToByteArray(num7));
    }

我正在 c# 中尝试这个,我的代码是

public class SerialPort
    {
        private Java.IO.FileDescriptor mFd;
        private Java.IO.FileInputStream mFileInputStream;
        private Java.IO.FileOutputStream mFileOutputStream;
     
        //[System.Runtime.InteropServices.DllImport("serial_port.so")]
        //private static extern Java.IO.FileDescriptor Open(String path, int baudrate, int flags);
        
        
        public SerialPort(Java.IO.File device, int baudrate, int flags)
        {
            MainActivity.addDebug(" su beging: .....");
            
            if (!device.CanRead() || !device.CanWrite())
            {
                
                MainActivity.addDebug("process su started: .....");
                Java.Lang.Process su;
                su = Java.Lang.Runtime.GetRuntime().Exec("su");

                MainActivity.addDebug("process su made: .....");
                string cmd = "chmod 666 " + device.AbsolutePath + "\n" + "exit\n";
                su.OutputStream.Write(Encoding.ASCII.GetBytes(cmd));

                MainActivity.addDebug("chmod 666 written ..... ");
            }

            mFd = Open(device.AbsolutePath, baudrate, flags);
            
            if (mFd == null)
            {
                MainActivity.addDebug("mfd made");
                throw new Exception();
            }
            mFileInputStream = new Java.IO.FileInputStream(mFd);
            mFileOutputStream = new Java.IO.FileOutputStream(mFd);

        }
        public Java.IO.FileInputStream getFileInputStream()
        {
            return mFileInputStream;
        }
        public Java.IO.FileOutputStream getFileOutputStream()
        {
            return mFileOutputStream;
        }
        
    }

public void AllGreenOn()
        {
            try
            {
                sp = new SerialPort(new Java.IO.File("/dev/ttyS1"), 115200, 0);
                _out = sp.getFileOutputStream();
                AllGOnLamps();
                _out.Close();
                
            }
            catch (IOException e)
            {
                
            }
        }

private SerialPort sp;
private Java.IO.FileOutputStream _out = null;
public void AllGOnLamps()
{

    int num1 = 0x55;
    int num2 = 0xaa;        
    int numL = 0xfb;
    int numR = 0;
    int numB = 0;
    int numG = 0x70;
    int num7 = 0x88;

    _out.Write(intToByteArray(num1));
    _out.Write(intToByteArray(num2));
    MainActivity.addDebug("num1 written ..... ");

    for (int i = 0; i < 52; i++)
    {
        _out.Write(intToByteArray(numL));
        _out.Write(intToByteArray(numB));
        _out.Write(intToByteArray(numR));
        _out.Write(intToByteArray(numG));

    }

    _out.Write(intToByteArray(num7));
    MainActivity.addDebug("num7 written ..... ");


   

}

现在这里 mFd = Open(device.AbsolutePath, baudrate, flags);导致应用崩溃

我不知道我在哪里做错了。对此的任何建议或替代方案都将受到高度评价。

【问题讨论】:

    标签: java c# android visual-studio


    【解决方案1】:

    C#代码有一些问题,我建议查看原始原生库的源代码。

    例如,您应该指定一个方法名称与本机方法签名不匹配的入口点。

    [System.Runtime.InteropServices.DllImport("serial_port", EntryPoint = "Java_android_1serialport_1api_SerialPort_open")]
    

    https://github.com/cepr/android-serialport-api/blob/master/android-serialport-api/project/jni/SerialPort.c

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-16
      • 2014-05-07
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多