android驱动例子(LED灯控制)

--作者:赖玉平(Peter Lai)aulyp@163.com

      本例子,讲述在android2.1上完全自已开发一个驱动去控制硬件口并写应用测试该驱动,通过这样一个例子,解析android下的驱动开发流程的应用调用流程,可以说是很好的入门引导

要达到的效果:通过android的应用,调用驱动程序,在开发板上控制4个LED的亮灭。

一、硬件原理

clip_image001

如上图,通过4个IO口控制这LED,低电平LED亮,

这4个IO口分别是GPM1, GPM2, GPM3, GPM4,

二、驱动程序

1、在kernel文件夹下的driver目录,新键驱动文件夹

# cd kernel_android_2.6.28.6/drivers

进到开发板的kernel目录,建驱动文件夹

#mkdir ledtest

2、在/driver/ledtest目录下,新建leddriver.c ,leddriver.h , Kconfig, Makefile 等4个文件

leddriver.c

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/init.h>            /* For __init/__exit/... */
#include <linux/module.h>
#include <mach/hardware.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-clock.h>
#include <plat/regs-lcd.h>
#include <plat/regs-gpio.h>
#include <mach/map.h>
#include <linux/gpio.h>
#include <plat/gpio-bank-m.h>
#include <linux/cdev.h>
#include <linux/fs.h> //for register_chrdev()
#include <linux/device.h>
#include <mach/map.h>
#include "leddriver.h"
#include <linux/miscdevice.h>        /* For MODULE_ALIAS_MISCDEV
                            (WATCHDOG_MINOR) */
#include <linux/watchdog.h>        /* For the watchdog specific items */
#include <linux/fs.h>            /* For file operations */
#define Viberator_MAJOR        97  //主设备号
#define SCULL_NR_DEVS           4
#define SCULL_QUANTUM         4000
#define SCULL_QSET             1000
//---do as the GIO driver
#define DEVCOUNT                4
#define GIO_MINOR            2    /* GIO minor no. */
static dev_t dev;        //申  请  到的主  设备  号
static struct cdev *cdev_p;
static int openCnt;
//--全局变量------------
int VIB_major  = 97;//we asigment it for test
int VIB_minor = 0;
int VIB_nr_devs = SCULL_NR_DEVS;
int VIB_quantum = SCULL_QUANTUM;
int VIB_qset = SCULL_QSET;

static struct class *vib_dev_class;
#define GPNCON  S3C64XX_GPNCON 
#define GPNDAT  S3C64XX_GPNDAT
#define GPNPUD  S3C64XX_GPNPUD
#define GPMCON S3C64XX_GPMCON
#define GPMDAT  S3C64XX_GPMDAT
#define GPMPUD S3C64XX_GPMPUD

#define VIB_ON 0x11
#define  VIB_OFF 0x22
static const struct file_operations GPIO_Viberator_ctl_ops={
    .owner        = THIS_MODULE,
    .open    = GPIO_VIB_open,
    .read    =GPIO_VIB_read,
    .write    =GPIO_VIB_write,
    .ioctl     = GPIO_VIB_ioctl,
    .release     =GPIO_VIB_release,
};
ssize_t GPIO_VIB_read(struct file * file,char * buf,size_t count,loff_t * f_ops)
{
       char sdas[5]={1,3,8,1,6};
       ssize_t            status = 5;
    unsigned long    missing;
    missing = copy_to_user(buf, sdas, status);
    if (missing == status)
        status = -EFAULT;
    else
        status = status - missing;   
       printk(" GPIO_VIB_read = %d ,count = %d/r/n",status,count);
    gpio_direction_output(S3C64XX_GPM(3), 0);// 
return status ; 
}
ssize_t GPIO_VIB_write (struct file * file,const char * buf, size_t count,loff_t * f_ops)
{
    unsigned long missing;
     char inbuffer[512]={0};
    int i;
     missing = copy_from_user(inbuffer, buf, count);
    printk(" GPIO_VIB_write count = %d missing =%d /r/n",count,missing);
    gpio_direction_output(S3C64XX_GPM(3), 1);// 
    for(i=0;i<count;i++)
        {
            printk("Write:inbuffer[%d]=%d /r/n",i,inbuffer[i]);
        } 
return count;
}

