[jni] 01_jni案例锅炉压力监控器

Android 4.0

JNI案例锅炉压力监控器

一、jni案例分析:这是一个嵌入式android模板
瓦斯浓度监控,温室二氧化碳浓度监控
二、技术点:
1)ndk-build编译c代码的过程
1、ndk-build ,临时生成*.o的文件,
2、然后在生成优化的*.o.d的文件
3、然后生成*.so的文件
4、最后拷贝到libs\armeabi目录下

2)获取手机屏幕大小,获取屏幕大小,根据系统版本获取屏幕大小,获取屏幕尺寸
/**
 * 1、根据系统的版本来获取屏幕的大小
 * @return
 */
@SuppressWarnings("deprecation")
private void getWindowSize() {
    WindowManager manager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
    Display display = manager.getDefaultDisplay();
    int window_width = 0;
    int window_height = 0;
    // 获取手机,系统的版本
    int sdkVersion = Build.VERSION.SDK_INT;// sdk版本
    // 获取手机屏幕大小
    if (sdkVersion < 13) {
        System.out.println("当前系统版本:" + sdkVersion);
        // 1、低版本
        window_width = display.getWidth();
        window_height = display.getHeight();
    } else {
        System.out.println("当前系统版本:" + sdkVersion);
        // 2、高版本
        Point outSize = new Point();
        display.getSize(outSize);
        window_width = outSize.x;
        window_height = outSize.y;
    }
}
3)自定义View控件,自定义组件
package cn.zengfansheng.boilerpressure;
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;
 
/**
* 自定义View对象,画矩形
* @author hacket
*/

public class RectangleView extends View {
 
    /**
     * 矩形框距离屏幕最顶端距离
     */

    private int right;
    /**
     * 画出来矩形的颜色的颜色
     */

    private int color;
 
    public RectangleView(Context context, int right, int color) {
        super(context);
        this.right = right;
        this.color = color;
    }
 
    // 所有android下的view控件的显示 其实是通过 ondraw
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
 
        // canvas 代表的是屏幕的画布
 
        // paint 画笔
        // Paint paint = new Paint();
        // paint.setColor(Color.RED);
        // paint.setTextSize(20.0f);
        // paint.setStrokeWidth(18.0f);
        // canvas.drawText("哥哥我是被画出来的", 30, 30, paint);
 
        Paint paint = new Paint();
        paint.setStrokeWidth(10);
        paint.setColor(color);
        // right值,需要根据锅炉的压力 动态确定
        canvas.drawRect(10, 30, right, 50, paint);
    }
}
4)Handler+Message

三、步骤:
1、c工程师写一个方法模拟获取锅炉压力的值rand()
2、在java代码中利用jni调用获取锅炉压力的方法JNI
3、利用定时器,每隔1秒钟来获取该压力值Timer,TimerTask
4、通过发送消息,在界面上展示出来,Hander+Message
5、长方块条,根据压力值的大小,显示不同的长度和颜色,这就要用到自定义控件(继承View,复写onDraw方法)
四、核心代码:
a)自定义View组件RectangleView 
package cn.zengfansheng.boilerpressure;
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;
 
/**
* 自定义View对象,画矩形
* @author hacket
*/

public class RectangleView extends View {
 
    /**
     * 矩形框距离屏幕最顶端距离
     */

    private int right;
    /**
     * 画出来矩形的颜色的颜色
     */

    private int color;
 
    public RectangleView(Context context, int right, int color) {
        super(context);
        this.right = right;
        this.color = color;
    }
 
    // 所有android下的view控件的显示 其实是通过 ondraw
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
 
        // canvas 代表的是屏幕的画布
 
        // paint 画笔
        // Paint paint = new Paint();
        // paint.setColor(Color.RED);
        // paint.setTextSize(20.0f);
        // paint.setStrokeWidth(18.0f);
        // canvas.drawText("哥哥我是被画出来的", 30, 30, paint);
 
        Paint paint = new Paint();
        paint.setStrokeWidth(10);
        paint.setColor(color);
        // right值,需要根据锅炉的压力 动态确定
        canvas.drawRect(10, 30, right, 50, paint);
    }
 
}
b)BoilerActivity.java
package cn.zengfansheng.boilerpressure;
 
import java.util.Timer;
import java.util.TimerTask;
 
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Display;
import android.view.WindowManager;
import android.widget.TextView;
 
@SuppressLint("NewApi")
public class BoilerActivity extends Activity {
 
    private static final int HIGH_PRESSURE = 404;// 高压力
 
    private native int obtainPressure();
 
    private Timer timer;
    private TimerTask task;
    int WINDOW_HEIGHT;
 
    private Handler handler = new Handler() {
 
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
 
            int pressure = (Integer) msg.obj;
 
            int color = obtainColor(pressure);
            if (color == 404) {
                TextView tView = new TextView(BoilerActivity.this);
                tView.setText("压力过高,要爆炸了~~~");
                tView.setTextColor(Color.RED);
                // TODO 播放报警声音
                BoilerActivity.this.setContentView(tView);
                timer.cancel();
                return;
            }
            RectangleView rectangleView = new RectangleView(BoilerActivity.this, pressure, color);
            BoilerActivity.this.setContentView(rectangleView);
        }
 
    };
 
    static {
        // libgetPressure.so
        System.loadLibrary("getPressure");
    }
 
    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        // 测试自定义View
        // RectangleView rectangleView = new RectangleView(this);
        // this.setContentView(rectangleView);
 
        timer = new Timer();
        task = new TimerTask() {
 
            @Override
            public void run() {
                int pressure = obtainPressure();
                System.out.println("压力值:" + pressure);
                Message msg = Message.obtain();
                msg.obj = pressure;
                handler.sendMessage(msg);
            }
        };
        timer.schedule(task, 1000, 1000);// 延迟一秒,每秒钟获取一次压力值
    }
 
    /**
     * 2、根据压力值来获取颜色
     * @param pressure 压力值
     * @return 返回不同压力值的范围的颜色值
     */

    private int obtainColor(int pressure) {
        if (pressure < 100) {
            return Color.GREEN;
        } else if (pressure < 200) {
            return Color.YELLOW;
        } else if (pressure < 20) {
            return Color.RED;
        } else {
            return HIGH_PRESSURE;
        }
    }
 
    /**
     * 1、根据系统的版本来获取屏幕的大小
     * @return
     */

    @SuppressWarnings("deprecation")
    private void getWindowSize() {
        WindowManager manager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        Display display = manager.getDefaultDisplay();
 
        int window_width = 0;
        int window_height = 0;
 
        // 获取手机,系统的版本
        int sdkVersion = Build.VERSION.SDK_INT;// sdk版本
 
        // 获取手机屏幕大小
        if (sdkVersion < 13) {
            System.out.println("当前系统版本:" + sdkVersion);
            // 1、低版本
            window_width = display.getWidth();
            window_height = display.getHeight();
        } else {
            System.out.println("当前系统版本:" + sdkVersion);
            // 2、高版本
            Point outSize = new Point();
            display.getSize(outSize);
            window_width = outSize.x;
            window_height = outSize.y;
        }
    }
}
源码:
结果: