驱动模型 从底层驱动到HAL到JNI到app到云端服务器

app通过二维码开关扫描请求云服务器对蜂鸣器的开或关
        概述:arm端建立服务与云端连接等待云服务器的命令,手机扫描二维码通过二维码里面的设备号和开或者关信息发送到云端服务器,云端服务器根据设备号找到对应的arm端发送相应的开或关命令,从而实现手机APP云端控制
1.硬件原理图  
蜂鸣器连接(GPD0_1)管脚
2.芯片手册
蜂鸣器的控制地址为 int id = 0xe02000a0;
配置为输出端口 (*(int *)id)&(~(0xf<<4)); (*(int *)id)&(0x1<<4);
蜂鸣器数据地址为 int add = 0xe02000a4;
蜂鸣器启动  (*(int *) add )|(0x1<<1));
蜂鸣器停止 (*(int *) add )&(~(0x1<<1));


3.编写驱动
        buzz_drv.c代码编写
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h> /* for class_create() and device_create() */
#include <linux/cdev.h> /* for cdev */
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/io.h>
static int num = 1;
static int major = 0;
struct buzz_cdev {
struct cdev cdev;
struct class *buzz_class;
struct device *buzz_device;
//...
int buzz_val;
};
struct buzz_cdev *buzz_dev =NULL;
/* buzz 控制寄存器的物理地址*/
#define BUZZ_PHY_GPC0BASE 0xe02000a0
/*(GPD0_1)管脚 所有为8 一个int4位*/
#define BUZZ_PHY_GPC0LEN 8
/* buzz 控制寄存器的虚拟地址 */
volatile unsigned long *gpd0con =NULL;
volatile unsigned long *gpd0dat = NULL;
/*打开外设 */
static int buzz_open (struct inode *inode, struct file *file)
{
//外设的初始化
gpd0con = ioremap(BUZZ_PHY_GPC0BASE, BUZZ_PHY_GPC0LEN);
if(!gpd0con){
printk(KERN_ERR "ioremap buzz physical address failed.!\n");
return -ENOMEM;
}
gpd0dat = gpd0con +1; //指针+1,表示4个字节 dpd0_1管脚
/*将GPd0_1配置成输出功能 */
*gpd0con = *gpd0con & ~(0xff<<4);
*gpd0con = *gpd0con & (0x1<<4);
return 0;
}
static ssize_t buzz_read (struct file * file, char __user *buf, size_t count, loff_t *offsize)
{
printk("func: %s() line: %d\n", __func__, __LINE__);
return count;
}
static ssize_t buzz_write(struct file *file, const char __user *buf,
size_t bytes, loff_t *off)
{
int ker_val, ret=-1;
ret = copy_from_user(&ker_val, buf, sizeof(int));
if(ret < 0) {
printk("buzz_write() failed!\n");
goto out;
}
if(ker_val == 1) { //打开蜂鸣器
*gpd0dat |= 1<<1;
} else { //关闭蜂鸣器
*gpd0dat &= ~(1<<1);
}
return bytes;
out:
return ret;
}
static int buzz_close(struct inode * inode, struct file * file)
{
// *gpd0dat &= ~(1<<1); //关闭蜂鸣器
iounmap(gpd0con);
return 0;
}
static struct file_operations fops = {
.owner = THIS_MODULE, /* 模块的自动计数 */
.open = buzz_open,
.read = buzz_read,
.write = buzz_write,
.release = buzz_close,
};
static int buzz_setup_cdev(void)
{
int err, devno = MKDEV(major,0);
/* 初始化cdev*/
cdev_init(&buzz_dev->cdev,&fops);
buzz_dev->cdev.owner = THIS_MODULE;
buzz_dev->cdev.ops = &fops;
/* 向系统注册*/
err = cdev_add(&buzz_dev->cdev, devno, 1);
if(err < 0) {
printk(KERN_ERR "Added cdev device failed.\n");
return err;
}
return 0;
}
static int __init buzz_init(void)
{
dev_t devno = MKDEV(major, 0);
int ret = -1;
buzz_dev = (struct buzz_cdev *)kmalloc(sizeof(struct buzz_cdev), GFP_KERNEL);
if(!buzz_dev) {
ret = -ENOMEM;
goto out_err_0;
}
/* 向系统申明占用设备号或让系统自动分配设备号*/
if(major) {
ret = register_chrdev_region(devno, 1, "buzz");
} else {
ret = alloc_chrdev_region(&devno,0,1,"buzz");
major = MAJOR(devno);
}
if(ret < 0) {
printk(KERN_ERR "register chrdev device number failed\n");
goto out_err_1;
}
ret = buzz_setup_cdev();
if( ret < 0) {
goto out_err_2;
}
/* 自动创建设备节点*/
buzz_dev->buzz_class = class_create(THIS_MODULE, "buzz_class");
if(IS_ERR(buzz_dev->buzz_class)) {
printk("class_create() failed");
goto out_err_3;
}
buzz_dev->buzz_device = device_create(buzz_dev->buzz_class, NULL,
MKDEV(major, 0), NULL, "buzz"); //正常情况下系统会自动创建/dev/buzz
if(IS_ERR(buzz_dev->buzz_device)) {
printk("device_create() failed");
goto out_err_4;
}
printk("buzz driver has installed.\n");
/* 正常返回*/
return 0;
out_err_4:
class_destroy(buzz_dev->buzz_class);
out_err_3:
cdev_del(&buzz_dev->cdev);
out_err_2:
unregister_chrdev_region(MKDEV(major, 0),1);
out_err_1:
kfree(buzz_dev);
out_err_0:
return ret;
}
static void __exit buzz_exit(void)
{
device_destroy(buzz_dev->buzz_class,MKDEV(major, 0));
class_destroy(buzz_dev->buzz_class);
cdev_del(&buzz_dev->cdev);
unregister_chrdev_region(MKDEV(major, 0),1);
return;
}
module_param(num, int, S_IRWXU);
module_init(buzz_init); /* 驱动的入口*/
module_exit(buzz_exit); /* 驱动的出口*/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("buzz@farsight.com.cn");
MODULE_DESCRIPTION("This is cdev demo driver");
        Makefile编写