//ssize_t GPIO_VIB_ioctl(struct inode *  inode,struct file * file,unsigned int cmd, long data)
static int GPIO_VIB_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
    printk(KERN_ERR"VIB:GPIO_VIB_ioctl --CMD=%x /n",cmd);
    switch(cmd)
        {
           case VIB_ON:
            gpio_direction_output(S3C64XX_GPM(1), 0);// 
            gpio_direction_output(S3C64XX_GPM(2), 0);// 
            gpio_direction_output(S3C64XX_GPM(3), 0);// 
            gpio_direction_output(S3C64XX_GPM(4), 1);// 
            printk(KERN_ERR"VIB:GPIO_VIB_ioctl --VIB_ON/n");
            break;
         case VIB_OFF:
            {
            printk(KERN_ERR"VIB:GPIO_VIB_ioctl --VIB_OFF/n");
            gpio_direction_output(S3C64XX_GPM(1), 1);// 
            gpio_direction_output(S3C64XX_GPM(2), 1);// 
            gpio_direction_output(S3C64XX_GPM(3), 1);// 
            gpio_direction_output(S3C64XX_GPM(4), 0);// 
            break;
         }
         default:break;
                
    }
        //gpio_free(S3C64XX_GPN(7));
}
ssize_t GPIO_VIB_open(struct inode * inode,struct file * file)
{
//模块数
  //MOD_INC_USE_COUNT;
  printk("GPIO_VIB_open() /n");   
  return 0;
}
ssize_t GPIO_VIB_release(struct inode * inode, struct file * file)
{
   // MOD_DEC_USE_COUNT;//模块数减1
     printk("GPIO_VIB_release() /n");   
    return 0;
}
static int GPIO_VIB_CTL_init(void)
{
    int ret  = -ENODEV;
   int error ;
    printk("---------------------------------------------- /r/n");
    //初始化端口
        s3c_gpio_cfgpin(S3C64XX_GPM(1), S3C_GPIO_SFN(1));//GPM1 output
        s3c_gpio_cfgpin(S3C64XX_GPM(2), S3C_GPIO_SFN(1));//GPM2 output
        s3c_gpio_cfgpin(S3C64XX_GPM(3), S3C_GPIO_SFN(1));//GPM3 output
        s3c_gpio_cfgpin(S3C64XX_GPM(4), S3C_GPIO_SFN(1));//GPM4 output
#if 1 /*静态方式注册驱动*/
ret = register_chrdev(Viberator_MAJOR, "viberator", &GPIO_Viberator_ctl_ops);
if (ret < 0) {
    printk(KERN_ERR "VIB: unable to get major %d/n", ret);
    return ret;
}
//创建class
vib_dev_class = class_create(THIS_MODULE, "viberator");
if (IS_ERR(vib_dev_class)) {
    unregister_chrdev(Viberator_MAJOR, "capi20");
    return PTR_ERR(vib_dev_class);
}
//创建节点,
device_create(vib_dev_class, NULL, MKDEV(Viberator_MAJOR, 0), NULL, "vib");
// create a point under /dev/class/vib  
//通过上面这两步,驱动加载后,就会在/dev/class/下面生成vib节点,应用程序可以像操作文件那样操作这个节点,通过open ,write,read 等函数操作,详情可以看后面的应用示例程序。
  return 0;    
#endif
#if 0/* 注册动态 */
    if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "vibrate")) < 0)
        {
        printk(KERN_ERR
               "VIB: Couldn't alloc_chrdev_region, error=%d/n",
               error);
        return 1;
    }
         printk("dev = %d  /n",dev);
    cdev_p = cdev_alloc();
    cdev_p->ops = &GPIO_Viberator_ctl_ops;
    error = cdev_add(cdev_p, dev, DEVCOUNT);
    if (error) {
        printk(KERN_ERR
               "VIB: Couldn't cdev_add, error=%d/n", error);
        return 1;
    }

    vib_dev_class = class_create(THIS_MODULE, "vib-dev");
    if (IS_ERR(vib_dev_class)) {
        res = PTR_ERR(vib_dev_class);
        goto out_unreg_class;
    }
    return 0;
