修改Mac的环境变量方法

2011年09月5日

1. 检查当前使用的是什么SHELL echo $SHELL
2. 如果是bash,则在用户根目录编辑或创建 .bash_profile 文件
3. 加入需要的环境变量,例如 export PATH=$PATH:$HOME/bin
4. 执行命令使配置生效 source .bash_profile

Eclipse+Resin开发环境配置 for Mac OS 10.6

2011年04月26日

一:下载、编译、安装Resin-Pro4
1.下载Resin Pro (www.caucho.com),解压到任意目录
2.打开控终端(控制台),进入解压后的Resin目录,执行以下两条命令,用于设置Java环境
JAVA_HOME=/Library/java/Home
export JAVA_HOME
3.编译Resin,执行以下命令(编译的好处是可使用JNI提升Resin的效率)
./configure –prefix=/opt/resin –enable-64bit-jni
make install
4.编译过程如未报错的话,Resin已部署在/opt/resin
备注:建议申请测试用的license,可开启ResinPro的所有功能

二:Eclipse和Resin插件安装
1.Eclipse的安装所有开发者都会,这里不是重点
2.运行Eclipse,利用Install New Software功能安装Resin Plug,插件安装地址:http://caucho.com/eclipse

三:创建一个Dynamic Web Project Demo
1.启动Eclipse,创建一个新的Workspace,进入偏好设置修改Workspace的默认文件字符集为UTF-8
2.创建Dynamic Web Project,注意以下几项设置
Target runtime:创建一个新的运行环境,Server选择Resin 4.0,Resin Home=/opt/resin
Web Module: Context root建议设置成短名,方便访问,Content directory=webapps (纯属个人习惯)
3.

待续…

中国应用开发者团队研究报告2010

2011年03月3日

分享由易观国际整理的研究报告:中国应用开发者团队研究报告2010

Analytics for Android Apps

2010年12月23日

With the addition of custom variables to the Mobile Analytics SDK for Android, it strikes me as a good time to cover something many of you might not have known was possible — using Google Analytics to easily track app usage. Using the mobile SDK is a handy way to get real data on how users interact with your Android apps. So today I’m going to explain how to track usage of your application with Google Analytics.

Prereqs Ahoy!

Before you take off running with this shiny new toy, there’s a few things you’ll need to set up first:

  • Download the mobile SDK. Download and installation instructions are available in the getting started section of the Mobile SDK docs, but the summarized version is:

    • Download the zip file from the download page

    • Put the libGoogleAnalytics.jar file in your project’s /libs directory

    • Be sure the following lines are in your AndroidManifest.XML file:
      <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

  • You’re going to need a Google Analytics account. Go to google.com/analytics and set up an account if you don’t already have one. Then set up a profile for your Android application. When you’re done you’ll see a javascript snippet to insert into your “site”. Copy the part that looks like UA-XXXXXXX-X. You’ll use this in the Android application to tell Analytics which profile the data is being sent for.

Get Tracking

Previous Google Analytics users are going to find a lot of this familiar. In fact, we’ve made a point of keeping the interface as familiar as possible.

First, get your tracker object, and initialize it using the UA code for the Analytics profile you want to track. It makes the most sense to do this in theonCreate() method for your activity main, so it only fires when your application starts up.

GoogleAnalyticsTracker tracker;
protected void onCreate(Bundle savedInstanceState) {
  ...
  tracker = GoogleAnalyticsTracker.getInstance();
  tracker.start(“UA-1234-1”, this);
  
}

The mobile SDK provides support for the 3 main types of data sent to the Google Analytics servers: Pageviews, events, and custom variables.

Pageviews

A pageview is a standard means to measure traffic volume to a traditional website. Given that this is going into an Android app and not a website, it’s going to be up to you to decide what a “pageview” means. Depending on the type of app, each Activity or different views within the same activity (for instance, different tabs within a TabActivity) could count as a pageview.

Whenever you want to trigger a pageview, call the trackPageView() method. It only takes one parameter, the URL you want a pageview counted towards.

tracker.trackPageView("/HomeScreen");

Pageviews make the most sense as full screen transitions, which in most cases will mean “one pageview per Activity.” Therefor it makes the most sense to put the call to trackPageView in the onCreate() method for each activity in your application. An exception would be if you were using a TabActivity, or other scenario where there were multiple full-screen transitions which all occurred within the same Activity, and conceptually mapped to seperate full-screen “pages” being viewed.