ifeq ($(KERNELRELEASE),)
KERNELDIR = /home/george/src_210/linux-3.0.8-FS210
PWD =$(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.so *.o *.ko .tmp_versions *.mod.c *.order *.symvers
else
obj-m :=buzz_drv.o
endif

创建自己的sh文件如infrare.sh:                                                                                        # ! /system/bin/sh
           insmod /device.ko                                                                                                              insmod /control.ko                                                                                                              mknod /dev/controler c 240 0
修改init.rc最后写入自己的脚本                                                                                            service infrare /system/bin/sh /data/infrare.sh                                                                               user root                                                                                                                             soneshot
这样就可以使用自己的驱动了另外在init.rc中的总结init中可以执行insmod命令但是不能执行mknod的,解释是这样的init.rc里所有可用的command都定义在system/core/init/keyword.h里,默认是不包含mknod的。事实上,Android的init进程会通过kenel的uevent来自动创建设备节点(见system/core/init/devices.c里的make_device()函数)。


4.硬件抽象层
        buzz_hal.h
#ifndef __BUZZ_HAL_H__
#define __BUZZ_HAL_H__
#include <hardware/hardware.h>
#define BUZZ_HAL_MODULE_ID "buzz_hal"
//扩展device对象和module对象
struct buzz_hw_module_t{ //自由定义
//继承父类
struct hw_module_t common; //一定要在第一个位置,必须叫做common
//进行扩展--可选的
//char *name ;
//void (*test)();
};
struct buzz_hw_device_t{
//继承父类
struct hw_device_t common; //一定要在第一个位置,必须叫做common
//进行扩展--可选的
int (*open)(void);
int (*switch_on)(int on);
};
#endif
        buzz_hal.c


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "buzz_hal.h"
#define LOG_TAG "buzz_hal_log"
#include <utils/Log.h>
static int buzz_fd = -1;
//去操作硬件
int buzz_hal_device_close(struct hw_device_t* device)
{
LOGD("-----^_^ %s--------\n", __FUNCTION__);
if(device != NULL)
{
free(device);
}
close(buzz_fd);
return 0;
}
int buzz_hal_device_open(void)
{
LOGD("-----^_^ %s--------\n", __FUNCTION__);
buzz_fd = open("/dev/buzz", O_RDWR);
if(buzz_fd < 0)
{
LOGE("open buzz : %s\n", strerror(errno));
return -1;
}
return 0;
}
int buzz_hal_device_switch(int on)
{
LOGD("-----^_^ %s--------\n", __FUNCTION__);
int ret = -1;
ret = write(buzz_fd, &on, 4);
if(ret < 0)
{
LOGE("write buzz off : %s\n", strerror(errno));
return -1;
}
return 0;
}
//如果该函数被调用,传递第三个参数为一个一级指针,该指针就会等于mydev
int buzz_module_open(const struct hw_module_t* module, const char* id,
struct hw_device_t** device)
{
LOGD("-----^_^ %s--------\n", __FUNCTION__);
//构建device对象
struct buzz_hw_device_t *mydev = NULL;
//动态去创建
mydev = (struct buzz_hw_device_t *)malloc(sizeof(struct buzz_hw_device_t));
if(mydev == NULL)
{
LOGE("malloc for buzz_hw_device_t error\n");
return -1;
}
//初始化
mydev->common.tag = HARDWARE_DEVICE_TAG;
mydev->common.version = 1;
mydev->common.module = (struct hw_module_t*)module;
mydev->common.close = buzz_hal_device_close;
//初始化扩展的部分
mydev->open = buzz_hal_device_open;
mydev->switch_on = buzz_hal_device_switch;
//将当前mydev交给jni
*device = (struct hw_device_t*)mydev;
return 0;
}
struct hw_module_methods_t my_module_methods = {
open : buzz_module_open,
};
//实例化module对象
// p->common.methods->open();
struct buzz_hw_module_t HMI = { //变量名一定要是HMI
//初始化
common :{
tag : HARDWARE_MODULE_TAG,
version_major : 1,
version_minor : 0,
id : BUZZ_HAL_MODULE_ID,
name : "this is a simple buzz hal hahah",
author : "luxun-zhoushuren@163.com",
methods : &my_module_methods,
},
};



        Android.mk



LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := \
libcutils
LOCAL_SRC_FILES:= buzz_hal.c
LOCAL_MODULE := buzz_hal.default
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)