#endif
out_unreg_class:
    class_destroy(vib_dev_class);
return 1;
}

static int __init S3C6410_VIB_init(void)
{
    int ret = -ENODEV;
    //调用函数    
        printk(KERN_ERR "Auly: S3C6410_VIB_init---/n");
    ret = GPIO_VIB_CTL_init();
    if(ret)
        {
        printk(KERN_ERR "Auly: S3C6410_VIB_init--Fail !!!/n");
        return ret;
    }
    return 0;
}
static void __exit cleanup_GPIO_VIB(void)
{
    //注销设备
  //  devfs_unregister_chrdev(Viberator_MAJOR,"gpio_vib_ctl");
 #if 0 
      cdev_del(cdev_p);
    unregister_chrdev_region(dev, DEVCOUNT);
    class_destroy(vib_dev_class);
#endif 
device_destroy(vib_dev_class, MKDEV(Viberator_MAJOR, 0));
class_destroy(vib_dev_class);
unregister_chrdev(Viberator_MAJOR, "viberator");
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Peter first driver");
MODULE_ALIAS_CHARDEV(Viberator_MAJOR, 0);

module_init(S3C6410_VIB_init);
module_exit(cleanup_GPIO_VIB);

leddriver.h文件

leddriver.h文件
  1. ssize_t GPIO_VIB_read(struct file * file,char * buf,size_t count,loff_t * f_ops);
  2. ssize_t GPIO_VIB_write (struct file * file,constchar * buf, size_t count,loff_t * f_ops);
  3. static int GPIO_VIB_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
  4. ssize_t GPIO_VIB_open(struct inode * inode,struct file * file);
  5. ssize_t GPIO_VIB_release(struct inode * inode,struct file * file);
  6. static int GPIO_VIB_CTL_init(void);

Kconfig 文件

Kconfig 文件
  1. config LEDTEST
  2.   tristate "LED test for ARMeasy"
  3.   default n
  4.   help
  5.   this is a LED driver for ARMEASY with S3C6410

Makefile文件

Makefile文件
  1. obj-$(CONFIG_LEDTEST)+=leddriver.o

3、在内核配置里菜单里加入本驱动的配置项

达到的效果是,可以通过内核配置来选择是否把本驱动编译进内核里,也就是出现在make menuconfig 后出来的界面里,可以参考9.8章<android添加新驱动方法>

1)在arch/arm/Kconfig文件里 menu "Device Drivers"与 endmenu之间添加

  1. source "drivers/ledtest/Kconfig"

2)在drivers/Kconfig menu "Device Drivers" 和 endmenu之间添加

  1. source "drivers/ledtest/Kconfig"

3)修改/drivers/Makefile文件

  1. Obj-$(CONFIG_LEDTEST) +=ledtest/

4、编译驱动

在kernel目录下,终端输入

  1. #make menuconfig

“Device Drivers” 下面会看到 “LED test for ARMeasy”,选择它,

保存并退出

  1. #make

这样,就会在/drivers/ledtest目录下得到leddrivr.ko文件,它就是驱动目标文件,已级编译进了zImage 里了,只要用这个kernel烧录到开发板,开机就会自动加载本驱动,

PS,如果发现如上编译,没有在ledtest目录下生成leddriver.ko文件,也就是本根没有去编译本驱动,那就把ledtest目录入到/drivers/misc目录下,相应的修改misc下面,然后,在makefile里,不用选直接写成obj-y += leddriver.o,这样强制的包含进去编译。

三、 应用程序(测试驱动)

用C语言写一个应用,测试上面写的驱动是否工作正常,这是一般的驱动开发流程

主要有两个文件:Android.mk和ledtest.c

1、

在$(YOUR_ANDROID)/external/LEDTEST/目录编写ledtest.c文件,

ledtest.c