Events

In Analytics, events are designed to track user interaction to that doesn’t map to pageviews, like hitting play/pause/stop in a multimedia app. This maps very well to Android usage — Any form of interaction, from hitting certain buttons to adding/removing data from the datastore, can be tracked using Events.

Events are a little more complicated than pageviews, but just slightly. Instead of 1 parameter, you have 4: Category, Action, Label (optional), Value (optional).

To see how to make use of these, let’s imagine you had a media player application, and wanted to track how many times play, pause, and stop were clicked. The code would look like this:

   playButton.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View v) {
     ...
       tracker.trackEvent(
           "Media Player",  // Category
           "Click",  // Action
           "Play", // Label
           0);       // Value
     }
   });

   pauseButton.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View v) {
     ...
       tracker.trackEvent(
           "Media Player",  // Category
           "Click",  // Action
           "Pause", // Label
           0);       // Value      
   });

   stopEventButton.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View v) {
     ...
       tracker.trackEvent(
           "Media Player",  // Category
           "Click",  // Action
           "Stop", // Label
           currentVideo.getPositionInSeconds());       // Value      
   });

   myMediaPlayer.setFinishedListener(new FinishedListener() {
     @Override
     public void onFinished(View v) {
     ...
       tracker.trackEvent(
           "Media Player",  // Category
           "Video Finished",  // Action
           "Stop", // Label
           currentVideo.getLengthInSeconds());       // Value      
   });

Remember that in the Google Analytics web interface, this data is displayed hierarchically — For instance, if you click on Categories in the left nav, and then on “Media Player”, you’ll see a list of all the different possible values of “Action” which have happened in the “media Player” category. Clicking on “Click” will show all the labels which were sent in the Media Player category with an action of “Click”.

The 4th parameter, “value”, is optional, and behaves differently from the others. It’s meant to be cumulative; In this example, I’m sending the amount of video watched when a video is either stopped or allowed to finish. This is aggregated server-side, and when I go to look at my data I’ll be able to see the total time people have spent watching videos using my application.

Custom Variables

The new hotness! Custom variables are name-value pair tags that you can insert in your tracking code in order to refine Google Analytics tracking. The easiest way to think of this is as meta-data accompanying your pageviews and events. Using this metadata, it becomes easy to split off and look at segments of your data, much the same way you use labels in Gmail. One Android-specific example would be to have a “AppType” status with “Full” or “Lite” depending on whether the user has the full version of the app or not. You could then use the Analytics web interface to look at only the “Lite” users, and see how their usage / userbase differs from the “Full” segment. Custom variables are a ridiculously powerful analytical tool, but they’re also a deep topic. I heartily recommend giving the docs a once-through before implementing them in your Android application. Especially make sure to read the section on scoping. Twice. I’m mean it… I’ll wait.

There are 4 parameters in a custom variable: Index (1 to 5 inclusive), Name, Value, and Scope (Optional, defaults to Page Scope).

The place in your code where setCustomVar() will be called depends largely on what scope that variable will be:

  • Visitor scope: Call once the first time your application is run on a device. Don’t create any custom variables at the same index, or they will overwrite the first one. Useful for sending data about which version of the app is being used, what kind of phone, lite vs full version of the app, or anything that won’t change during the lifetime of the installation of that application.

  • Session scope: Call once at the beginning of every Activity startup. Will apply to all pageviews and events for the lifecycle of the activity, unless a different custom variable is created at the same index.

  • Page scope: Call right before trackEvent or trackPageView that the custom variable should apply to, every time that method is called. If no scope is specified, this is the default.

The call to set a custom variable will look like the following:

// Scopes are encoded to integers:  Visitor=1, Session=2, Page=3
tracker.setCustomVar(1, "Navigation type", "Button click", 3);

Choose a Dispatch Mode

In order to optimize for battery life, a request isn’t actually sent out to the server every time you fire a pageview or custom variable. Instead, all the pageviews, events, and their associated custom variables are stored in a local SQLITE database until they’re dispatched as a group to the server. You can set this up to happen one of two ways: Either have the dispatch occur automatically every n seconds, or manually when you call “dispatch” in code. The mode is chosen when you call the start method on your tracker.

Manual dispatch looks like this:

// No time increment sent as a parameter
tracker.start(“UA-1234-1”, this);

// Call this when you want to send the entire event queue to the server
tracker.dispatch();

The timed automatic dispatch looks similar, but sends an extra parameter (the number of seconds between dispatches). In timed dispatch, you never have to manually call dispatch.

// Dispatch all queued pagevies/events every 300 seconds (5 minutes)
tracker.start("UA-YOUR-ACCOUNT-HERE", 300, this);

It’s important to remember that Google Analytics uses the timestamp for when it receives your data, not when the actual pageview/event occurred. This can potentially lead to inaccurate Analytics data, since events can be sent on different days than when they occurred, so take care to dispatch regularly.

The end result

Let’s go back to that onCreate() method we used to instantiate the tracker earlier, and see what it looks like with all the pieces in place:

GoogleAnalyticsTracker tracker;

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

tracker = GoogleAnalyticsTracker.getInstance();
tracker.start(“UA-1234-1”, this);

if(isFirstTimeRunningApplication()) {
 tracker.setCustomVar(1, App Type”, Demo”, 1);
}
tracker.trackPageView("/HomeScreen");


}