5.JNI层
        buzz_jni.cpp

#define LOG_TAG "buzz_jni_log"
#include <utils/Log.h>
#include "jni.h"
// 对于hal的头文件, 典型的做法: libhardware/hardware/buzz_hal.h
//其他的代码去引用的时候: #include <hardware/buzz_hal.h>
/*
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
$(LOCAL_PATH)/../buzz_hal
*/
#include "buzz_hal.h"
//声明两个指针
static struct buzz_hw_module_t *pModule;
static struct buzz_hw_device_t *pDevice;
/*
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
*/
jint open_buzz(JNIEnv *env, jobject thiz)
{
LOGD("-----^_^ %s--------\n", __FUNCTION__);
//加载hal.so
jint ret = -1;
//如果在代码中使用了该函数,编译的时候需要连接 libhardware
ret = hw_get_module(BUZZ_HAL_MODULE_ID, (const struct hw_module_t * *)&pModule);
if(ret == 0)
{
if(pModule != NULL)
{
//调用module中的open方法
//p->common.methods->open();
pModule->common.methods->open(&pModule->common,NULL, (struct hw_device_t**)&pDevice);
if(pDevice != NULL)
{
//调用device中的方法
ret = pDevice->open();
if(ret < 0)
{
LOGE("open device error\n");
return -1;
}
}
}
}else{
LOGE("hw_get_module error\n");
return -2;
}
return 0;
}
jint buzz_off(JNIEnv *env, jobject thiz)
{
LOGD("-----^_^ %s--------\n", __FUNCTION__);
jint ret = -1;
if(pDevice != NULL)
{
ret = pDevice->switch_on(0);
if(ret < 0){
return -1;
}
}
return 0;
}
jint buzz_on(JNIEnv *env, jobject thiz)
{
LOGD("-----^_^ %s--------\n", __FUNCTION__);
jint ret = -1;
if(pDevice != NULL)
{
ret = pDevice->switch_on(1);
if(ret < 0){
return -1;
}
}
return 0;
}
jint close_buzz(JNIEnv *env, jobject thiz)
{
LOGD("-----^_^ %s--------\n", __FUNCTION__);
if(pDevice != NULL)
{
pDevice->common.close((struct hw_device_t *)pDevice);
}
return 0;
}
/*
package com.android.lowlevel;
public class BuzzNative{
native int openDev()
native int devOn()
native int devOff()
native int closeDev()
}
*/
//构建一个映射表
static JNINativeMethod myMethods[] = {
//java方法的名字一定要和java代码中的名字保持一致
{"openDev", "()I", (void *)open_buzz},
{"devOn", "()I", (void *)buzz_on},
{"devOff", "()I", (void *)buzz_off},
{"closeDev", "()I", (void *)close_buzz},
};
//实现jni_onload
jint JNI_OnLoad(JavaVM * vm,void * reserved)
{
LOGE("--------JNI_OnLoad----------\n");
jint ret = -1;
//1,获取到dvm的环境变量对象,是一个工具集合, 有操作jni空间代码的各种方法
JNIEnv *env = NULL;
//获取到env, 并且测试当前的jni版本是否是1.4
ret = vm->GetEnv((void * * )&env, JNI_VERSION_1_4);
if(ret != JNI_OK)
{
//表示出错了
LOGE("vm->GetEnv error\n");
return -1;
}
//2,通过环境变量对象提供去注册映射表对象
//为java方法提供类名
jclass myCls = env->FindClass("com/android/lowlevel/BuzzNative");
if(myCls == NULL)
{
LOGE("env->FindClass error\n");
return -1;
}
ret = env->RegisterNatives(myCls, myMethods, sizeof(myMethods)/sizeof(myMethods[0]));
if(ret < 0)
{
LOGE("env->RegisterNatives error\n");
return -1;
}
//JNI_OnLoad正常返回
return JNI_VERSION_1_4;
}
        Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= libbuzz_jni