ledtest.c
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>// contact the open(),close(),read(),write() and so on!
  4.   #define DEVICE_NAME"/dev/vib"//device point
  5. #define LED_ON     0x11
  6. #define LED_OFF     0x22
  7. int main(int argc,char **argv)
  8. {   
  9.     int fd;
  10.     int ret;
  11.     char *i;
  12.     printf("\n start gpio_led_driver test \r\n");
  13.     fd = open(DEVICE_NAME,O_RDWR);//Open device ,get the handle
  14.     printf("fd = %d \n",fd);
  15.     if(fd == -1) //open fail
  16.     {
  17.       printf("open device %s error \n",DEVICE_NAME);
  18.     }
  19.     else
  20.     {
  21.         while(1)
  22.         {
  23.           ioctl(fd,LED_OFF); //call the output function to off LEDs
  24.           sleep(1);//wait 1 second
  25.           ioctl(fd,LED_ON);
  26.           sleep(1);
  27.         }
  28.         ret = close(fd); //close device
  29.         printf("ret = %d \n",ret);
  30.         printf("close gpio_led test \n");
  31.     }
  32.   return 0;
  33. }

2、在$(YOUR_ANDROID)/external/ LEDTEST /目录编写Android.mk文件。这是Android Makefile的标准命名,不要更改。Android.mk文件的格式和内容可以参考其他已有的Android.mk文件的写法,针对helloworld程序的Android.mk文件内容如下:

Android.mk
  1.  
  2. LOCAL_PATH:= $(call my-dir)
  3. include $(CLEAR_VARS)
  4. LOCAL_SRC_FILES:= \/par     hello.c
  5. LOCAL_MODULE := ledtestapp
  6. include $(BUILD_EXECUTABLE)

注意上面LOCAL_SRC_FILES用来指定源文件;

LOCAL_MODULE指定要编译的模块的名字,下一步骤编译时就要用到;

include $(BUILD_EXECUTABLE)表示要编译成一个可执行文件,如果想编译成动态库则可用BUILD_SHARED_LIBRARY,这些可以在

$(YOUR_ANDROID)/build/core/config.mk查到。

3、 回到Android源代码顶层目录进行编译:

# cd $(YOUR_ANDROID) && make ledtestapp

例如我这里的实际操作是

#cd android2.1
#make ledtestapp

注意make ledtestapp中的目标名ledtestapp就是上面Android.mk文件中由LOCAL_MODULE指定的模块名。编译结果如下

make ledtestapp
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.1-update1
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=ECLAIR
============================================
/bin/bash: line 0: cd: sdk/layoutopt/app/src/resources: No such file or directory
target thumb C: ledtestapp <= external/LEDTEST/ledtest.c
Install: out/host/linux-x86/bin/apriori
Install: out/host/linux-x86/bin/soslim
target Executable: ledtestapp (out/target/product/generic/obj/EXECUTABLES/ledtestapp_intermediates/LINKED/ledtestapp)
target Non-prelinked: ledtestapp (out/target/product/generic/symbols/system/bin/ledtestapp)
target Strip: ledtestapp (out/target/product/generic/obj/EXECUTABLES/ledtestapp_intermediates/ledtestapp)
Install: out/target/product/generic/system/lib/libdl.so
Install: out/target/product/generic/system/lib/libc.so
Install: out/target/product/generic/system/lib/libstdc++.so
Install: out/target/product/generic/system/lib/libm.so
Install: out/target/product/generic/system/bin/ledtestapp

4、如上面的编译结果所示,编译后的可执行文件存放在

out/target/product/generic/system/bin/目录 可执行文件是ledtestapp

5、拷贝ledtestapp可执行文件到T卡,插入开发板

6、开电,在启动进入android的过程中,串口终端 按回车,进入命令行模式

7、拷贝可执行文件到根目录

#cp /sdcard/ledtestapp /   

8、执行程序

#./ledtestapp

通过上面的步骤,可以看到开发板上相应的LED在闭,每秒钟闪一次!


  推荐使用 著名开源项目:树莓派3 卡片电脑,我个人觉得挺不错的,也非常的便宜,

 介绍看这里

 http://www.superpi.org/chanpin/superpi3/superpi3.htm