How to look at all this data

There are two ways you can approach this. First, Google Analytics has a pretty snazzy web interface, which does a very good job of surfacing useful information for you. If you’re new to Analytics and don’t really know what you’re looking for yet, the web interface is a great way to explore your data and understand your users.

If you already have a strong idea of the questions you want to ask (app usage across versions of the Android platform, growth rates, time-in-app per demo user vs full user, how many people beat level 3 on their first try, etc), and just want to automate the asking, Google Analytics also has a swanky data export API, with client libraries to facilitate the querying of your data in Java, Python, JavaScript, and C#.

Abiding by the TOS

Google Analytics comes with its own TOS, and it’s important to read and abide by it. The important bit, especially since this will be used inside Android applications, is that you cannot send personally identifying information to Analytics servers. This is a big deal. It means, for instance, that a visitor-level custom variable cannot contain a phone number, first name, or email address. Less intuitively, but still important, it means that if this application is a client to a web application (say, CRM software or a shopping site), you also cannot store information in Analytics which can be combined with your own backend software to identify the user, such as user ID or a transaction ID identical to the one stored on your web backend.

Nexus One 2.2.1 root教程

2010年10月26日

1.下载rootfiles,并解压到D盘的files目录中
2.下载adb并安装
3.点开始,运行,输入CMD,回车,出来的控制台窗口里输入:

adb push d:\files\rootnow /data/local/tmp/rootnow
adb shell chmod 700 /data/local/tmp/rootnow

4.这时我们要切到系统的shell里,继续输入:

adb shell
cd /data/local/tmp
./rootnow

5.这时候你可以看到一大堆信息出现在你的控制台窗口里了,并且ADB会自动重启。
接下来输入:

adb kill-server
adb start-server

再次输入:adb shell

6.这时候你可以看到原本命令行最左边的的美元号$变成了#,这时候就代表已经root了,如果没成功就重复4和5。还没完,别急着离开,还有第二部分,你需要安装守护程序。

输入:exit
关闭shell

7.关掉控制台窗口,再次 点开始,运行,输入CMD,回车,出来的控制台窗口里输入(直接从这里复制吧,右键点击控制台的窗口栏就可以/编辑/粘贴了,记得是一行一行地来,每次粘贴后都要回车一下):

adb push d:\files\superuser.apk /data/local/tmp/superuser.apk
adb push d:\files\su /data/local/tmp/su
adb push d:\files\busybox /data/local/tmp/busybox
adb shell
cd /data/local/tmp/
chmod 755 busybox
./busybox mount -o remount,rw /dev/block/mtdblock3 /system
./busybox cp busybox /system/bin
chmod 4755 /system/bin/busybox
busybox cp superuser.apk /system/app
busybox cp su /system/bin
chmod 4755 /system/bin/su

好了,现在已经root成功了!

转自 机锋网

Google Voice 激活方法

2010年10月17日

前提条件: 一个可使用的Gmail帐号,并从未激活过Google Voice

步骤如下:

1.首先,你需要在Nonoh.net注册一个帐号并通过邮件激活,然后下载nonoh客户端(用于接听Google Voice拨打过来的电话,并输入校验码[两位数字]). 注册流程很简单,不详细介绍.

