从艺十周年

从艺十周年


  • Linux下的sudo及其配置文件/etc/sudoers的详细配置说明

    Linux下的sudo及其配置文件/etc/sudoers的详细配置说明

    1.sudo介绍

    sudo是linux下常用的允许普通用户使用超级用户权限的工具,允许系统管理员让普通用户执行一些或者全部的root命令,如halt,reboot,su等等。这样不仅减少了root用户的登陆 和管理时间,同样也提高了安全性。Sudo不是对shell的一个代替,它是面向每个命令的。它的特性主要有这样几点:

    § sudo能够限制用户只在某台主机上运行某些命令。

    § sudo提供了丰富的日志,详细地记录了每个用户干了什么。它能够将日志传到中心主机或者日志服务器。

    § sudo使用时间戳文件来执行类似的“检票”系统。当用户调用sudo并且输入它的密码时,用户获得了一张存活期为5分钟的票(这个值可以在编译的时候改变)。

    § sudo的配置文件是sudoers文件,它允许系统管理员集中的管理用户的使用权限和使用的主机。它所存放的位置默认是在/etc/sudoers,属性必须为0411。

    2.配置文件/etc/sudoers

    它的主要配置文件是sudoers,linux下通常在/etc目录下,如果是solaris,缺省不装sudo的,编译安装后通常在安装目录的 etc目录下,不过不管sudoers文件在哪儿,sudo都提供了一个编辑该文件的命令:visudo来对该文件进行修改。强烈推荐使用该命令修改 sudoers,因为它会帮你校验文件配置是否正确,如果不正确,在保存退出时就会提示你哪段配置出错的。

    言归正传,下面介绍如何配置sudoers

    首先写sudoers的缺省配置:

    #############################################################
    # sudoers file.
    #
    # This file MUST be edited with the ‘visudo’ command as root.
    #
    # See the sudoers man page for the details on how to write a sudoers file.
    #

    # Host alias specification

    # User alias specification

    # Cmnd alias specification

    # Defaults specification

    # User privilege specification
    root    ALL=(ALL) ALL

    # Uncomment to allow people in group wheel to run all commands
    # %wheel        ALL=(ALL)       ALL

    # Same thing without a password
    # %wheel        ALL=(ALL)       NOPASSWD: ALL

    # Samples
    # %users  ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
    # %users  localhost=/sbin/shutdown -h now
    ##################################################################

    1. 最简单的配置,让普通用户support具有root的所有权限
    执行visudo之后,可以看见缺省只有一条配置:
    root    ALL=(ALL) ALL
    那么你就在下边再加一条配置:
    support ALL=(ALL) ALL

    这样,普通用户support就能够执行root权限的所有命令

    以support用户登录之后,执行:
    sudo su -
    然后输入support用户自己的密码,就可以切换成root用户了

    2. 让普通用户support只能在某几台服务器上,执行root能执行的某些命令
    首先需要配置一些Alias,这样在下面配置权限时,会方便一些,不用写大段大段的配置。Alias主要分成4种
    Host_Alias
    Cmnd_Alias
    User_Alias
    Runas_Alias

    1) 配置Host_Alias:就是主机的列表
    Host_Alias      HOST_FLAG = hostname1, hostname2, hostname3
    2) 配置Cmnd_Alias:就是允许执行的命令的列表
    Cmnd_Alias      COMMAND_FLAG = command1, command2, command3
    3) 配置User_Alias:就是具有sudo权限的用户的列表
    User_Alias USER_FLAG = user1, user2, user3
    4) 配置Runas_Alias:就是用户以什么身份执行(例如root,或者oracle)的列表
    Runas_Alias RUNAS_FLAG = operator1, operator2, operator3
    5) 配置权限
    配置权限的格式如下:
    USER_FLAG HOST_FLAG=(RUNAS_FLAG) COMMAND_FLAG
    如果不需要密码验证的话,则按照这样的格式来配置
    USER_FLAG HOST_FLAG=(RUNAS_FLAG) NOPASSWD: COMMAND_FLAG

    配置示例:
    ############################################################################
    # sudoers file.
    #
    # This file MUST be edited with the ‘visudo’ command as root.
    #
    # See the sudoers man page for the details on how to write a sudoers file.
    #

    # Host alias specification
    Host_Alias      EPG = 192.168.1.1, 192.168.1.2

    # User alias specification

    # Cmnd alias specification
    Cmnd_Alias      SQUID = /opt/vtbin/squid_refresh, /sbin/service, /bin/rm

    # Defaults specification

    # User privilege specification
    root    ALL=(ALL) ALL
    support EPG=(ALL) NOPASSWD: SQUID

    # Uncomment to allow people in group wheel to run all commands
    # %wheel        ALL=(ALL)       ALL

    # Same thing without a password
    # %wheel        ALL=(ALL)       NOPASSWD: ALL

    # Samples
    # %users  ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
    # %users  localhost=/sbin/shutdown -h now
    ###############################################################


  • Android开发之ListView 适配器(Adapter)优化

    Adapter的作用就是ListView界面与数据之间的桥梁,当列表里的每一项显示到页面时,都会调用Adapter的getView方法返回一个View。想过没有? 在我们的列表有1000000项时会是什么样的?是不是会占用极大的系统资源?

    先看看下面的代码:

    public View getView(int position, View convertView, ViewGroup parent) {
    View item = mInflater.inflate(R.layout.list_item_icon_text, null);
    ((TextView) item.findViewById(R.id.text)).setText(DATA[position]);
    ((ImageView) item.findViewById(R.id.icon)).setImageBitmap(
    (position & 1) == 1 ? mIcon1 : mIcon2);
    return item;
    }
    怎么样?如果超过1000000项时,后果不堪设想!您可千万别这么写!

    我们再来看看下面的代码:

    public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
    convertView = mInflater.inflate(R.layout.item, null);
    }
    ((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);
    ((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap(
    (position & 1) == 1 ? mIcon1 : mIcon2);
    return convertView;
    }
    怎么样,上面的代码是不是好了很多?系统将会减少创建很多View。性能得到了很大的提升。

    还有没有优化的方法呢? 答案是肯定的:

    public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
    convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
    holder = new ViewHolder();
    holder.text = (TextView) convertView.findViewById(R.id.text);
    holder.icon = (ImageView) convertView.findViewById(R.id.icon);
    convertView.setTag(holder);
    } else {
    holder = (ViewHolder) convertView.getTag();
    }
    holder.text.setText(DATA[position]);
    holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
    return convertView;
    }

    static class ViewHolder {
    TextView text;
    ImageView icon;
    }


  • android命令实战手册

    1 android.bat· 2
    1.1 查看帮助信息: 2
    1.2 创建avd· 2
    1.3 Lists existing targets or virtual devices 2
    1.4 Lists existing Android Virtual Devices 3
    1.5 Lists existing targets 4
    2 emulator.exe·· 5
    2.1 启动模拟器··· 5
    2.2 使用模拟器控制台··· 7
    3 ddms.bat· 10
    3.1 直接启动ddms 10
    4 adb·· 11
    4.1 Adb help: 11
    4.2 scripting: 13
    4.3 device commands: 14
    5 关于编译···· 17
    5.1 am: 18
    5.2 重新编译源码··· 18
    6 系统信息···· 18
    6.1 Process: list process after phone started· 19
    6.2 Memory info: list memory information after phone started· 19
    6.3 Init log: list phone init log· 19
    6.4 Bugreport: from adb bugreport· 19

    1 android.bat
    1.1 查看帮助信息:
    android.bat –h 或 android.bat –help

    1.2 创建avd
    (1) android.bat create avd -t 1 -c 256M -p
    E:\android_sdk\android-sdk-windows-1.6_r1\platforms\android-1.6\images -n avd16 -f -s HVGA
    (2) android.bat create avd -t 2 -c 256M -p
    E:\android_sdk\android-sdk-windows-1.6_r1\platforms\android-1.6\images -n avd2 -f -s HVGA
    以上,用不同的设置创建avd.
    (3) 直接用”android.bat”命令可以启动Android SDK图开界面(如下图),用它也可以创建avd;

    (4) 在eclipse中,点击工具栏中的“open the avd and SDK manager”图标来打开上图。

    1.3 Lists existing targets or virtual devices

    E:\android_sdk\android-sdk-windows-1.6_r1\tools>android.bat list
    Available Android targets:
    id: 1
    Name: Android 1.5
    Type: Platform
    API level: 3
    Revision: 1
    Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
    id: 2
    Name: Android 1.6
    Type: Platform
    API level: 4
    Revision: 1
    Skins: HVGA (default), QVGA, WVGA800, WVGA854
    id: 3
    Name: Google APIs
    Type: Add-On
    Vendor: Google Inc.
    Revision: 3
    Description: Android + Google APIs
    Based on Android 1.5 (API level 3)
    Libraries:
    * com.google.android.maps (maps.jar)
    API for Google Maps
    Skins: QVGA-P, HVGA-L, HVGA (default), QVGA-L, HVGA-P
    id: 4
    Name: Google APIs
    Type: Add-On
    Vendor: Google Inc.
    Revision: 1
    Description: Android + Google APIs
    Based on Android 1.6 (API level 4)
    Libraries:
    * com.google.android.maps (maps.jar)
    API for Google Maps
    Skins: WVGA854, HVGA (default), WVGA800, QVGA
    Available Android Virtual Devices:
    Name: avd16
    Path: C:\Documents and Settings\lizhongyi\.android\avd\avd16.avd
    Target: Android 1.6 (API level 4)
    Skin: HVGA
    ———
    Name: avd2
    Path: C:\Documents and Settings\lizhongyi\.android\avd\avd2.avd
    Target: Android 1.6 (API level 4)
    Skin: QVGA

    1.4 Lists existing Android Virtual Devices

    E:\android_sdk\android-sdk-windows-1.6_r1\tools>android list avd
    Available Android Virtual Devices:
    Name: avd16
    Path: C:\Documents and Settings\lizhongyi\.android\avd\avd16.avd
    Target: Android 1.6 (API level 4)
    Skin: HVGA
    ———
    Name: avd2
    Path: C:\Documents and Settings\lizhongyi\.android\avd\avd2.avd
    Target: Android 1.6 (API level 4)
    Skin: QVGA

    1.5 Lists existing targets
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>android list target
    Available Android targets:
    id: 1
    Name: Android 1.5
    Type: Platform
    API level: 3
    Revision: 1
    Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
    id: 2
    Name: Android 1.6
    Type: Platform
    API level: 4
    Revision: 1
    Skins: HVGA (default), QVGA, WVGA800, WVGA854
    id: 3
    Name: Google APIs
    Type: Add-On
    Vendor: Google Inc.
    Revision: 3
    Description: Android + Google APIs
    Based on Android 1.5 (API level 3)
    Libraries:
    * com.google.android.maps (maps.jar)
    API for Google Maps
    Skins: QVGA-P, HVGA-L, HVGA (default), QVGA-L, HVGA-P
    id: 4
    Name: Google APIs
    Type: Add-On
    Vendor: Google Inc.
    Revision: 1
    Description: Android + Google APIs
    Based on Android 1.6 (API level 4)
    Libraries:
    * com.google.android.maps (maps.jar)
    API for Google Maps
    Skins: WVGA854, HVGA (default), WVGA800, QVGA

    12 emulator.exe
    2.1 启动模拟器
    (1) 最简单的方法(用avd):
    emulator -avd avd2
    (2) 按尺寸启动模拟器
    emulator.exe -avd avd2 -scale 0.7

    (3) 启动userdata.img
    emulator -data userdata.img

    (4) 启动system.img
    emulator -data system.img

    (5) 使用-verbose选项

    E:\android_sdk\android-sdk-windows-1.6_r1\tools>emulator -verbose -avd avd2
    emulator: found SDK root at E:\android_sdk\android-sdk-windows-1.6_r1
    emulator: root virtual device file at C:\Documents and Settings\lizhongyi\.android/avd/avd2.ini
    emulator: virtual device content at C:\Documents and Settings\lizhongyi\.android\avd\avd2.avd
    emulator: virtual device config file: C:\Documents and Settings\lizhongyi\.android\avd\avd2.avd/config.ini
    emulator: locking user data image at C:\Documents and Settings\lizhongyi\.android\avd\avd2.avd/userdata-qemu.img
    emulator: locking cache image at C:\Documents and Settings\lizhongyi\.android\avd\avd2.avd/cache.img
    emulator: ignoring non-existing SD Card at C:\Documents and Settings\lizhongyi\.android\avd\avd2.avd/sdcard.img: No such file or directory
    emulator: found skin ‘QVGA’ in directory: E:\android_sdk\android-sdk-windows-1.6_r1/platforms\android-1.6\skins
    emulator: autoconfig: -skin QVGA
    emulator: autoconfig: -skindir E:\android_sdk\android-sdk-windows-1.6_r1/platforms\android-1.6\skins
    emulator: keyset loaded from: C:\Documents and Settings\lizhongyi\.android\default.keyset
    emulator: trying to load skin file ‘E:\android_sdk\android-sdk-windows-1.6_r1/platforms\android-1.6\skins/QVGA/layout’
    emulator: skin network speed: ‘full’
    emulator: skin network delay: ‘none’
    emulator: registered ‘boot-properties’ qemud service
    emulator: registered ‘boot-properties’ qemud service
    emulator: Adding boot property: ‘qemu.sf.lcd_density’ = ’120′
    emulator: argv[00] = “emulator”
    emulator: argv[01] = “-kernel”
    emulator: argv[02] = “E:\android_sdk\android-sdk-windows-1.6_r1/platforms\android-1.6\images\/kernel-qemu”
    emulator: argv[03] = “-initrd”
    emulator: argv[04] = “E:\android_sdk\android-sdk-windows-1.6_r1/platforms\android-1.6\images\/ramdisk.img”
    emulator: argv[05] = “-nand”
    emulator: argv[06] = “system,size=0×4200000,initfile=E:\android_sdk\android-sdk-windows-1.6_r1/platforms\android-1.6\images\/system.img”
    emulator: argv[07] = “-nand”
    emulator: argv[08] = “userdata,size=0×4200000,file=C:\Documents and Settings\lizhongyi\.android\avd\avd2.avd/userdata-qemu.img”
    emulator: argv[09] = “-nand”
    emulator: argv[10] = “cache,size=0×4200000,file=C:\Documents and Settings\lizhongyi\.android\avd\avd2.avd/cache.img”
    emulator: argv[11] = “-serial”
    emulator: argv[12] = “android-kmsg”
    emulator: argv[13] = “-serial”
    emulator: argv[14] = “android-qemud”
    emulator: argv[15] = “-append”
    emulator: argv[16] = “qemu=1 console=ttyS0 android.checkjni=1 android.qemud=ttyS1 android.ndns=1″
    emulator: argv[17] = “-m”
    emulator: argv[18] = “96″
    emulator: mapping ‘system’ NAND image to C:\DOCUME~1\LIZHON~1\LOCALS~1\Temp\\AndroidEmulator\TMP834.tmp
    emulator: using ‘winaudio’ audio input backend
    emulator: using ‘winaudio’ audio output backend
    emulator: control console listening on port 5556, ADB on port 5557
    emulator: sent ’0012host:emulator:5557′ to ADB server
    emulator: ping program: E:\android_sdk\android-sdk-windows-1.6_r1\tools\ddms.bat
    emulator: ping command: C:\WINDOWS\system32\cmd.exe /C “E:\android_sdk\android-sdk-windows-1.6_r1\tools\ddms.bat” ping emulator 1.11

    (6) 使用- logcat 选项
    emulator -logcat main -avd avd2

    (7) 使用-trace选项
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>emulator -trace main(或events,或radio) -avd avd2
    – When done tracing, exit the emulator. –
    emulator: emulator window was out of view and was recentred
    或者:
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>emulator -trace radio -trace main -trace radio -avd avd2

    (7) 使用- kernel和-ramdisk选项
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>emulator -kernel ..\platforms\android-1.6\images\kernel-qemu -ramdisk ..\platforms\android-1
    .6\images\ramdisk.img -debug-kernel -verbose -avd avd2

    (7) 使用- netfast选项
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>emulator -netfast -avd avd2

    2.2 使用模拟器控制台
    每一个运行中的模拟器实例都包括一个控制台,你可以利用控制台动态的查询和控制模拟设备的环境 。例如,你可以利用控制台动态的管理端口映射和网络特性,还可以模拟电话时间。要想进入控制台输入 命令,你需要使用telnet连接到控制台的端口号。

    可以使用下面的命令随时随地连接到任何一个运行中的模拟器实例:

    telnet localhost 端口号

    假设第一个模拟器实例的控制台使用5554端口,下一个实例使用的端口号会加2,比如5556、5558…… 等。你可以在启动模拟器是使用-verbose选项来检测该模拟器实例使用的端口号,在调试 输出的找到以”emulator console running on port number”这一行。 另外, 你可 以在命令行中使用adb devices来查看模拟器实例和他们的端口列表。最多可以有16个模拟 器实例同时运行控制台。

    (1) 进入控制台
    先在一个cmd窗口中启动一个模拟器, 再打开一个cmd窗口,运行telnet命令,如下:
    E:\android_sdk\android-sdk-windows-1.6_r1\tools> telnet localhost 5556
    ( 因为在我的PC上,启动了两个模拟器, 一个用的是5554端口,另一个用的是5556端口.这里,控制的是使用5556端口的模拟器)
    进入后,如下图:

    (2) gsm测试

    输入
    gsm voice on
    ok
    则可以在模拟器上看到3G图标,并且网络图标处于有信号状态。

    而执行
    gsm voice off
    ok
    后,3G图标消失,并且网络图标处于关闭(X)状态。

    gsm call 13522543026
    ok
    后,模拟器有如下反应:

    (3) sms测试
    sms send 13522543026 hello
    ok
    则, 在模拟器的messaging中,就会看到有一条短信了.
    如图:

    13 ddms.bat

    3.1 直接启动ddms
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>ddms
    02:30 I/ddms: Created: [Debugger 8600-->568 inactive]
    02:30 I/ddms: Created: [Debugger 8601-->617 inactive]
    02:30 I/ddms: Created: [Debugger 8602-->619 inactive]
    02:30 I/ddms: Created: [Debugger 8603-->657 inactive]
    02:30 I/ddms: Created: [Debugger 8604-->670 inactive]
    02:30 I/ddms: Created: [Debugger 8605-->681 inactive]

    这和eclipse中的ddms是一样的.

    4 adb

    1.14.1 Adb help:

    直接运行adb会显示出adb的help信息.如下:

    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb -help
    Android Debug Bridge version 1.0.22

    -d – directs command to the only connected USB device
    returns an error if more than one USB device is present.
    -e – directs command to the only running emulator.
    returns an error if more than one emulator is running.
    -s – directs command to the USB device or emulator with
    the given serial number
    -p – simple product name like ‘sooner’, or
    a relative/absolute path to a product
    out directory like ‘out/target/product/sooner’.
    If -p is not specified, the ANDROID_PRODUCT_OUT
    environment variable is used, which must
    be an absolute path.
    devices – list all connected devices

    device commands:
    adb push – copy file/dir to device
    adb pull – copy file/dir from device
    adb sync [ ] – copy host->device only if changed
    (see ‘adb help all’)
    adb shell – run remote shell interactively
    adb shell – run remote shell command
    adb emu – run emulator console command
    adb logcat [ ] – View device log
    adb forward – forward socket connections
    forward specs are one of:
    tcp: localabstract:
    localreserved:
    localfilesystem:
    dev:
    jdwp: (remote only)
    adb jdwp – list PIDs of processes hosting a JDWP transport
    adb install [-l] [-r] – push this package file to the device and install it
    (‘-l’ means forward-lock the app)
    (‘-r’ means reinstall the app, keeping its data)
    adb uninstall [-k] – remove this app package from the device
    (‘-k’ means keep the data and cache directories)
    adb bugreport – return all information from the device
    that should be included in a bug report.

    adb help – show this help message
    adb version – show version num

    DATAOPTS:
    (no option) – don’t touch the data partition
    -w – wipe the data partition
    -d – flash the data partition

    scripting:
    adb wait-for-device – block until device is online
    adb start-server – ensure that there is a server running
    adb kill-server – kill the server if it is running
    adb get-state – prints: offline | bootloader | device
    adb get-serialno – prints:
    adb status-window – continuously print device status for a specified device
    adb remount – remounts the /system partition on the device read-write
    adb reboot [bootloader|recovery] – reboots the device, optionally into the bootloader or recovery program
    adb root – restarts adb with root permissions

    networking:
    adb ppp [parameters] – Run PPP over USB.
    Note: you should not automatically start a PPP connection.
    refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1
    [parameters] – Eg. defaultroute debug dump local notty usepeerdns

    adb sync notes: adb sync [ ]
    can be interpreted in several ways:

    – If is not specified, both /system and /data partitions will be updated.

    - If it is “system” or “data”, only the corresponding partition
    is updated.

    14.2 scripting:
    (1) start adb server
    方法1: E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb kill-server

    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb start-server
    * daemon not running. starting it now *
    * daemon started successfully *
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>

    方法2: E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb kill-server

    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb fork-server server
    OK

    注意: 方法1是直接用adb的scripting “adb start-server” 来启动的, 启动成功后,直接返回到cmd命令窗口;
    方法2 是用直接启动adb server进程的方式” adb fork-server server”来启动的,启动成功后, 显示”OK”, 并且不返回到cmd命令窗口.
    分析: 这是因为adb.exe是一个命令(可执行程序), 它启动后,会调用到” adb fork-server server”(这个server正是adb server), 然后, adb.exe就退出了,这时,只剩下adb server 这个进程了,这个进程的名字也是adb.exe.而方法2是直接启动adb server,所以,不能退出,如果退出,就相当于adb server退出了.
    adb server启动后,会在任务管理器中进程中可以看到adb.exe.
    如果用户将adb.exe 强行结束了,那么, 对于方法2,就会回到cmd窗口.
    另外,如果eclipse中启动了模拟器,那么, 强行结束adb server后, 会再启动一个.

    (2) adb get-state and get-serialno
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb get-state
    device

    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb get-serialno
    emulator-5554

    如果同时启动了两个模拟器,则这两个脚本的执行结果均是:
    unknown

    (3) adb root
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb root
    adbd is already running as root

    adb reboot recovery
    (4) adb reboot [android-sdk-windows-1.6_r1支持]
    adb reboot bootloader(或 recovery)
    说明:reboots the device, optionally into the bootloader or recovery program,可见,只针对真机,
    所以,当运行此脚本时,模拟器就不能运行了。
    另外,此脚本是从android-sdk-windows-1.6_r1开始支持的。

    1.12.3 device commands:
    (1) list all connected devices
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb devices
    List of devices attached
    emulator-5554 device
    emulator-5556 device

    (2) adb shell
    开机:
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb shell
    # ls
    ls
    sqlite_stmt_journals
    cache
    sdcard
    etc
    system
    sys
    sbin
    proc
    init.rc
    init.goldfish.rc
    init
    default.prop
    data
    root
    dev
    # cd data
    cd data
    # ls
    ls
    misc
    local
    data
    app-private
    app
    property
    anr
    dalvik-cache
    system
    lost+found

    # cd data
    cd data
    # pwd
    pwd
    /data/data
    # ls -l
    Ls -l
    # ls -l
    ls -l
    drwxr-xr-x app_0 app_0 2009-11-25 02:42 com.android.packageinstaller
    drwxr-xr-x app_1 app_1 2009-11-25 02:42 com.android.providers.contacts
    drwxr-xr-x app_2 app_2 2009-11-25 02:42 com.android.fallback
    drwxr-xr-x app_1 app_1 2009-11-25 02:42 com.android.inputmethod.latin
    drwxr-xr-x app_3 app_3 2009-11-25 02:42 com.android.gesture.builder
    drwxr-xr-x app_4 app_4 2009-11-25 02:42 com.google.android.marvin.talkback
    drwxr-xr-x app_5 app_5 2009-11-25 02:42 com.android.providers.downloads
    drwxr-xr-x app_1 app_1 2009-11-25 02:42 com.android.inputmethod.pinyin
    drwxr-xr-x system system 2009-11-25 02:42 com.android.providers.settings
    drwxr-xr-x app_6 app_6 2009-11-25 02:42 com.android.development
    drwxr-xr-x app_7 app_7 2009-11-25 02:42 com.android.email
    drwxr-xr-x app_8 app_8 2009-11-25 02:42 com.android.music
    drwxr-xr-x app_1 app_1 2009-11-25 02:42 com.android.globalsearch
    drwxr-xr-x app_9 app_9 2009-11-25 02:42 jp.co.omronsoft.openwnn
    drwxr-xr-x app_10 app_10 2009-11-25 02:42 com.android.mms
    drwxr-xr-x app_5 app_5 2009-11-25 02:42 com.android.camera
    drwxr-xr-x app_11 app_11 2009-11-25 02:42 com.android.term
    drwxr-xr-x system system 2009-11-25 02:42 com.android.settings
    drwxr-xr-x app_12 app_12 2009-11-25 02:42 com.android.browser
    drwxr-xr-x app_13 app_13 2009-11-25 02:42 android.tts
    drwxr-xr-x app_14 app_14 2009-11-25 02:42 com.android.customlocale
    drwxr-xr-x app_1 app_1 2009-11-25 02:42 com.android.providers.userdictionary
    drwxr-xr-x app_15 app_15 2009-11-25 02:42 com.android.soundrecorder
    drwxr-xr-x app_16 app_16 2009-11-25 02:42 com.android.netspeed
    drwxr-xr-x radio radio 2009-11-25 02:43 com.android.phone
    drwxr-xr-x app_1 app_1 2009-11-25 02:43 com.android.contacts
    drwxr-xr-x app_17 app_17 2009-11-25 02:43 com.android.htmlviewer
    drwxr-xr-x system system 2009-11-25 02:43 com.android.server.vpn
    drwxr-xr-x app_1 app_1 2009-11-25 02:43 com.google.android.providers.enhancedgooglesearch
    drwxr-xr-x app_18 app_18 2009-11-25 02:43 com.android.sdksetup
    drwxr-xr-x app_4 app_4 2009-11-25 02:43 com.google.android.marvin.soundback
    drwxr-xr-x app_5 app_5 2009-11-25 02:43 com.android.providers.drm
    drwxr-xr-x app_1 app_1 2009-11-25 02:43 com.android.launcher
    drwxr-xr-x app_1 app_1 2009-11-25 02:43 com.android.providers.applications
    drwxr-xr-x app_19 app_19 2009-11-25 02:43 com.svox.pico
    drwxr-xr-x app_5 app_5 2009-11-25 02:43 com.android.providers.media
    drwxr-xr-x app_20 app_20 2009-11-25 02:43 com.android.calculator2
    drwxr-xr-x app_4 app_4 2009-11-25 02:43 com.google.android.marvin.kickback
    drwxr-xr-x radio radio 2009-11-25 02:43 com.android.providers.telephony
    drwxr-xr-x app_21 app_21 2009-11-25 02:43 com.android.alarmclock
    drwxr-xr-x app_22 app_22 2009-11-25 02:43 com.android.spare_parts
    先后启动kx011和a两个应用程序(都是activity),则,
    在/data/data下,就会看到如下两个应用了,
    # ls
    a.a
    com.kx011
    而且,在/data/app下,也有这两个应用的apk文件。
    # cd /data/app
    cd /data/app
    # ls
    ls
    com.kx011.apk
    a.a.apk

    说明:在/data/data目录下,存放了所有系统已经启动的的应用程序;
    在/data/app下,以apk的形式存放了用户建立的应用。

    (3)adb pull // 说明:copy file/dir from device
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb pull /init.rc F:\ABD\x.txt
    668 KB/s (10700 bytes in 0.015s)

    adb push – copy file/dir to device
    adb pull – copy file/dir from device

    (4)adb push // 说明:copy file/dir to device
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb push ddms.bat /data/
    124 KB/s (1992 bytes in 0.015s)

    (5) adb install
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb install D:\allProject\android16\kx011\bin\kx011.apk
    259 KB/s (8297 bytes in 0.031s)
    pkg: /data/local/tmp/kx011.apk
    Success
    #
    说明: install 完成之后,直接进入adb shell

    (6) adb jdwp
    E:\android_sdk\android-sdk-windows-1.6_r1\tools>adb jdwp
    567
    614
    616
    641
    661
    678
    707
    714

    (7) adb bugreport
    列出了bug信息,see to bugreport.txt [ 点击查看 ]

    13 关于编译

    1.13.1 am:

    adb install c:\NetScramble_1.1.apk
    adb shell rm data/app/NetScramble_1.1.apk
    am start -n net.xiashou.android/net.xiashou.android.HelloAndroid
    # am start -a android.intent.action.VIEW -d http://www.xiashou.net
    # am start -a android.intent.action.CALL -d tel:10086
    # am start -a android.intent.action.VIEW geo:0,0?q=tianjin
    # am start –n com.android.music/.MediaPlaybackActivity

    1.13.2 重新编译源码
    当然,这是在linux下面进行的。
    (1) 编译源码
    解压原码到本地,进入原码目录,执行: make, 即可。

    (2) 编译SDK
    在make完成后,直接make sdk,会在out/host/linux-x86/sdk下面生成mdk文件及文件夹,形如:android-sdk_eng.xxx_linux-x86

    (3) 编译单个模块
    1.先将system文件夹移出,
    2.在android目录下执行
    $ . build/envsetup.sh
    3. 然后你就会多出几个可用的命令。在改了Contacts联系人项目后,可以简单的执行一下命令来单独编译这个部分:
    $mmm packages/apps/Contacts/
    或者在src目录下直接运行make module name :
    cd ~/android/src
    make Contacts
    4.将新生成的system文件夹覆盖原system文件夹
    5.然后编译system.img
    ./out/host/linux-x86/bin/mkyaffs2image -f out/target/product/generic/system out/target/product/generic/system.img
    第二次mmm需将/out/target/product/generic/obj/全部拷回!!!
    (mmm命令非常的多管闲事,它每次编译都把obj删了!!!)
    输出cmd命令到文件
    dir > a.log

    4 系统信息
    由于篇幅的原因,这里,只给出链接,分别列出了process, memory info, init log, bugreport信息。值得注意的是,bugreport 中包含了前三项。另外,process和memory info是从真机中导出来的,init log 和bugreport是从模拟器拿到的,而且,取得的日期时间都不一致

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liranke/archive/2009/12/16/5014534.aspx
    23:32评论 / 浏览 (0 / 1386)收藏分类:移动开发
    2010-05-31
    缩略显示
    如何更换Android模拟器界面

    博客分类: android
    AndroidEclipseIDE
    1、制作或下载一个已有Android模拟器界面(比如TMobile-G1)
    2、拷贝到你的$(path of your android sdk)\platforms\android-1.5\skins\TMobile-G1 目录下,通常是一些PNG和layout文件
    3、重新启动Eclipse,IDE会自动加载这些界面
    4、在AVD Manager里创建一个AVD,Name为TMobile-G1, Target为Android-1.5,Skin在下拉列表框中选择刚才下载的TMobile-G1皮肤
    5、把该AVD应用到你的应用程序中,运行即可。
    23:28评论 / 浏览 (0 / 482)收藏分类:移动开发
    2010-05-31
    缩略显示
    Android开发指南-工具-画九宫格

    博客分类: android
    Android浏览器Windows工作.net
    画九宫格Draw 9-patch
    这个九宫格绘画工具(draw9patch.bat)可以让你很容易的通过一个所见即所得(WYS|WYG)的编辑器来创建一个九宫格NinePatch图。
    关于九宫格图以及它是如何工作的,请阅读九宫格图像Ninepatch Images主题的相关章节。

    下面是一个便捷指南。你需要PNG图像来创建一个九宫格。
    1. 从一个终端(比如windows浏览器),启动这个draw9patch应用程序,该程序位于你的SDK /tools 目录下。
    2. 把你的PNG图像拖放到这个工具的窗口中(或者通过File->Open 9-patch… 来定位文件)。你的工作台将被打开。
    左边的窗格是你的绘画区域,你可以在里面编辑可延伸的宫格和内容区域。右边窗格是预览区域,从中你可以预览图形的拉伸。
    3. 在1个像素周长里点击,绘制线条来定义可延伸宫格以及(可选的)内容区域。点击右键(或者在苹果机上,按住Shift并点击)取消之前画的线。
    4. 这些完成后,选择File > Save 9-patch…
    你的图片将以.9.png 文件名保存。
    注意: 一个通常的PNG文件(*.png) 加载时,将以一个空的单像素边界补充在图片周围,你可以在里面画可延伸宫格和内容区域。一个前面保存的九宫格文件(*.9.png)将以原样加载,因为这个已经存在。

    可选控制包括:
    · 缩放Zoom: 调整图片大小
    · 宫格比例Patch scale: 调整预览视图中图像的比例
    · 显示锁定区域Show lock: 使不可画区域在鼠标移动到该区域上时显示出来。
    · 显示宫格Show patches: 预览这个绘图区中的可延伸宫格(粉红色代表一个可延伸宫格)。
    · 显示内容Show content: 预览视图中的高亮内容区域(紫色部分)。
    · 显示坏宫格Show bad patches: 在宫格区域四周增加一个红色边界,这可能会在图像被延伸时产生人工痕迹。如果你消除所有的坏宫格,延伸视图的视觉一致性将得到维护。

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/iefreer/archive/2009/09/29/4618025.aspx
    23:26评论 / 浏览 (0 / 837)收藏分类:移动开发
    2010-05-31
    缩略显示
    Android开发指南-二维图形

    博客分类: android
    AndroidXML活动游戏编程
    二维图形2D Graphics
    Android 提供一个定制的2D图形库,用来绘制图形图像和制作动画。你将从android.graphics.drawable和android.view.animation包中找到这些通用类。
    本文简单介绍如何在Android应用程序中进行画图。我们将讨论使用Drawable对象画图的基础知识,如何使用几个Drawable子类,以及如何创建动画,一个图形的补间动画或者一系列图形的连续动画(就像电影胶卷一样)。
    可绘制物Drawables
    一个Drawable 是一个“某些可以被绘制的物体”的一般抽象。你将发现这个Drawable类扩展了多种具体可绘制图形类,包括BitmapDrawable, ShapeDrawable, PictureDrawable, LayerDrawable, 等等。当然,你还可以扩展这些类来定义你自己的具有独特行为的可绘制对象。
    有三种方式来定义和实例化一个Drawable:使用一个保存在你的项目资源中的图像;使用一个定义了Drawable属性的XML文件;或者使用通常的类构造函数。下面,我们将挨个讨论前面两种方法(对于一个经验丰富的开发人员而言,使用构造函数没什么新意)。
    从资源图像中创建Creating from resource images
    一个为你的应用程序增加图形的简单方法是通过引用项目资源中的一个图片文件。支持的图片文件格式有PNG(推荐的),JPG(可接受的)和GIF(不鼓励的)。这个技术将显然推荐使用在应用程序图标,logo,或者其它类似使用于游戏中的图形。
    为了使用一个图片资源,只要把你的文件添加到你项目的res/drawable/目录即可。从那里,你可以在代码或XML布局中进行引用。任何一种方式,都是通过资源ID来引用,资源ID是不带扩展后缀的文件名(比如,my_image.png通过my_image来引用)。
    注意: 图像资源被放在res/drawable/里。也许会通过aapt工具进行无损图像压缩而被自动优化。比如,一个不需要多于256色的真彩色PNG图片可能会被转换成一个带有调色板的8位PNG。这产生了相同质量但占用更少内存的图片。因此需要意识到该目录下的二进制图像可能会在编译期间被改变。如果你想以比特流读取一个图片并转换为一个位图,那么需要把你的图片文件放在res/raw/目录,这里的文件不会被优化。
    示例代码Example code
    下面的代码片断说明了如何构造一个ImageView,从drawable资源中使用并添加到布局中。
    LinearLayout mLinearLayout;

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Create a LinearLayout in which to add the ImageView
    mLinearLayout = new LinearLayout(this);

    // Instantiate an ImageView and define its properties
    ImageView i = new ImageView(this);
    i.setImageResource(R.drawable.my_image);
    i.setAdjustViewBounds(true); // set the ImageView bounds to match the Drawable’s dimensions
    i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

    // Add the ImageView to the layout and set the layout as the content view
    mLinearLayout.addView(i);
    setContentView(mLinearLayout);
    }
    在其它情况下,你可能想把你的图片资源当作一个可绘制Drawable对象。为此,你可以这样做:
    Resources res = mContext.getResources();
    Drawable myImage = res.getDrawable(R.drawable.my_image);
    注意: 每个你项目里的唯一资源只能维护一个状态,而无论你为它实例化了多少个不同对象。比如,如果你从相同的图像资源实例化两个可绘制对象,然后改变其中之一的属性(比如alpha),那它也将作用于另一个。所以当处理一个图片资源的多个实例时,你应该实施一个tween animation,而不是直接转换这个可绘制对象。

    示例XML
    下面的XML片断显示了如何添加一个可绘制资源到一个XML布局中的ImageView里(为了有趣些,添加一些红色渲染)。
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:tint="#55ff0000"
    android:src="@drawable/my_image"/>
    更多关于使用项目资源的信息,请阅读资源和资产Resources and Assets。
    从资源XML中创建Creating from resource XML
    到目前为止,你应该对Android用户界面User Interface的开发原理比较熟悉。因此,你应该了解在XML中定义对象所固有的能力和灵活性。这个理念从视图延伸到可绘制对象。如果你想创建一个可绘制(Drawable)对象,而它并不初始依赖于你代码中的变量或者用户交互,那么在XML里面定义它是个好的选择。即便你预期这个可绘制对象在用户使用你的应用程序时将会改变其属性,你也应该考虑在XML里面定义它,因为一旦被实例化后,你就可以修改它的属性。
    一旦你在XML中定义了你的可绘制对象,把这个文件保存到你项目中的res/drawable/ 目录下。然后,通过传递资源ID参数调用Resources.getDrawable()获取并实例化这个对象。 (参见example below.)
    任何支持inflate()方法的可绘制对象(Drawable)子类可以在XML里定义并由你的应用程序实例化。每个支持XML扩充的可绘制对象利用特定的XML属性来帮助定义对象属性(参见类参考了解这些属性)。查阅每个可绘制对象子类的类描述文档,以获知如何在XML中定义它。
    例子Example
    下面是一些定义了一个TransitionDrawable对象的XML语句:



    当把这个XML保存为res/drawable/expand_collapse.xml文件后,下面的代码将用来实例化它并把它设置为一个ImageView的内容:
    Resources res = mContext.getResources();
    TransitionDrawable transition = (TransitionDrawable) res.getDrawable(R.drawable.expand_collapse);
    ImageView image = (ImageView) findViewById(R.id.toggle_image);
    image.setImageDrawable(transition);
    然后通过下面的方法让这个transition运转起来(每1秒转变一次):
    transition.startTransition(1000);
    请参考上面所列的可绘制对象(Drawable)类以了解更多它们所支持的XML属性。
    可绘制形状ShapeDrawable
    当你想动态的画一些二维图形时,ShapeDrawable对象可能会满足你的要求。 通过一个ShapeDrawable,你可以绘制原始图形和以任何想象得到的方式设计它们。
    ShapeDrawable是Drawable的一个扩展类,因此你能使用在任何可用Drawable的地方- 也许是视图背景,用setBackgroundDrawable()方法来设置。当然,你还能以它自己的视图来绘制图形,并添加到你的布局中只要你乐意。因为ShapeDrawable有它自己的draw()方法,你可以创建一个视图子类在View.onDraw()方法中绘制这个ShapeDrawable。下面这个视图类的一个基本扩展就是这么做的,把ShapeDrawable作为一个视图来绘制。
    public class CustomDrawableView extends View {
    private ShapeDrawable mDrawable;

    public CustomDrawableView(Context context) {
    super(context);

    int x = 10;
    int y = 10;
    int width = 300;
    int height = 50;

    mDrawable = new ShapeDrawable(new OvalShape());
    mDrawable.getPaint().setColor(0xff74AC23);
    mDrawable.setBounds(x, y, x + width, y + height);
    }

    protected void onDraw(Canvas canvas) {
    mDrawable.draw(canvas);
    }
    }
    在构造函数里,ShapeDrawable被定义为一个OvalShape。然后设置颜色和边界。如果你不设置边界,那么这个图形将不被绘制,不过如果你不设置颜色的话,它会设置成缺省的黑色。
    通过这个定制视图,它能以任何你想要的方式绘制。通过上面的例子,我们能在一个活动中以编程的方式绘制这个图形:
    CustomDrawableView mCustomDrawableView;

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mCustomDrawableView = new CustomDrawableView(this);

    setContentView(mCustomDrawableView);
    }
    如果你希望从XML布局中而不是活动中绘制这个自定义可绘制对象,那么这个CustomDrawable类必须重写View(Context, AttributeSet) 构造函数,这个当通过XML扩充来实例化一个视图时被调用。然后为这个XML添加一个CustomDrawable元素,如下:
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    />
    这个ShapeDrawable类(像很多其他在android.graphics.drawable包中的可绘制对象类型一样)允许你通过公共的方法来定义这个可绘制对象的各种属性。有一些属性,你可能会做一些调整,比如alpha透明度,颜色过滤器,抖动,模糊度和颜色。
    可绘制九宫格
    一个NinePatchDrawable图形是一个可拉伸位图图像,Android会自动调整来容纳视图的内容,你可以用来作为背景。一个使用九宫格的例子是Android按钮背景-按钮必须延伸以适应各种长度的字符串。一个九宫格可绘制对象是一个标准的PNG图像,并包含一个附加的单像素宽的边界。它必须以扩展名.9.png保存,并存放到res/drawable/目录。
    这个边界用来定义这个图像的可拉伸和静态区域。通过在边界的左边和上面部分绘画单像素宽的一个或多条黑线来指示一个可拉伸区。(你能有任意多的可拉伸区)。这些可拉伸区的相对尺寸保持一样,因此最大的区域总是保持最大。
    你也可以通过在右边和下面画线来定义这个图片(事实上,这些填充线)的一个可选的可绘制区。如果一个视图对象设置这个九宫格为其背景然后指定这个视图的文本,它将自我调整以使得文本适应在刚才通过右边和下面的画线指定的区域里面(如果被包含进来)。如果这些填充线未被包含,Android使用左边和上面的线来定义可绘制区域。
    为了阐明不同线的区别,左边和上面定义了哪些图像像素允许被复制来拉伸这个图像。下面和右边的线则定义了这个图像中的相对区域,这个区域可允许视图内容显示于其中。
    下面是一个用来定义一个按钮的九宫格文件例子:

    这个九宫格通过左边和上面的线条定义了一个可拉伸区域以及通过下面和右边的线条定义了一个可绘制区域。在图中上半部分,灰色的虚线标示了可以被复制来拉伸图像的区域。而下半部分的粉红虚线框标示了允许显示视图内容的区域。如果内容不能适应这个区域,那么这个图像将被拉伸来适应它。
    Draw 9-patch 工具提供了一个非常方便的方法来创建你的九宫格图像,使用一个所见即所得的图像编辑器。它甚至会在你的可拉伸区域会产生人工痕迹时(复制像素的副效果)提出告警。
    示例XMLExample XML
    下面是一些示例布局XML来说明怎么添加一个九宫格图像到几个按钮中。(这个九宫格图像被保存为res/drawable/my_button_background.9.png)


  • EditText 属性大全

    EditText的属性
    本文主要研究一下EditText的属性(还没研究完,边研究边写)

    android:layout_gravity=”center_vertical”//设置控件显示的位置:默认top,这里居中显示,还有bottom

    android:hint=”请输入数字!”//设置显示在空间上的提示信息

    android:numeric=”integer”//设置只能输入整数,如果是小数则是:decimal

    android:singleLine=”true”//设置单行输入,一旦设置为true,则文字不会自动换行。

    android:gray=”top” //多行中指针在第一行第一位置

    et.setSelection(et.length());//调整光标到最后一行

    Android:autoText//自动拼写帮助

    Android:capitalize//首字母大写

    Android:digits//设置只接受某些数字

    Android:singleLine //是否单行或者多行,回车是离开文本框还是文本框增加新行

    Android:numeric //只接受数字

    Android:password //密码

    Android:phoneNumber // 输入电话号码

    Android:editable //是否可编辑

    Android:autoLink=”all” //设置文本超链接样式当点击网址时,跳向该网址

    android:password=”true”//设置只能输入密码

    android:textColor= “#ff8c00″//字体颜色

    android:textStyle=”bold”//字体,bold, italic,bolditalic

    android:textSize=”20dip”//大小

    android:capitalize= “characters”//以大写字母写

    android:textAlign=”center”//EditText没有这个属性,但TextView有

    android:textColorHighlight=”#cccccc”//被选中文字的底色,默认为蓝色

    android:textColorHint=”#ffff00″//设置提示信息文字的颜色,默认为灰色

    android:textScaleX=”1.5″//控制字与字之间的间距

    android:typeface=”monospace”//字型,normal, sans, serif,monospace

    android:background=”@null”//空间背景,这里没有,指透明

    android:layout_weight=”1″//权重 在控制控
    件显示的大小时蛮有用的。

    android:textAppearance=”?android:attr/textAppearanceLargeInverse”//文字外观,这里引用的是系统自带的一个外观,?表示系统是否有这种外观,否则使用默认的外观。不知道这样理解对不对?

     属性名称描述
      android:autoLink设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接。可选值(none/web/email/phone/map/all)
      android:autoText如果设置,将自动执行输入值的拼写纠正。此处无效果,在显示输入法并输入的时候起作用。
      android:bufferType指定getText()方式取得的文本类别。选项editable 类似于StringBuilder可追加字符,
      也就是说getText后可调用append方法设置文本内容。spannable 则可在给定的字符区域使用样式,参见这里1、这里2。
      android:capitalize设置英文字母大写类型。此处无效果,需要弹出输入法才能看得到,参见EditView此属性说明。
      android:cursorVisible设定光标为显示/隐藏,默认显示。
      android:digits设置允许输入哪些字符。如“1234567890.+-*/%()”
      android:drawableBottom在text的下方输出一个drawable,如图片。如果指定一个颜色的话会把text的背景设为该颜色,并且同时和background使用时覆盖后者。
      android:drawableLeft在text的左边输出一个drawable,如图片。
      android:drawablePadding设置text与drawable(图片)的间隔,与drawableLeft、drawableRight、drawableTop、drawableBottom一起使用,可设置为负数,单独使用没有效果。


  • 下面列出几种Intent的用法

    下面列出几种Intent的用法
    显示网页:

    1. Uri uri = Uri.parse(“http://www.google.com”);
    2. Intent it  = new Intent(Intent.ACTION_VIEW,uri);
    3. startActivity(it);

    显示地图:

    1. Uri uri = Uri.parse(“geo:38.899533,-77.036476″);
    2. Intent it = new Intent(Intent.Action_VIEW,uri);
    3. startActivity(it);

    路径规划:

    1. Uri uri = Uri.parse(“http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en”);
    2. Intent it = new Intent(Intent.ACTION_VIEW,URI);
    3. startActivity(it);

    拨打电话:

    调用拨号程序

    1. Uri uri = Uri.parse(“tel:xxxxxx”);
    2. Intent it = new Intent(Intent.ACTION_DIAL, uri);
    3. startActivity(it);
    1. Uri uri = Uri.parse(“tel.xxxxxx”);
    2. Intent it =new Intent(Intent.ACTION_CALL,uri);

    要使用这个必须在配置文件 中加入<uses-permission id=”android .permission.CALL_PHONE” />

    发送SMS/MMS
    调用发送短信 的程序

    1. Intent it = new Intent(Intent.ACTION_VIEW);
    2. it.putExtra(“sms_body”, “The SMS text”);
    3. it.setType(“vnd.android-dir/mms-sms”);
    4. startActivity(it);

    发送短信

    1. Uri uri = Uri.parse(“smsto:0800000123″);
    2. Intent it = new Intent(Intent.ACTION_SENDTO, uri);
    3. it.putExtra(“sms_body”, “The SMS text”);
    4. startActivity(it);

    发送彩信

    1. Uri uri = Uri.parse(“content://media/external/images/media/23″);
    2. Intent it = new Intent(Intent.ACTION_SEND);
    3. it.putExtra(“sms_body”, “some text”);
    4. it.putExtra(Intent.EXTRA_STREAM, uri);
    5. it.setType(“image/png”);
    6. startActivity(it);

    发送Email

    1. Uri uri = Uri.parse(“mailto:xxx@abc.com”);
    2. Intent it = new Intent(Intent.ACTION_SENDTO, uri);
    3. startActivity(it);
    1. Intent it = new Intent(Intent.ACTION_SEND);
    2. it.putExtra(Intent.EXTRA_EMAIL, “me@abc.com”);
    3. it.putExtra(Intent.EXTRA_TEXT, “The email body text”);
    4. it.setType(“text/plain”);
    5. startActivity(Intent.createChooser(it, “Choose Email Client”));
    1. Intent it=new Intent(Intent.ACTION_SEND);
    2. String[] tos={“me@abc.com”};
    3. String[] ccs={“you@abc.com”};
    4. it.putExtra(Intent.EXTRA_EMAIL, tos);
    5. it.putExtra(Intent.EXTRA_CC, ccs);
    6. it.putExtra(Intent.EXTRA_TEXT, “The email body text”);
    7. it.putExtra(Intent.EXTRA_SUBJECT, “The email subject text”);
    8. it.setType(“message/rfc822″);
    9. startActivity(Intent.createChooser(it, “Choose Email Client”));

    添加附件

    1. Intent it = new Intent(Intent.ACTION_SEND);
    2. it.putExtra(Intent.EXTRA_SUBJECT, “The email subject text”);
    3. it.putExtra(Intent.EXTRA_STREAM, “file:///sdcard/mysong.mp3″);
    4. sendIntent.setType(“audio/mp3″);
    5. startActivity(Intent.createChooser(it, “Choose Email Client”));

    播放 多媒体

    1. Intent it = new Intent(Intent.ACTION_VIEW);
    2. Uri uri = Uri.parse(“file:///sdcard/song.mp3″);
    3. it.setDataAndType(uri, “audio/mp3″);
    4. startActivity(it);
    1. Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, “1″);
    2. Intent it = new Intent(Intent.ACTION_VIEW, uri);
    3. startActivity(it);

    Uninstall 程序

    1. Uri uri = Uri.fromParts(“package”, strPackageName, null);
    2. Intent it = new Intent(Intent.ACTION_DELETE, uri);
    3. startActivity(it);
    1. uninstall apk
    2. Uri uninstallUri = Uri.fromParts(“package”, “xxx”, null);
    3. returnIt = new Intent(Intent.ACTION_DELETE, uninstallUri);

    install apk

    1. Uri installUri = Uri.fromParts(“package”, “xxx”, null);
    2. returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);

    play audio

    1. Uri playUri = Uri.parse(“file:///sdcard/download/everything.mp3″);
    2. returnIt = new Intent(Intent.ACTION_VIEW, playUri);

    //发送附件

    1. Intent it = new Intent(Intent.ACTION_SEND);
    2. it.putExtra(Intent.EXTRA_SUBJECT, “The email subject text”);
    3. it.putExtra(Intent.EXTRA_STREAM, “file:///sdcard/devdiv.mp3″);
    4. sendIntent.setType(“audio/mp3″);
    5. startActivity(Intent.createChooser(it, “Choose Email Client”));

    market相关

    再来一个market相关的:
    market相关

    //搜索应用

    1. Uri uri = Uri.parse(“market://search?q=pname:pkg_name”);
    2. Intent it = new Intent(Intent.ACTION_VIEW, uri);
    3. startActivity(it);
    4. //where pkg_name is the full package path for an application

    //显示指定应用的详细页面(这个好像不支持了,找不到app_id)

    1. Uri uri = Uri.parse(“market://details?id=app_id”);
    2. Intent it = new Intent(Intent.ACTION_VIEW, uri);
    3. startActivity(it);
    4. //where app_id is the application ID, find the ID
    5. //by clicking on your application on Market home
    6. //page, and notice the ID from the address bar

    I am using the following code snippet for searching through Google

    1. Intent intent = new Intent();
    2. intent.setAction(Intent.ACTION_WEB_SEARCH);
    3. intent.putExtra(SearchManager.QUERY,”searchString”)
    4. startActivity(intent);

     

     


  • 获取手机设备识别码

    package com.demo.android;

    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.provider.Settings;
    import android.telephony.TelephonyManager;
    import android.widget.TextView;

    public class androidId extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    fetch_status();
    }

    public void fetch_status(){

    TelephonyManager tm = (TelephonyManager) this

    .getSystemService(Context.TELEPHONY_SERVICE);//

    String str = “”;

    str +=”andrdoi_id =” + Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID)+ “\n”;

    str += “DeviceId(IMEI) = ” + tm.getDeviceId() + “\n”;

    str += “DeviceSoftwareVersion = ” + tm.getDeviceSoftwareVersion() + “\n”;

    str += “Line1Number = ” + tm.getLine1Number() + “\n”;

    str += “NetworkCountryIso = ” + tm.getNetworkCountryIso() + “\n”;

    str += “NetworkOperator = ” + tm.getNetworkOperator() + “\n”;

    str += “NetworkOperatorName = ” + tm.getNetworkOperatorName() + “\n”;

    str += “NetworkType = ” + tm.getNetworkType() + “\n”;

    str += “honeType = ” + tm.getPhoneType() + “\n”;

    str += “SimCountryIso = ” + tm.getSimCountryIso() + “\n”;

    str += “SimOperator = ” + tm.getSimOperator() + “\n”;

    str += “SimOperatorName = ” + tm.getSimOperatorName() + “\n”;

    str += “SimSerialNumber = ” + tm.getSimSerialNumber() + “\n”;

    str += “SimState = ” + tm.getSimState() + “\n”;

    str += “SubscriberId(IMSI) = ” + tm.getSubscriberId() + “\n”;

    str += “VoiceMailNumber = ” + tm.getVoiceMailNumber() + “\n”;

    TextView sys = (TextView) findViewById(R.id.get);

    sys.setText(str);

    }

    }

    需要加权限:
    但是获取android_id的那句代码是不需要此权限的


  • 优化

    优化循环,通过重新组织重复的子表达式来提高循环体的运行性能
    减少使用对象的数量来提高运行性能
    缩减网络传输数据来缩短等待时间等

    1、采用对象池技术、提高对象的利用效率
    2、尽可能地使用基本数据类型代替对象,节省资源开销
    3、用简单的数值计算代替复杂的函数计算,节省处理器时间


  • Android Intent机制实例详解

    Android中提供了Intent机制来协助应用间的交互与通讯,或者采用更准确的说法是,Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。Intent这个英语单词的本意是“目的、意向”等,对于较少从事于大型平台开发工作的程序员来说,这可能是一个不太容易理解的抽象概念,因为它与我们平常使用的简单函数/方法调用,或者上节中提到的通过库调用接口的方式不太一样。在Intent的使用中你看不到直接的函数调用,相对函数调用来说,Intent是更为抽象的概念,利用Intent所实现的软件复用的粒度是Activity/Service,比函数复用更高一些,另外耦合也更为松散。
    Android中与Intent相关的还有Action/Category及Intent Filter等,另外还有用于广播的Intent,这些元素掺杂在一起,导致初学者不太容易迅速掌握Intent的用法。在讲解这些名词之前,我们先来从下面的例子中感受一下Intent的一些基本用法,看看它能做些什么,之后再来思考这种机制背后的意义。
    理解Intent的关键之一是理解清楚Intent的两种基本用法:一种是显式的Intent,即在构造Intent对象时就指定接收者,这种方式与普通的函数调用类似,只是复用的粒度有所差别;另一种是隐式的Intent,即Intent的发送者在构造Intent对象时,并不知道也不关心接收者是谁,这种方式与函数调用差别比较大,有利于降低发送者和接收者之间的耦合。另外Intent除了发送外,还可用于广播,这些都将在后文进行详细讲述。
    下面的一小节我们来看看显式Intent的用法。
    显式的Intent(Explicit Intent)
    ² 同一个应用程序中的Activity切换
    我们在前面的章节已经讨论过Activity的概念,通常一个应用程序中需要多个UI屏幕,也就需要多个Activity类,并且在这些Activity之间进行切换,这种切换就是通过Intent机制来实现的。
    在同一个应用程序中切换Activity时,我们通常都知道要启动的Activity具体是哪一个,因此常用显式的Intent来实现。下面的例子用来实现一个非常简单的应用程序SimpleIntentTest,它包括两个UI屏幕也就是两个Activity——SimpleIntentTest类和TestActivity类,SimpleIntentTest类有一个按钮用来启动TestActivity,程序运行的截图如图5.3所示:

    Android Intent机制实例详解二

    程序的代码非常简单,SimpleIntentTest类的源代码如下:
    package com.tope.samples.intent.simple;
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    public class SimpleIntentTest extends Activity implements View.OnClickListener{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button startBtn = (Button)findViewById(R.id.start_activity);
    startBtn.setOnClickListener(this);
    }

    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.start_activity:
    Intent intent = new Intent(this, TestActivity.class);
    startActivity(intent);
    break;
    default:
    break;
    }
    }
    }
    上面的代码中,主要是为“Start activity”按钮添加了OnClickListener,使得按钮被点击时执行onClick()方法,onClick()方法中则利用了Intent机制,来启动TestActivity,关键的代码是下面这两行:
    Intent intent = new Intent(this, TestActivity.class);
    startActivity(intent);
    这里定义Intent对象时所用到的是Intent的构造函数之一:
    Intent(Context packageContext, Class cls)
    两个参数分别指定Context和Class,由于将Class设置为TestActivity.class,这样便显式的指定了TestActivity类作为该Intent的接收者,通过后面的startActivity()方法便可启动TestActivity。
    TestActivity的代码更为简单(定义TestActivity类需要新建TestActivity.java文件,如果你是一个初学者,你需要学会如何在Eclipse或其他开发环境下添加一个新的类,本书不作详述,请参考其他文档),如下所示:
    package com.tope.samples.intent.simple;
    import android.app.Activity;
    import android.os.Bundle;
    public class TestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_activity);
    }
    }
    可见TestActivity仅仅是调用setContentView来显示test_activity.xml中的内容而已。对于test_activity.xml及本例中所用到其他xml文件这里不作多余说明,读者练习时可自行参考本书所附光盘中的源代码。
    如果我们仅仅是做上面的一些工作,还不能达到利用SimpleIntentTest启动TestActivity的目的。事实上,这样做会出现下面的Exception,导致程序退出。以下是利用logcat工具记录的log信息(省略了后半部分):
    I/ActivityManager( 569): Displayed activity com.tope.samples/.SimpleIntentTest: 3018 ms
    I/ActivityManager( 569): Starting activity: Intent { comp={com.tope.samples/com.tope.samples.TestActivity} }
    D/AndroidRuntime( 932): Shutting down VM
    W/dalvikvm( 932): threadid=3: thread exiting with uncaught exception (group=0x4000fe70)
    E/AndroidRuntime( 932): Uncaught handler: thread main exiting due to uncaught exception
    E/AndroidRuntime( 932): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.tope.samples/com.tope.samples.TestActivity}; have you declared this activity in your AndroidManifest.xml?
    E/AndroidRuntime( 932): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1480)
    E/AndroidRuntime( 932): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1454)
    E/AndroidRuntime( 932): at android.app.Activity.startActivityForResult(Activity.java:2656)
    E/AndroidRuntime( 932): at android.app.Activity.startActivity(Activity.java:2700)
    E/AndroidRuntime( 932): at com.tope.samples.SimpleIntentTest.onClick(SimpleIntentTest.java:24)

    Android Intent机制实例详解三

    从这些log中我们可以看到点击按钮后startActivity的调用过程,主要的原因是:“android.content.ActivityNotFoundException: Unable to find explicit activity class {com.tope.samples/com.tope.samples.TestActivity}; have you declared this activity in your AndroidManifest.xml?”
    从这些log我们可以看到原因是找不到TestActivity这个Activity,并且log中还给出了提示:你是否在AndroidManifest.xml中声明了这个Activity?解决问题的方法也就是按照提示在AndroidManifest.xml中增加TestActivity的声明,如下所示,注意粗体字部分:

    package="com.tope.samples"
    android:versionCode="1"
    android:versionName="1.0">

    android:label="@string/app_name">









    完成这个修改后再重新运行该程序,就一切都正常了。
    从AndroidManifest.xml修改的过程我们可以体会到,Intent机制即使在程序内部且显式指定接收者,也还是需要在AndroidManifest.xml中声明TestActivity。这个过程并不像一个简单的函数调用,显式的Intent也同样经过了Android应用程序框架所提供的支持,从满足条件的Activity中进行选择,如果不在AndroidManifest.xml中进行声明,则Android应用程序框架找不到所需要的Activity。
    请读者通过我们的示例来逐步理解AndroidManifest.xml在这个过程中所扮演的角色,这样有利于理解Intent的作用,及后面的Intent Filter。当然,这个例子仅仅是开始,且看下文分解。
    ² 不同应用程序之间的Activity切换
    上面的例子我们所做的是在同一应用程序中进行Activity的切换,那么在不同的应用程序中,是否也能这么做呢,答案是肯定的,不过对应的代码要稍作修改。本例中我们需要两个应用程序,可利用上例中的SimpleIntentTest作为其中之一,另外还需要写一个新的程序,来调用SimpleIntentTest应用程序中的TestActivity。
    我们新建程序CrossIntentTest(注意不是新建一个类,如果是Eclipse环境,选择File->New->Project新建工程),其中只有一个Activity,其源代码与SimpleIntentTest.java类似:
    package com.tope.samples.intent.cross;
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    public class CrossIntentTest extends Activity
    implements View.OnClickListener{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button startBtn = (Button)findViewById(R.id.start_activity);
    startBtn.setOnClickListener(this);
    }

    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.start_activity:
    Intent intent = new Intent();
    intent.setClassName(“com.tope.samples.intent.simple”,
    “com.tope.samples.intent.simple.TestActivity”);
    startActivity(intent);
    break;
    default:
    break;
    }
    }
    }
    注意比较它与SimpleIntentTest的不同之处主要在于初始化Intent对象的过程:
    Intent intent = new Intent();
    intent.setClassName(“com.tope.samples.intent.simple”,
    “com.tope.samples.intent.simple.TestActivity”);
    startActivity(intent);
    Android Intent机制实例详解四

    package com.tope.samples.intent.simple;
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    public class SimpleIntentTest extends Activity implements View.OnClickListener{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button startBtn = (Button)findViewById(R.id.start_activity);
    startBtn.setOnClickListener(this);
    }

    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.start_activity:
    Intent intent = new Intent(this, TestActivity.class);
    startActivity(intent);
    break;
    default:
    break;
    }
    }
    }
    上面的代码中,主要是为“Start activity”按钮添加了OnClickListener,使得按钮被点击时执行onClick()方法,onClick()方法中则利用了Intent机制,来启动TestActivity,关键的代码是下面这两行:
    Intent intent = new Intent(this, TestActivity.class);
    startActivity(intent);
    这里定义Intent对象时所用到的是Intent的构造函数之一:
    Intent(Context packageContext, Class cls)
    两个参数分别指定Context和Class,由于将Class设置为TestActivity.class,这样便显式的指定了TestActivity类作为该Intent的接收者,通过后面的startActivity()方法便可启动TestActivity。
    TestActivity的代码更为简单(定义TestActivity类需要新建TestActivity.java文件,如果你是一个初学者,你需要学会如何在Eclipse或其他开发环境下添加一个新的类,本书不作详述,请参考其他文档),如下所示:
    package com.tope.samples.intent.simple;
    import android.app.Activity;
    import android.os.Bundle;
    public class TestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_activity);
    }
    }
    可见TestActivity仅仅是调用setContentView来显示test_activity.xml中的内容而已。对于test_activity.xml及本例中所用到其他xml文件这里不作多余说明,读者练习时可自行参考本书所附光盘中的源代码。
    如果我们仅仅是做上面的一些工作,还不能达到利用SimpleIntentTest启动TestActivity的目的。事实上,这样做会出现下面的Exception,导致程序退出。以下是利用logcat工具记录的log信息(省略了后半部分):
    I/ActivityManager( 569): Displayed activity com.tope.samples/.SimpleIntentTest: 3018 ms
    I/ActivityManager( 569): Starting activity: Intent { comp={com.tope.samples/com.tope.samples.TestActivity} }
    D/AndroidRuntime( 932): Shutting down VM
    W/dalvikvm( 932): threadid=3: thread exiting with uncaught exception (group=0x4000fe70)
    E/AndroidRuntime( 932): Uncaught handler: thread main exiting due to uncaught exception
    E/AndroidRuntime( 932): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.tope.samples/com.tope.samples.TestActivity}; have you declared this activity in your AndroidManifest.xml?
    E/AndroidRuntime( 932): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1480)
    E/AndroidRuntime( 932): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1454)
    E/AndroidRuntime( 932): at android.app.Activity.startActivityForResult(Activity.java:2656)
    E/AndroidRuntime( 932): at android.app.Activity.startActivity(Activity.java:2700)
    E/AndroidRuntime( 932): at com.tope.samples.SimpleIntentTest.onClick(SimpleIntentTest.java:24)

    Android Intent机制实例详解五

    从这些log中我们可以看到点击按钮后startActivity的调用过程,主要的原因是:“android.content.ActivityNotFoundException: Unable to find explicit activity class {com.tope.samples/com.tope.samples.TestActivity}; have you declared this activity in your AndroidManifest.xml?”
    从这些log我们可以看到原因是找不到TestActivity这个Activity,并且log中还给出了提示:你是否在AndroidManifest.xml中声明了这个Activity?解决问题的方法也就是按照提示在AndroidManifest.xml中增加TestActivity的声明,如下所示,注意粗体字部分:

    package="com.tope.samples"
    android:versionCode="1"
    android:versionName="1.0">

    android:label="@string/app_name">









    完成这个修改后再重新运行该程序,就一切都正常了。
    从AndroidManifest.xml修改的过程我们可以体会到,Intent机制即使在程序内部且显式指定接收者,也还是需要在AndroidManifest.xml中声明TestActivity。这个过程并不像一个简单的函数调用,显式的Intent也同样经过了Android应用程序框架所提供的支持,从满足条件的Activity中进行选择,如果不在AndroidManifest.xml中进行声明,则Android应用程序框架找不到所需要的Activity。
    请读者通过我们的示例来逐步理解AndroidManifest.xml在这个过程中所扮演的角色,这样有利于理解Intent的作用,及后面的Intent Filter。当然,这个例子仅仅是开始,且看下文分解。
    ² 不同应用程序之间的Activity切换
    上面的例子我们所做的是在同一应用程序中进行Activity的切换,那么在不同的应用程序中,是否也能这么做呢,答案是肯定的,不过对应的代码要稍作修改。本例中我们需要两个应用程序,可利用上例中的SimpleIntentTest作为其中之一,另外还需要写一个新的程序,来调用SimpleIntentTest应用程序中的TestActivity。
    我们新建程序CrossIntentTest(注意不是新建一个类,如果是Eclipse环境,选择File->New->Project新建工程),其中只有一个Activity,其源代码与SimpleIntentTest.java类似:
    package com.tope.samples.intent.cross;
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    public class CrossIntentTest extends Activity
    implements View.OnClickListener{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button startBtn = (Button)findViewById(R.id.start_activity);
    startBtn.setOnClickListener(this);
    }

    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.start_activity:
    Intent intent = new Intent();
    intent.setClassName(“com.tope.samples.intent.simple”,
    “com.tope.samples.intent.simple.TestActivity”);
    startActivity(intent);
    break;
    default:
    break;
    }
    }
    }


  • 利用View.inflate加载xml

    Layout1.xml

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent" >

    android:layout_width="fill_parent"

    android:layout_height="40px"

    android:background="#ff00ff00"

    android:text="This is main layout" />

    android:id="@+id/box_1"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:layout_below="@+id/box_0">


    Layout2.xml

    android:id="@+id/box"

    android:orientation="horizontal"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent" >

    android:layout_width="fill_parent"
    android:layout_height="40px"
    android:background="#ffff0000"
    android:text="this is 2" />

    setContentView(R.layout.layout_1);
    LinearLayout ll = (LinearLayout) findViewById(R.id.box_1);

    View vv = View.inflate(this, R.layout.layout_2, null);

    ll.addView(vv, new LinearLayout.LayoutParams( ll.getLayoutParams().width,ll.getLayoutParams().height));

    这个主要是在某一个控件里面动态加载。

    也可以利用inflate加载menu

    android:title="Home"
    android:icon="@drawable/home" >

    android:title="Help"
    android:icon="@drawable/help" >

    android:title="Save n Quit"
    android:icon="@drawable/save_quit" >

    android:title="Quit"
    android:icon="@drawable/exit" >

    public class Welcome extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu, menu);
    return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.home:
    // TODO
    break;
    case R.id.help:
    // TODO
    break;
    case R.id.save:
    // TODO
    break;
    case R.id.exit:
    // TODO
    break;
    }
    return true;
    }
    }

    2.两种刚方法:
    LayoutInflater inflater = getLayoutInflater();
    View layout = inflater.inflate(R.layout.toast_sms,
    (ViewGroup) findViewById(R.id.toast_sms_root));
    LayoutInflater mInflater = LayoutInflater.from(context);
    View myView = mInflater.inflate(R.layout.customToast, null);
    TextView sender = (TextView) myView.findViewById(R.id.sender);
    TextView message = (TextView) myView.findViewById(R.id.message);


  • Android Intent和Intent Filter详解

    Intents and Intent Filters
    Intent Objects Intent对象
    Intent Resolution Intent解析
    Intent filters
    Filters and security Filter和安全
    Common cases 常见情况
    Using intent matching 使用intent匹配
    Note Pad Example 例子:记事本

    Intents and Intent Filters
    三种应用程序基本组件——activity, service和broadcast receiver——是使用称为intent的消息来激活的。Intent消息传递是一种组件间运行时绑定的机制. intent是Intent对象, 它包含了需要做的操作的描述, 或者, 对于广播来说, 包含了正在通知的消息内容. 对于向这三种组件发送intent有不同的机制:
    使用Context.startActivity() 或 Activity.startActivityForResult(), 传入一个intent来启动一个activity. 使用 Activity.setResult(), 传入一个intent来从activity中返回结果.
    将intent对象传给Context.startService()来启动一个service或者传消息给一个运行的service. 将intent对象传给 Context.bindService()来绑定一个service.
    将intent对象传给 Context.sendBroadcast(), Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方法,则它们被传给 broadcast receiver.
    在上述三种情况下, android系统会自己找到合适的activity, service, 或者 broadcast receivers来响应intent. 三者的intent相互独立互不干扰.
    Intent Objects Intent对象
    一个intent对象包含了接受该intent的组件的信息(例如需要的动作和该动作需要的数据)和android系统所需要的信息. 具体的说:
    组件名称
    为一个ComponentName 对象. 它是目标组件的完整名(例如”com.example.project.app.FreneticActivity”)和应用程序manifest文件设定的包名(例如”com.example.project”)的组合.前者的包名部分和后者不一定一样.
    组件名称是可选的. 如果设定了的话, Intent对象会被传给指定的类的一个实例. 如果不设定, 则android使用其它信息来定位合适的目标.
    组件名称是使用setComponent(), setClass(),或 setClassName()来设定, 使用 getComponent()来获取.
    Action
    一个字符串, 为请求的动作命名, 或者, 对于broadcast intent, 发生的并且正在被报告的动作. 例如:

    常量 目标组件 动作
    ACTION_CALL activity 发起一个电话呼叫.
    ACTION_EDIT activity 显示数据给用户来编辑.
    ACTION_MAIN activity 将该activity作为一个task的第一个activity启动,不传入参数也不期望返回值.
    ACTION_SYNC activity 将设备上的数据和一个服务器同步.
    ACTION_BATTERY_LOW broadcast receiver 发出电量不足的警告.
    ACTION_HEADSET_PLUG broadcast receiver 一个耳机正被插入或者拔出.
    ACTION_SCREEN_ON broadcast receiver 屏幕被点亮.
    ACTION_TIMEZONE_CHANGED broadcast receiver 时区设置改变.

    你也可以定义自己的action字符串用来启动你的应用程序. 自定义的action应该包含应用程序的包名.例如”com.example.project.SHOW_COLOR”.
    action很大程度上决定了intent的另外部分的结构, 就像一个方法名决定了它接受的参数和返回值一样. 因此, 最好给action一个最能反映其作用的名字.
    一个intent对象中的action是使用getAction()和setAction()来读写的.
    Data
    需要操作的数据的URI和它的MIME(多用途互联网邮件扩展,Multipurpose Internet Mail Extensions)类型. 例如, 如果action为ACTION_EDIT, 那么Data将包含待编辑的数据URI. 如果action为ACTION_CALL, Data将为tel:电话号码的URI. 如果action为ACTION_VIEW, 则Data为http:网络地址的URI.
    当将一个intent和一个组件相匹配时, 除了URI外数据类型也很重要. 例如, 一个显示图片的程序不应该用来处理声音文件.
    数据类型常常可以从URI推断, 特别是content:URI, 它表示该数据属于一个content provider. 但数据类型也可以被intent对象显示声明. setData()方法设置URI, 而setType()方法指定MIME类型, setDataAndType()设置数据URI和MIME类型. 它们可以使用getData()和getType()来读取.
    Category
    一个字符串,包含了关于处理该intent的组件的种类的信息. 一个intent对象可以有任意个category. intent类定义了许多category常数, 例如:

    常量 含义
    CATEGORY_BROWSABLE 目标activity可以使用浏览器来显示-例如图片或电子邮件消息.
    CATEGORY_GADGET 该activity可以被包含在另外一个装载小工具的activity中.
    CATEGORY_HOME 该activity显示主屏幕,也就是用户按下Home键看到的界面.
    CATEGORY_LAUNCHER 该activity可以作为一个任务的第一个activity,并且列在应用程序启动器中.
    CATEGORY_PREFERENCE 该activity是一个选项面板.

    addCategory()方法为一个intent对象增加一个category, removeCategory删除一个category, getCategories()获取intent所有的category.
    Extras
    为键值对形式的附加信息. 例如ACTION_TIMEZONE_CHANGED的intent有一个”time-zone”附加信息来指明新的时区, 而ACTION_HEADSET_PLUG有一个”state”附加信息来指示耳机是被插入还是被拔出.
    intent对象有一系列put…()和set…()方法来设定和获取附加信息. 这些方法和Bundle对象很像. 事实上附加信息可以使用putExtras()和getExtras()作为Bundle来读和写.
    Flags
    各种标志. 很多标志指示android系统如何启动一个activity(例如该activity属于哪个任务)和启动后如何处理它(例如, 它是否属于最近activity列表中).
    android系统和应用程序使用intent对象来送出系统广播和激活系统定义的组件.
    Intent Resolution Intent解析
    intent有两种:
    显式intent使用名字来指定目标组件. 由于组件名称一般不会被其它开发者所熟知, 这种intent一般用于应用程序内部消息– 例如一个activity启动一个附属的service或者另一个activity.
    隐式intent不指定目标的名称. 一般用于启动其它应用程序的组件.
    Android将显式intent发送给指定的类. intent对象中名字唯一决定接受intent的对象.对于隐式intent, android系统必须找到最合适的组件来处理它. 它比较intent的内容和intent filter. intent filter是组件的一个相关结构, 表示其接受intent的能力. android系统根据intent filter打开可以接受intent的组件. 如果一个组件没有intent filter, 那么它只能接受显式intent. 如果有, 则能同时接受二者.当一个intent和intent filter比较时, 只考虑三个属性: action, data, category.extra和flag在intent解析中没有用.
    Intent filters
    activity, service和broadcast receiver可以有多个intent filter来告知系统它们能接受什么样的隐式intent. intent filter的名字很形象: 它过滤掉不想接受的intent, 留下想接受的intent. 显式intent无视intent filter.一个组件对能做的每件事有单独的filter. 例如, 记事本程序的NoteEditor activity有两个filter — 一个启动并显示一个特定的记录给用户查看或编辑, 另一个启动一个空的记录给用户编辑.
    Filters and security Filter和安全
    一个intent filter不一定安全可靠. 一个应用程序可以让它的某个组件去接受隐式intent, 但是它没法防止这个组件接受显示intent. 其它的程序总是可以使用自定义的数据加上显式的程序名称来调用该组件.
    一个intent filter是IntentFilter类的实例, 但是它一般不出现在代码中,而是出现在android Manifest文件中, 以的形式. (有一个例外是broadcast receiver的intent filter是使用 Context.registerReceiver()来动态设定的, 其intent filter也是在代码中创建的.)
    一个filter有action, data, category等字段. 一个隐式intent为了能被某个intent filter接受, 必须通过3个测试. 一个intent为了被某个组件接受, 则必须通过它所有的intent filter中的一个.
    Action 测试
    java代码:

    1. <intent-filter >
    2. <action android:name=”com.example.project.SHOW_CURRENT” />
    3. <action android:name=”com.example.project.SHOW_RECENT” />
    4. <action android:name=”com.example.project.SHOW_PENDING” />
    5. . . .
    6. </intent-filter>

    一个intent对象只能指定一个action, 而一个intent filter可以指定多个action. action列表不能为空, 否则它将组织所有的intent.
    一个intent对象的action必须和intent filter中的某一个action匹配, 才能通过.如果intent filter的action列表为空, 则不通过.如果intent对象不指定action, 并且intent filter的action列表不为空, 则通过.
    Category 测试
    java代码:




    注意前面说到的对于action和category的常数是在代码中用的,而不是manifest文件中用的. 例如, CATEGORY_BROWSABLE常数对应xml中的表示为”android.intent.category.BROWSABLE”.
    一个intent要通过category测试, 那么该intent对象中的每个category都必须和filter中的某一个匹配.
    理论上来说, 一个intent对象如果没有指定category的话, 它应该能通过任意的category 测试. 有一个例外: android把所有的传给startActivity()的隐式intent看做至少有一个category: “android.intent.category.DEFAULT”. 因此, 想要接受隐式intent的activity必须在intent filter中加入”android.intent.category.DEFAULT”.
    Data test
    java代码:



    . . .

    每个元素指定了一个URI和一个数据类型. URI每个部分为不同的属性 — scheme, host, port, path:
    scheme://host:port/path
    例如, 在如下的URI中:content://com.example.project:200/folder/subfolder/etc
    scheme为”content”, host为”com.example.project”, port为”200″, path为”folder/subfolder/etc”. host和port一起组成了URI authority. 如果host未指定,则port被忽略.
    这些属性都是可选的,但它们并非相互独立: 要使一个authority有意义,必须指定一个scheme. 要使一个path有意义, 必须指定一个scheme和一个authority.
    当intent对象中的URI和intent filter中相比较时, 它只和filter中定义了的部分比较. 例如, 如果filter中之定义了scheme,那么所有包含该scheme的URI的intent对象都通过测试.对于path来说,可以使用通配符来进行部分匹配.
    元素的type属性指定了数据类型. 它在filter中比在URI中更常见. intent对象和filter都可以使用”*”通配符作为子类型. 例如”text/*” “audio/*”表示所有的子类型都匹配.
    data测试的规则如下:
    一个不含uri也不含数据类型的intent对象只通过两者都不包含的filter.
    一个含uri但不含数据类型的intent对象(并且不能从uri推断数据类型的)只能通过这样的filter: uri匹配, 并且不指定类型. 这种情况限于类似mailto:和tel:这样的不指定实际数据的uri.
    一个只包含数据类型但不包含URI的intent只通过这样的filter: 该filter只列出相同的数据类型, 并且不指定uri.
    一个既包含uri又包含数据类型的intent对象只通过这样的filter: intent对象的数据类型和filter中的一个类型匹配, intent对象的uri要么和filter的uri匹配, 要么intent对象的uri为content:或者file:, 并且filter不指定uri.
    如果一个intent可以通过多于一个activity或者service的filter, 那么用户可能会被询问需要启动哪一个. 如果一个都没有的话, 那么会抛出异常.
    Common cases 常见情况
    上述的最后一个规则(d)说明了组件通常可以从文件和content provider中获取数据. 因此, 它们的filter可以只列出数据类型不列scheme. 这是个特殊情况. 下列元素告诉android该组件可以从一个content provider取得图像数据并显示之:
    java代码:

    由于大部分可用的数据由content provider提供, 指定数据类型但不指定uri的filter是最常见的情况.
    另外一个常见的配置是filter具有一个scheme和一个数据类型. 例如, 下列元素告诉android该component可以从网络获取图像数据并显示之:
    java代码:

    考虑用户点击一个网页时浏览器的动作. 它首先试图显示这个数据(当做一个html页来处理). 如果无法显示, 则创建一个隐式intent, 并启动一个可以处理它的activity. 如果没有这样的activity, 那么它请求下载管理器来下载该数据. 然后它将数据置于一个content provider的控制之下, 这样有很多activity(拥有只有数据类型的filter)可以处理这些数据.
    大部分应用程序还有一种方法来单独启动, 不需要引用任何特定的数据. 这些能启动应用程序的activity具有action为”android.intent.action.MAIN” 的filter. 如果它们需要在应用程序启动器中显示, 它们必须指定”android.intent.category.LAUNCHER” 的category.
    java代码:




    Using intent matching 使用intent匹配
    intent和intent filter相匹配, 不仅为了寻找并启动一个目标组件, 也是为了寻找设备上组件的信息. 例如, android系统启动了应用程序启动器, 该程序位于屏幕的顶层, 显示了用户可以启动的程序, 这是通过查找设备上所有的action为”android.intent.action.MAIN” ,category为”android.intent.category.LAUNCHER”的intent filter所在的activity实现的. 然后它显示了这些activity的图标和标题. 类似的, 它通过寻找 “android.intent.category.HOME”的filter来定位主屏幕程序.
    应用程序可以用相同的方式来使用intent匹配. PackageManager 有一组query…()方法来寻找接受某个特定intent的所有组件, 还有一系列resolve…()方法来决定响应一个intent的最佳组件. 例如, queryIntentActivities()返回一个activity列表, 这些activity可以执行传入的intent. 类似的还有queryIntentServices()和queryIntentBroadcastReceivers().
    Note Pad Example 例子:记事本
    记事本示例程序让用户可以浏览一个笔记列表, 查看, 编辑, 删除和增加笔记. 这一节关注该程序定义的intent filter.
    在其manifest文件中, 记事本程序定义了三个activity, 每个有至少一个intent filter. 它还定义了一个content provider来管理笔记数据. manifest 文件如下:
    java代码:
    package="eoe.demo">
    android:label="@string/app_name" >

    android:authorities="com.google.provider.NotePad" />


















    android:theme="@android:style/Theme.Light"
    android:label="@string/title_note" >













    android:label="@string/title_edit_title"
    android:theme="@android:style/Theme.Dialog">










    第一个activity, NoteList, 和其它activity不同, 因为它操作一个笔记的目录(笔记列表), 而不是一个单独的笔记. 它一般作为该程序的初始界面. 它可以做以下三件事:
    java代码:




    该filter声明了记事本应用程序的主入口. 标准的MAIN action是一个不需要任何其它信息(例如数据等)的程序入口, LAUNCHER category表示该入口应该在应用程序启动器中列出.
    java代码:







    该filter声明了改activity可以对一个笔记目录做的事情. 它允许用户查看或编辑该目录(使用VIEW和EDIT action), 或者选取特定的笔记(使用PICK action).
    元素的mimeType指定了这些action可以操作的数据类型. 它表明该activity可以从一个持有记事本数据的content provider(vnd.google.note)取得一个或多个数据项的Cursor(vnd.android.cursor.dir).
    注意该filter提供了一个DEFAULT category. 这是因为 Context.startActivity() 和 Activity.startActivityForResult()方法将所有的intent都作为作为包含了DEFAULT category来处理, 只有两个例外:
    显式指明目标activity名称的intent.
    包含MAIN action 和LAUNCHER category的intent.
    因此, 除了MAIN和LAUNCHER的filter之外, DEFAULT category是必须的.
    java代码:





    这个filter描述了该activity能够在不需要知道目录的情况下返回用户选择的一个笔记的能力. GET_CONTENT action和PICK action相类似. 在这两者中, activity都返回用户选择的笔记的URI. (返回给调用startActivityForResult()来启动NoteList activity的activity.) 在这里, 调用者指定了用户选择的数据类型而不是数据的目录.
    这个数据类型, vnd.android.cursor.item/vnd.google.note, 表示了该activity可以返回的数据类型 — 一个笔记的URI. 从返回的URI, 调用者可以从持有笔记数据的content provider(vnd.google.note)得到一个项目(vnd.android.cursor.item)的Cursor.
    也就是说, 对于PICK来说, 数据类型表示activity可以给用户显式的数据类型.对于GET_CONTENT filter, 它表示activity可以返回给调用者的数据类型.
    下列intent可以被NoteList activity接受:
    action: android.intent.action.MAIN
    不指定任何数据直接启动activity.
    action: android.intent.action.MAIN
    category: android.intent.category.LAUNCHER
    不指定任何数据直接启动activity. 这是程序启动器使用的intent. 所有使用该组合的filter的activity被加到启动器中.
    action: android.intent.action.VIEW
    data: content://com.google.provider.NotePad/notes
    要求activity显示一个笔记列表,这个列表位于content://com.google.provider.NotePad/notes. 用户可以浏览这个列表并获取列表项的信息.
    action: android.intent.action.PICK
    data: content://com.google.provider.NotePad/notes
    请求activity显示content://com.google.provider.NotePad/notes下的笔记列表. 用户可以选取一个笔记, activity将返回笔记的URI给启动NoteList的activity.
    action: android.intent.action.GET_CONTENT
    data type: vnd.android.cursor.item/vnd.google.note
    请求activity提供记事本数据的一项.
    第二个activity, NoteEditor, 为用户显示一个笔记并允许他们编辑它. 它可以做以下两件事:
    java代码:







    这个activity的主要目的是使用户编辑一个笔记–VIEW或者EDIT一个笔记. (在category中,EDIT_NOTE是EDIT的同义词.) intent包含匹配MIME类型vnd.android.cursor.item/vnd.google.note的URI–也就是某一个特定的笔记的URI. 它一般来说是NoteList activity中的PICK或者GET_CONTENT action返回的.像以前一样,该filter列出了DEFAULT category.
    java代码:





    该activity的第二个目的是使用户能够创建一个新的笔记, 并插入到已存在的笔记目录中. 该intent包含了匹配vnd.android.cursor.dir/vnd.google.note的URI, 也就是笔
    有了这些能力, NoteEditor就可以接受以下intent:
    action: android.intent.action.VIEW
    data: content://com.google.provider.NotePad/notes/ID
    要求activity显示给定ID的笔记.
    action: android.intent.action.EDIT
    data: content://com.google.provider.NotePad/notes/ID
    要求activity显示指定ID的笔记,然后让用户来编辑它. 如果用户保存了更改,则activity更新该content provider的数据.
    action: android.intent.action.INSERT
    data: content://com.google.provider.NotePad/notes
    要求activity创建一个新的空笔记在content://com.google.provider.NotePad/notes, 并允许用户编辑它, 如果用户保存了更改,则该URI被返回给调用者.
    最后一个activity, TitleEditor, 允许用户编辑笔记的标题. 这可以通过直接调用activity(在intent中设置组件名称)的方式来实现. 但是这里我们用这个机会来展示如何在已有数据上进行另外的操作
    java代码:








  • dinamic_sidebar 4 none

©2012 从艺十周年 Entries (RSS) and Comments (RSS)  Raindrops Theme