csdn签名

 

 

后语:近来老发现有网站盗用我的博客文章,又不注明出处,很不尊重我的劳动果实,所以设计了以上签名,做成图片,望理解!


  • 4
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Android开发案例驱动教程》 配套代码。 注: 由于第12,13,14章代码太大,无法上传到一个包中。 这三节代码会放到其他压缩包中。 作者:关东升,赵志荣 Java或C++程序员转变成为Android程序员 采用案例驱动模式展开讲解知识点,即介绍案例->案例涉及技术->展开知识点->总结的方式 本书作者从事多年一线开发和培训,讲解知识点力求细致,深入浅出 目 录 前言 第1章 Android操作系统概述 1 1.1 Android历史介绍 1 1.2 Android架构 1 1.3 Android平台介绍 2 1.4 现有智能手机操作系统比较 4 第2章 Android开发环境搭建 5 2.1 Eclipse和ADT插件 5 2.1.1 Eclipse安装 5 2.1.2 ADT插件 6 2.2 Android SDK 8 2.2.1 Android SDK的获得 8 2.2.2 Android SDK版本说明 10 2.2.3 ADT配置 10 2.3 Android开发模拟器 11 2.3.1 创建模拟器 11 2.3.2 启动模拟器 13 2.3.3 键盘映射与模拟器控制 13 2.3.4 横屏与竖屏切换 14 第3章 第一个Android程序 15 3.1 HelloAndroid 15 3.1.1 在Eclipse中创建项目 15 3.1.2 编写程序项目代码 17 3.1.3 运行HelloAndroid 18 3.1.4 Android工程目录 19 3.1.5 AndroidManifest.xml文件 21 3.2 Android中的组件介绍 22 3.3 使用Android SDK帮助 23 3.3.1 Android SDK API文档 23 3.3.2 Android SDK开发指南 24 3.3.3 Android SDK samples 24 3.4 使用DDMS帮助调试程序 26 3.4.1 启动DDMS 26 3.4.2 Device 28 3.4.3 Emulator Control 29 3.4.4 File Explorer 30 3.4.5 LogCat 31 3.5 使用ADB帮助调试程序 33 3.5.1 查询模拟器实例和设备 34 3.5.2 进入shell 34 3.5.3 导入导出文件 35 3.6 应用程序的打包、安装和卸载 37 3.6.1 应用程序打包 37 3.6.2 应用程序安装 40 3.6.3 应用程序卸载 40 本章小结 42 第4章 UI基础知识 43 4.1 Android UI组件概述 43 4.1.1 View 43 4.1.2 ViewGroup 44 4.1.3 布局管理器 44 4.2 UI设计工具 44 4.2.1 DroidDraw工具 44 4.2.2 ADT插件UI设计工具 46 4.3 事件处理模型 47 4.3.1 接口实现事件处理模型 47 4.3.2 内部类事件处理模型 49 4.3.3 匿名内部类事件处理模型 51 4.4 Activity中的常用事件 53 4.4.1 触摸事件 53 4.4.2 键盘事件 55 4.5 菜单 57 4.5.1 文本菜单 57 4.5.2 图片文本菜单 59 本章小结 60 第5章 UI基础控件 61 5.1 按钮 61 5.1.1 Button 62 5.1.2 ImageButton 63 5.1.3 ToggleButton 64 5.2 TextView 64 5.3 EditText 65 5.4 RadioButton和RadioGroup 66 5.4.1 RadioButton 66 5.4.2 RadioGroup 67 5.5 CheckBox 68 5.6 ImageView 70 5.7 Progress Bar 70 5.7.1 条状进度条 71 5.7.2 圆形进度条 73 5.7.3 对话框进度条 74 5.7.4 标题栏中进度条 75 5.8 SeekBar 76 5.9 RatingBar 78 本章小结 82 第6章 UI高级控件 83 6.1 列表类控件 83 6.1.1 Adapter概念 83 6.1.2 AutoComplete 84 6.1.3 Spinner 87 6.1.4 ListView 90 6.1.5 GridView 96 6.1.6 Gallery 99 6.2 Toast 103 6.2.1 文本类型 103 6.2.2 图片类型 104 6.2.3 复合类型 105 6.2.4 自定义显示位置Toast 106 6.3 对话框 107 6.3.1 文本信息对话框 107 6.3.2 简单列表项对话框 109 6.3.3 单选项列表项对话框 111 6.3.4 复选框列表项对话框 113 6.3.5 复杂布局列表项对话框 115 6.4 Android国际化和本地化 118 本章小结 121 第7章 UI布局 122 7.1 FrameLayout 122 7.1.1 TextSwitcher 124 7.1.2 ImageSwitcher 126 7.1.3 DatePicker 129 7.1.4 TimePicker 131 7.1.5 ScrollView 133 7.1.6 选项卡 134 7.2 LinearLayout 138 7.3 RelativeLayout 139 7.4 AbsoluteLayout 141 7.5 TableLayout 143 7.6 布局嵌套 146 7.7 屏幕旋转 152 本章小结 154 第8章 多线程 155 8.1 多线程案例--计时器 155 8.2 线程概念 156 8.2.1 进程概念 156 8.2.2 线程概念 156 8.3 Java中的线程 157 8.3.1 Java中的实现线程体方式1 157 8.3.2 Java中的实现线程体方式2 160 8.3.3 Java中的实现线程体方式3 162 8.4 Android中的线程 163 8.4.1 Android线程应用中的问题与分析 164 8.4.2 Message和MessageQueue 169 8.4.3 Handler 169 8.4.4 Looper和HandlerThread 172 本章小结 178 第9章 Activity和Intent 179 9.1 Activity 179 9.1.1 创建Activity 179 9.1.2 Activity生命周期 180 9.2 Intent 183 9.2.1 显式Intent 184 9.2.2 隐式Intent 186 9.2.3 匹配组件 186 9.3 多Activity之间跳转 188 9.3.1 多个Activity之间数据传递 189 9.3.2 跳转与返回 192 9.3.3 任务与标志 196 9.4 Android系统内置Intent 199 本章小结 201 第10章 数据存储 203 10.1 健康助手案例 203 10.2 Android数据存储概述 205 10.3 本地文件 205 10.3.1 访问SD卡 207 10.3.2 访问应用文件目录 212 10.4 SQLite数据库 216 10.4.1 SQLite数据类型 216 10.4.2 Android平台下管理SQLite数据库 216 10.5 编写访问SQLite数据库组件 220 10.5.1 DBHelper类 220 10.5.2 数据插入 222 10.5.3 数据删除 224 10.5.4 数据修改 224 10.5.5 数据查询 227 10.6 案例重构 229 10.6.1 系统架构设计 229 10.6.2 重构数据访问层 230 10.7 为案例增加参数设置功能 238 10.7.1 Shared Preferences 240 10.7.2 Preferences控件介绍 243 10.7.3 使用Preferences控件的案例 248 本章小结 250 第11章 Content Provider 251 11.1 Content Provider概述 251 11.2 Content URI 252 11.2.1 Content URI含义 252 11.2.2 内置的Content URI 253 11.3 通过Content Provider访问联系人 253 11.3.1 查询联系人 255 11.3.2 通过联系人ID查询联系人的Email 258 11.3.3 按照过滤条件查询Email 259 11.3.4 查询联系人的电话 261 11.4 通过Content Provider访问通话记录 262 11.4.1 查询通话记录 262 11.4.2 按照过滤条件查询通话记录 264 11.5 通过Content Provider访问短信 266 11.6 自定义Content Provider实现数据访问 269 11.6.1 编写Content Provider 269 11.6.2 在不同的应用中调用Content Provider 277 11.6.3 重构Content Provider调用 278 本章小结 281 第12章 多媒体 282 12.1 多媒体文件介绍 282 12.1.1 音频多媒体文件介绍 282 12.1.2 视频多媒体文件介绍 283 12.2 Android音频播放 284 12.2.1 Android音频/视频播放状态 284 12.2.2 音频播放案例介绍 286 12.2.3 资源音频文件播放 287 12.2.4 本地音频文件播放 291 12.2.5 网络音频文件播放 292 12.2.6 完善案例其他功能 293 12.3 Android音频录制 303 12.3.1 Android音频/视频录制状态 303 12.3.2 音频录制案例介绍 303 12.3.3 音频录制案例实现 305 12.4 Android视频播放 309 12.4.1 视频播放案例 309 12.4.2 采用MediaPlayer类播放视频 310 12.4.3 使用VideoView控件重构案例 315 本章小结 316 第13章 Service 317 13.1 Service概述 317 13.1.1 本地Service生命周期 317 13.1.2 远程Service生命周期 318 13.2 本地Service 319 13.2.1 本地Service案例 319 13.2.2 编写AudioService 320 13.2.3 调用Service 322 13.2.4 重构案例 323 13.3 远程Service 325 13.3.1 远程Service调用原理 325 13.3.2 远程Service案例 326 13.3.3 设计AIDL文件 327 13.3.4 编写AudioService 331 13.3.5 调用远程Service 336 13.3.6 组件间参数传递 343 本章小结 347 第14章 Broadcast Receiver和Notification 348 14.1 Broadcast Receiver 348 14.1.1 音频播放案例 349 14.1.2 编写音频播放Broadcast Receiver 350 14.1.3 注册音频播放Broadcast Receiver 351 14.1.4 接收系统的广播 353 14.1.5 MP3下载服务案例 353 14.2 Notification 358 14.2.1 完善MP3下载服务案例 358 14.2.2 完善音频播放案例 363 14.2.3 其他形式的Notification 369 本章小结 371 第15章 云端应用 372 15.1 典型云端应用--城市天气信息服务 372 15.2 网络通信技术与实现 374 15.2.1 网络通信技术介绍 376 15.2.2 Java URL类实现方式 377 15.2.3 Apache HttpClient实现方式 378 15.3 数据交换格式 380 15.3.1 纯文本格式 381 15.3.2 XML格式 381 15.3.3 JSON格式 385 15.4 自定义服务器端程序实例 387 15.4.1 Java Servlet概述 387 15.4.2 编写城市信息服务的Servlet 388 15.4.3 编写城市天气服务的Servlet 393 15.4.4 再次探讨HttpClient的POST请求 395 15.5 云端应用案例优化 400 本章小结 404 第16章 Google Map和定位服务 405 16.1 MyMap服务系统案例 405 16.2 Android Google Map 406 16.2.1 申请Google Map Android API Key 407 16.2.2 编写Android Google Map骨架程序 409 16.2.3 控制地图 412 16.2.4 地图的显示模式 416 16.2.5 地图的图层 419 16.2.6 查询与定位 422 16.3 Android定位服务 430 16.3.1 开启定位服务 431 16.3.2 模拟测试 433 16.3.3 GPS与Google Map结合 435 16.4 案例重构 437 16.4.1 重构"定位查询"方法 438 16.4.2 重构"查询周围"方法 440 本章小结 443 第17章 Android通信应用 444 17.1 电话应用开发 444 17.1.1 拨打电话功能 444 17.1.2 呼入电话状态 446 17.2 短信和彩信应用开发 450 17.2.1 Android内置的发送短信/彩信功能 450 17.2.2 自己编写发送文本内容的短信 452 17.2.3 自己编写接收文本内容的短信 458 17.2.4 自己编写发送二进制内容的短信 459 17.2.5 自己编写接收二进制内容的短信 461 17.3 蓝牙通信 463 17.3.1 Android 2 BluetoothChat案例 464 17.3.2 Android 2 蓝牙API介绍 464 17.3.3 TCP Socket与蓝牙Socket的区别 465 17.3.4 BluetoothChat中的类 466 17.3.5 初始化本地蓝牙设备 467 17.3.6 查找蓝牙设备 471 17.3.7 管理连接 476 17.3.8 互相之间的通信 480 17.4 WiFi通信 484 17.4.1 管理WiFi 484 17.4.2 扫描热点 487 17.4.3 Socket通信 489

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值