LOCAL_SRC_FILES:= buzz_jni.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhardware
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
$(LOCAL_PATH)/../buzz_hal
include $(BUILD_SHARED_LIBRARY)

6.arm端上层
        com.android.lowlevel.BuzzNative.java
package com.android.lowlevel;
public class BuzzNative {
static{
System.loadLibrary("buzz_jni");
}
public native int openDev();
public native int devOn();
public native int devOff();
public native int closeDev();
}

        com.android.buzz.service.BuzzManagerI.aidl

package com.android.buzz.service;
interface BuzzManagerI {
int openDev();
int devOn();
int devOff();
int closeDev();
}

        com.android.buzz.service.BuzzManagerService.java

package com.android.buzz.service;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import com.android.lowlevel.BuzzNative;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class BuzzManagerService extends Service {
public static final String BUZZ_DEVICE_ID = "fs210_1507_11_arm_buzz";
public static final String IP = "120.25.120.198";
public static final int port = 5010;
private ClientThread mClientThread;
@Override
public IBinder onBind(Intent intent) {
return BuzzManagerBinder.getInstance();
}
@Override
public void onCreate() {
super.onCreate();
mClientThread = new ClientThread(BuzzManagerBinder.getInstance(), IP, port);
mClientThread.start();
}
@Override
public void onDestroy() {
super.onDestroy();
mClientThread.stop();
}
private static class commandThread implements Runnable{
private String command;
private BuzzManagerBinder mBinder;
private OutputStream os;
public commandThread(String common,BuzzManagerBinder mBinder,OutputStream os) {
super();
this.mBinder = mBinder;
this.command = common;
this.os = os;
}
public void start(){
new Thread(this).start();
}
@Override
public void run() {
if(command!=null){
if(command.contains(":")&&command.indexOf("command")==0){
String strs[] = command.split(":");
if(strs.length==2){
try {
int ret = mBinder.openDev();
if(ret == 0){
if(strs[1].equals("on")){
mBinder.devOn();
}else if(strs[1].equals("on")){
mBinder.devOff();
}
mBinder.closeDev();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
}
}
public static class ClientThread implements Runnable{
private static final Object LOCK = new Object();
private BuzzManagerBinder mBinder;
private boolean flages = false;
private Socket mSocket;
private String ip;
private int port;
private OutputStream os;
public ClientThread(BuzzManagerBinder mBinder,String ip,int port) {
super();
this.mBinder = mBinder;
this.ip = ip;
this.port = port;
}
public void start(){
synchronized (LOCK) {
if(!flages){
flages = true;
new Thread(this).start();
}
}
}
public void stop(){
synchronized (LOCK) {
if(os!=null){
try {
os.write("close".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
flages = false;
}
}
@Override
public void run() {
try {
mSocket = new Socket(InetAddress.getByName(ip), port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if(mSocket != null){
try {
InputStream is = mSocket.getInputStream();
os = mSocket.getOutputStream();
os.write(("deviceId:"+BUZZ_DEVICE_ID).getBytes());
while (flages) {
byte[] buffer = new byte[1024*2];
int len = is.read(buffer);
String str = new String(buffer, 0, len).trim();
if("close".equals(str)){
flages = false;
}else{
new commandThread(str, mBinder, os).start();
}
}
os.close();
is.close();
if(!mSocket.isClosed()){
mSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static class BuzzManagerBinder extends BuzzManagerI.Stub{
private static BuzzManagerBinder mBinder;
private int openNumber = 0;
private int openDev=-1;
private int closeDev = 0;
private BuzzNative mBuzzNative;
public BuzzManagerBinder() {
super();
mBuzzNative = new BuzzNative();
}
public static BuzzManagerBinder getInstance(){
if(mBinder==null){
mBinder = new BuzzManagerBinder();
}
return mBinder;
}
@Override
public int openDev() throws RemoteException {
if(openNumber==0){
openDev = mBuzzNative.openDev();
}
openNumber++;
return openDev;
}
@Override
public int devOn() throws RemoteException {
if(openDev==0){
return mBuzzNative.devOn();
}
return -1;
}
@Override
public int devOff() throws RemoteException {
if(openDev==0){
return mBuzzNative.devOff();
}
return -1;
}
@Override
public int closeDev() throws RemoteException {
if(openDev==0){
openNumber--;
if(openNumber==0){
closeDev = mBuzzNative.closeDev();
}
return closeDev;
}
return -1;
}
}
}

         BootReciver.java

package com.android.buzz.service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootReciver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_BOOT_COMPLETED.equals(action)
||"com.android.buzz.SERVICE_START".equals(action)){
if(!BuzzManagerService.isLive){
Intent startServiceIntent = new Intent(context, BuzzManagerService.class);
context.startService(startServiceIntent);
}
}
}
}

         AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.buzz"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="com.android.buzz.service.BuzzManagerService"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service android:name="com.android.buzz.service.BuzzManagerService"
android:permission="com.android.buzz.service.BuzzManagerService"
android:exported="true">
<intent-filter >
<action android:name="com.android.buzz.service.BuzzManagerService"/>
</intent-filter>
</service>
<receiver android:name="com.android.buzz.service.BootReciver">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="com.android.buzz.SERVICE_START"/>
</intent-filter>
</application>
</manifest>

         Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
src/com/android/buzz/service/BuzzManagerI.aidl
LOCAL_PACKAGE_NAME := BuzzService
LOCAL_CERTIFICATE := platform
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
7.二维码处理
        ZxingUtil.java
package com.android.zxing;
import java.io.FileNotFoundException;
import java.util.Hashtable;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
public class ZxingUtil {
public static String getStringFromBitmap(Bitmap bitmap){
Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
RGBLuminanceSource mLuminanceSource = new RGBLuminanceSource(bitmap);
Binarizer binarizer = new HybridBinarizer(mLuminanceSource);
BinaryBitmap mBinaryBitmap = new BinaryBitmap(binarizer);
QRCodeReader mCodeReader = new QRCodeReader();
try {
Result r= mCodeReader.decode(mBinaryBitmap, hints);
return r.getText();
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ChecksumException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static Bitmap getBitmapFromString(BitmapDrawable bitmapDrawable,String string,int wh){
if(wh<10){
throw new IllegalArgumentException("ͼƬ̫С");
}
Bitmap bitmap = Bitmap.createBitmap(wh, wh, Bitmap.Config.ARGB_8888);
if(bitmapDrawable!=null){
bitmapDrawable.setBounds(0, 0, wh, wh);
Canvas mCanvas = new Canvas(bitmap);
bitmapDrawable.draw(mCanvas);
}
// QRCodeWriter mCodeWriter = new QRCodeWriter();
MultiFormatWriter mCodeWriter = new MultiFormatWriter();
try {
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
BitMatrix mBitMatrix = mCodeWriter.encode(string, BarcodeFormat.QR_CODE, wh, wh,hints);
int[] pixels = new int[wh * wh];
bitmap.getPixels(pixels, 0, wh, 0, 0, wh, wh);
for (int y = 0; y < wh; y++) {
for (int x = 0; x < wh; x++) {
if (mBitMatrix.get(x, y)) {
pixels[y * wh + x] = 0xdd222222&pixels[y * wh + x];
} else {
pixels[y * wh + x] = 0x88ffffff&pixels[y * wh + x];
}
}
}
bitmap.setPixels(pixels, 0, wh, 0, 0, wh, wh);
} catch (WriterException e) {
e.printStackTrace();
}
return bitmap;
}
public static class RGBLuminanceSource extends LuminanceSource {
private final byte[] luminances;
public RGBLuminanceSource(String path) throws FileNotFoundException {
this(loadBitmap(path));
}
public RGBLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
// In order to measure pure decoding speed, we convert the entire image
// to a greyscale array
// up front, which is the same as the Y channel of the
// YUVLuminanceSource in the real app.
luminances = new byte[width * height];
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
int pixel = pixels[offset + x];
int r = (pixel >> 16) & 0xff;
int g = (pixel >> 8) & 0xff;
int b = pixel & 0xff;
if (r == g && g == b) {
// Image is already greyscale, so pick any channel.
luminances[offset + x] = (byte) r;
} else {
// Calculate luminance cheaply, favoring green.
luminances[offset + x] = (byte) ((r + g + g + b) >> 2);
}
}
}
}
@Override
public byte[] getRow(int y, byte[] row) {
if (y < 0 || y >= getHeight()) {
throw new IllegalArgumentException(
"Requested row is outside the image: " + y);
}
int width = getWidth();
if (row == null || row.length < width) {
row = new byte[width];
}
System.arraycopy(luminances, y * width, row, 0, width);
return row;
}
// Since this class does not support cropping, the underlying byte array
// already contains
// exactly what the caller is asking for, so give it to them without a copy.
@Override
public byte[] getMatrix() {
return luminances;
}
}
private static Bitmap loadBitmap(String path) throws FileNotFoundException {
Bitmap bitmap = BitmapFactory.decodeFile(path);
if (bitmap == null) {
throw new FileNotFoundException("Couldn't open " + path);
}
return bitmap;
}
}

8.手机APP
        MainActivity.java
package com.buzzapp;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Hashtable;
import com.android.buzz.R;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
public static final String BUZZ_DEVICE_ID_ON = "fs210_1507_11_arm_buzz:on";
public static final String BUZZ_DEVICE_ID_OFF = "fs210_1507_11_arm_buzz:off";
public static final String IP = "120.25.120.198";
private static final int port = 5010;
public Bitmap getBitmapFromString(String string,int len){
Bitmap bitmap = Bitmap.createBitmap(len, len, Bitmap.Config.ARGB_8888);
int[] pixels = new int[len*len];
MultiFormatWriter qrCodeWriter = new MultiFormatWriter();
try {
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
BitMatrix mBitMatrix = qrCodeWriter.encode(string, BarcodeFormat.QR_CODE, len, len,hints);
for(int y=0;y<len;y++){
for(int x=0;x<len;x++){
if(mBitMatrix.get(x, y)){
pixels[y*len+x] = 0xff000000;
}else{
pixels[y*len+x] = 0xffffffff;
}
}
}
bitmap.setPixels(pixels, 0, len, 0, 0, len, len);
} catch (WriterException e) {
e.printStackTrace();
}
return bitmap;
}
public class SendMsgThread implements Runnable{
private String msg;
public SendMsgThread(String msg) {
super();
this.msg = msg;
}
public void start(){
new Thread(this).start();
}
@Override
public void run() {
try {
Socket mSocket = new Socket(InetAddress.getByName(IP), port);
OutputStream os = mSocket.getOutputStream();
os.write(msg.getBytes());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
os.write("close".getBytes());
os.flush();
os.close();
mSocket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private TextView msg;
private Button scan,buzz,unbuzz;
private ImageView image;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msg = (TextView) findViewById(R.id.textView1);
scan = (Button) findViewById(R.id.button_scan);
scan.setOnClickListener(this);
buzz = (Button) findViewById(R.id.button_buzz);
buzz.setOnClickListener(this);
unbuzz = (Button) findViewById(R.id.button_unbuzz);
unbuzz.setOnClickListener(this);
image = (ImageView) findViewById(R.id.image);
image.setVisibility(View.GONE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case SCAN_REQUEST_CODE:
if(resultCode == RESULT_OK){
String str = data.getStringExtra("result");
msg.setText(str);
new SendMsgThread(str.trim()).start();
}else{
msg.setText("扫描失败");
}
break;
default:
break;
}
}
public static final int SCAN_REQUEST_CODE = 0x1001;
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.button_scan:
Intent intent = new Intent("com.android.SCAN_ACTION");
intent.setClassName("com.ericssonlabs", "com.zxing.activity.CaptureActivity");
startActivityForResult(intent, SCAN_REQUEST_CODE); break;
case R.id.button_buzz:
image.setImageBitmap(getBitmapFromString(BUZZ_DEVICE_ID_ON, 300));
image.setVisibility(View.VISIBLE);
break;
case R.id.button_unbuzz:
image.setImageBitmap(getBitmapFromString(BUZZ_DEVICE_ID_OFF, 300));
image.setVisibility(View.VISIBLE);
break;
default:
break;
}
}
}

        Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
src/com/android/buzz/service/BuzzManagerI.aidl
LOCAL_PACKAGE_NAME := BuzzAPP
LOCAL_CERTIFICATE := platform
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
# Added for source code compile start 为jar起一个别名
LOCAL_STATIC_JAVA_LIBRARIES := \
jarlibzxing \
jarlibv4
include $(BUILD_PACKAGE)
# Added for source code compile start 冒号前面为jar别名,后面为jar文件的实际路径
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
jarlibzxing:libs/zxing.jar \
jarlibv4:libs/android-support-v4.jar
include $(BUILD_MULTI_PREBUILT)
include $(call all-makefiles-under,$(LOCAL_PATH))

9.云服务器端
        ClouceBuzzService.java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ClouceBuzzService implements Runnable {
public static final String DEVICE_ID_STRING = "deviceId";
public static String getValue(String str) {
if (str.contains(":")) {
String[] array = str.split(":");
if (array.length == 2) {
return array[1];
}
}
return null;
}
public static String getKey(String str) {
if (str.contains(":")) {
String[] array = str.split(":");
if (array.length == 2) {
return array[0];
}
}
return null;
}
/**
* @param args
*/
public static void main(String[] args) {
ClouceBuzzService mClouceBuzzService = new ClouceBuzzService();
mClouceBuzzService.start();
}
private ServerSocket mServerSocket;
private static final int port = 5010;
private boolean flage = false;
private static List<ClientBuzz> clients = new ArrayList<ClientBuzz>();
public List<ClientBuzz> getClients() {
return clients;
}
public void removeClient(ClientBuzz item) {
if (clients.contains(item)) {
clients.remove(item);
}
}
public void run() {
try {
mServerSocket = new ServerSocket(port);
System.out.println("ServerSocket start !!!!!");
while (flage) {
try {
Socket mSocket = mServerSocket.accept();
String ip = mSocket.getInetAddress().getHostAddress();
int port = mSocket.getPort();
ClientBuzz mClientBuzz = new ClientBuzz(mSocket, this);
clients.add(mClientBuzz);
mClientBuzz.start();
System.out.println("---mServerSocket.accept() ip:" + ip
+ " port:" + port);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() {
if (!flage) {
flage = true;
System.out.println("service start !!!!!");
new Thread(this).start();
}
}
public void stop() {
try {
flage = false;
mServerSocket.close();
System.out.println("service stop !!!!!");
} catch (IOException e) {
e.printStackTrace();
}
}
public static class ClientBuzz implements Runnable {
private Socket mSocket;
private ClouceBuzzService mBuzzService;
private String ip;
private int port;
private OutputStream os;
private InputStream is;
private boolean flage = false;
private String device_id = null;
public ClientBuzz(Socket mSocket, ClouceBuzzService mBuzzService) {
super();
this.mSocket = mSocket;
this.mBuzzService = mBuzzService;
ip = mSocket.getInetAddress().getHostAddress();
port = mSocket.getPort();
try {
os = mSocket.getOutputStream();
is = mSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
public void commond(String str) {
String key = getKey(str);
if (device_id != null && key != null && key.equals(device_id)) {
String value = getValue(str);
if (value.equals("on") || value.equals("off")) {
try {
os.write(("commond:" + value).getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void doMsg(String msg) {
// os.write(("deviceId:"+BUZZ_DEVICE_ID).getBytes());
if (msg != null) {
String key = getKey(msg);
if (key != null) {
if (key.equals(DEVICE_ID_STRING)) {
device_id = getValue(msg);
System.out.println("ip:" + ip + "\nport:" + port
+ "\ndevice_id:" + device_id);
} else if (msg.equals("close")) {
flage = false;
} else {
for (ClientBuzz item : mBuzzService.getClients()) {
item.commond(msg);
}
}
}
}
}
public void run() {
while (flage) {
byte[] buffer = new byte[1024 * 2];
try {
int len = is.read(buffer);
if (len <= 0) {
// 客户端断开
flage = false;
} else {
String str = new String(buffer, 0, len).trim();
if (str.equals("close")) {
flage = false;
} else {
doMsg(str);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
mBuzzService.removeClient(this);
}
public void start() {
flage = true;
}
public void stop() {
try {
flage = false;
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMsg(String string) {
if (os != null) {
try {
os.write(string.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

        build.sh
#!/bin/sh
if [ "$1" = "clean" ]
then
rm *.class *.jar
else
javac *.java
jar cvf buzz_icloud.jar *.class
rm *.class
java -classpath buzz_icloud.jar ClouceBuzzService
fi



开发板这端:
FS210 # set bootcmd tftp 0x40008000 uImage \; bootm 0x40008000
FS210 # set serverip 192.168.7.121
FS210 # set ethaddr 192.168.7.191
FS210 # set ethaddr 00:23:32:23:32:11
FS210 # set bootargs console=ttySAC0,115200 root=/dev/nfs nfsroot=192.168.7.121:/opt/rootfs_dir ip=192.168.7.191 init=/init
FS210 # save
阅读更多
个人分类: android 驱动 jni
上一篇JNI调用串口
下一篇ESP8266
想对作者说点什么? 我来说一句

点亮一个led 灯的实验

2015年10月08日 1.81MB 下载

android gps architecture

2011年10月23日 49KB 下载

没有更多推荐了,返回首页

关闭
关闭