2.注册IPKall帐号,注册信息见截图,注册成功后收邮件会告诉你一个十位的电话号码 (Your IPKall phone number is: xxx-xxx-xxxx)IPKall

SIP Phone number: 输入你注册nonoh时的帐号名

SIP Proxy: sip.nonoh.net  (这是nonoh SPI代理服务器地址)

Email Address: 输入你注册nonoh时的邮箱地址

Password: 输入你注册nonoh时的密码

未说明的选项都为默认,请不要修改

3.访问Google Voice服务,进行激活(一共需要4步)

3.1.根据个人喜好选择一个你喜欢的电话号码(区号部分可选择520或510)

3.2.输入你的4位数字PIN,任意数字都可以,但需要牢记,以后要用到

3.3.转移号码 Phone Number,为IPKall的那个十位电话号码

3.4.点击Call Me now,并在nonoh客户端接听电话,输入两位数字校验码(切记检查nonoh是否启动,并在logged on状态),校验通过即完成

4.享受Google Voice给你带来的乐趣吧!

详细步骤参考 http://passtest.net/2010/07/google-voice-how-to-use 或 页面截图

如何在Android虚拟机里使用Google Market(Android 1.6)

2010年10月12日

1.安装Android虚拟机, 就不多说了.

2.检查虚拟机里是否下载了Android SDK Platform 1.6 (也就是Android OS 1.6),如果没有则下载

3.启动虚拟机配置工具, 创建一个新的虚拟机,Name输入test,Target选择Android 1.6 – API Level4,SD Card Size = 256M,其他默认

4.找到虚拟机配置文件目录(确认系统盘符和自己的用户目录), 例如我的是C:\Users\Emck\.android\avd

5.复制system.img到C:\Users\Emck\.android\avd\test\目录

6.启动虚拟机即可看到Google Market应用.

附件: 下载 system.img

恢复Windows 7 开机密码

2010年06月19日

忘记密码,无法登陆系统,最简单有效的修复办法

1.准备一张Ubuntu安装CD (9.04以上版本)

2.光盘启动,进入Ubuntu安装界面,选择语言后,点击试用(不需要安装)

3.等待加载完毕后,在菜单里选择Mount Windows7的系统分区(具体操作不再细讲)

4.用超级终端进入已Mount的Windows7系统分区目录,找到/Windows/System32目录

5.将目录下osk.exe修改为osk.exe.bak(命令: mv osk.exe osk.exe.bak),并将cmd.exe修改为osk.exe(命令: mv cmd.exe osk.exe)

6.关机并从硬盘启动Windows7

7.出现登录界面后,单击屏幕左下角的”轻松访问”图标,然后在弹出窗口里勾选”启动屏幕键盘”,再单击确定. 此时,就会启动一个DOS命令行窗口(这个命令行窗口,具备超级权限,后续操作就靠它了)

8.在命令行窗口里,输入net user,查看用户名,再输入 net user test newpass,修改用户test的密码为newpass

9.在登录窗口里输入新的密码,就能顺利登录到windows

10.登录成功后,重启计算机并重新进入Ubuntu,还原刚才修改osd.exe和cmd.exe(否则将无法再windows7里使用命令行工具)

备注: 请先掌握Ubuntu或Linux的基础知识,避免误操作.

2009年12月16日

常用刷机命令和方法

1. mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system

2. flash_image recovery /sdcard/recovery.img

3. cat recovery.img > /system/recovery.img

4. fastboot刷机

a) CAMERA+POWER进入手机fastboot模式

b) fastboot erase recovery

c) fastboot flash recovery recovery.img

具体用法就不多说了.

Android G1 刷Recovery简明教程

2009年12月15日

1.SD卡格式化成FAT, 复制DREAIMG.NBH拷到sd卡根目录(RC29或RC7)
2.按照相机 + 开机启动键启动手机, 刷DREAIMG.NBH,成功后重启手机
3.复制recovery.img到sd卡根目录
4.在Home中输入telnetd,启动telnet server
5.通过计算机,输入telnet x.x.x.x 连接手机,如果提示符是#号, 则root成功
6.输入命令 flash_image recovery /sdcard/recovery.img,成功后关机
7.按HOME + 开机启动键启动手机,则自动进入恢复模式.
8.大功告成!