Android: r cannot be resolved to a variable

19 November 2012

早上發生了一個很有趣的事情...
因為最近新版的Android SDK非常的雞婆!
如果一開始預設選的sdk是4.x以上,
res/底下會多了一個value-v11, value-v14住兩個資料夾,
這裡面都是放一些layout/theme!

這些layout就是根據不同的SDK version去gen出來的!
其實它的目的就是要你吃它新推出的action bar的概念!
但是如果你把project default sdk version改成2.x!
那就慘了!因為2.X SDK不認得那是什麼!!!
所以你的R.java會一直build不出來!
soloution就是把那兩個資料夾砍了!
還有一點!在layout裡面以前有一個attribute是fill_parent!
但在某個版本SDK被deprecated!改成match_parent!!!

而4.X就是用match_parent!
如果改回2.X sdk就要把match_parent改成fill_parent!



read more »


Google Analytics for Android - EasyTrack

18 November 2012

Google Analytics是一套分析工具!
最初只有WEB版才有,可以分析你的流量、人口分布、瀏覽器來源等等之類的資訊!
但現在已有了Android & iOS等其他版本,
可以利用這套API去分析使用者在你app上的使用情況.
(例如:在這個Activiy待了多久,或者做了怎樣的行為,點了哪些button等等之類的,甚至可以有exception report)


這篇主要會說明在Android上面如何使用!
在這篇會先講解簡單的EasyTrakcer的部分!
EasyTrakcer顧名思義就是很簡單的意思!
有好有壞!好的是你可以快速implement,
壞的是彈性較小!



在開始實作之前,你得先去Google Analytics上開一個project for android,
目的是為了申請一個ID !
網址:https://www.google.com/analytics/web/

進來此網站之後,會見到下圖,
(1)  請點選下圖中的New Account

圖一


(2)  接著會看到下圖,請點選“應用程式”(預設是網站)
接著就輸入自己的應用程式名

圖二

(3)  完成上述步驟以後,你就會得到自己的Google Analytics ID,
這ID要記起來!因為待會再Android

圖三




完成上述的申請以後!
(1) 接著要先去下載Google Analytics SDK (Here)

(2) 解壓縮出來

(3) 開一個Android Project

(4) 把lib include至Android Project中
     在Project中點選右鍵選擇properties
     接著會見到下圖,點選下圖中右方的紅色框框Java Build Path
     然後點選下圖中上方的紅色框框Libraries
     再點選下圖中有方紅色框框的Add External JARS...
     然後找到你剛剛下載的lib,把它加進來就好!

圖四

(5) 把剛剛include進來的jar export出來!(如下圖)







(7) 加入下列兩項permission
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />



(8) 接著在project中/res/value底下建立一個analytics.xml
內容如下:
<?xml version="1.0" encoding="utf-8" ?>

<resources>
<!--Replace ID with your tracking ID-->
<string name="ga_trackingId">UA-XXXX-Y</string>

<!-- use for debug -->
<bool name="ga_debug">true</bool>

<!--Enable Activity tracking-->
<bool name="ga_autoActivityTracking">false</bool>

</resources>


註:
ga_trackingId記得填寫自己剛剛申請的那個id
ga_debug的意思是使用debug模式,可以讓你在local端看到一些track的資訊!
如果你沒有設置這個attributes,你可能要等很久很久,你的Google Analytics後台管理頁面才會更新資訊.....
所以還是設定一下吧!
ga_autoActivityTracking這個property也很重要,如果設為true的話,在initial tracker時,tracker會自動發出一個request,這個requset就包含了device name, screen resolution, os等等之類的資訊!在這我們先設為false,一切以手動的方式進行track!

(9) 開始寫code,
private Tracker tracker  = null; // use for track event, exception..etc.
private Context cxt = null;
private int iDispatchTime = 3; // determine how long send the information to Google
private double dSampleRate = 100; // determine how much information to be send

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cxt = this;

EasyTracker.getInstance().setContext(cxt); // initial

// start a Tracker, you must to do this thing otherwise you can't send any tracker to Google.
EasyTracker.getInstance().activityStart((Activity)cxt); // Add this method.

// 取得一個tracker
tracker = EasyTracker.getTracker();

// 設定Sample Rate, sample rate用意在於如果你的app很多人使用,
// 那麼你可以自己設定有百分之幾的device資訊會被送出Google
// 這裡設定100%,也就是說所有device都會送出資訊
tracker.setSampleRate(dSampleRate);

// 設定dispatch time
// 這裡預設為3秒,也就是說每次trackEvent, trackException一次
// 都會在3秒以後送出(當然你可以手動進行dipatch)
GAServiceManager.getInstance().setDispatchPeriod(iDispatchTime);


// track event
tracker.trackEvent("UI_ACTION", "buttonClick", "labelCreatedByKen", 0l);

// track view, 追蹤這個activity使用者停留了多久之類的
tracker.trackView("trackViewHomePage");

// track exception, 這裡是手動的track exception
// 你可以把trackException放在try{}cathc(){};之中
tracker.trackException("ExceptionCreatedByKen", false);

}


完成以後你可以利用DDMS進行debug,
你可以用來看這些track(trackEvent, trackView,trackExeption)送出了那些資訊
大概會看到下面那張圖!






而在Google Analytics的後台就會看到上面送出的那些資訊!
如下圖!
trackEvent

trackView

trackExcpetion-1

trackException-2

trackException有兩張圖,因為trackException會記錄著是那個version的app發生exception的!
所以如果你有很多個version,你會在第一張圖看到很多個version,
因為這個是test app,所以目前只有一個1.0,點進去以後就會看到詳細的exception資訊了!(如第二張圖)




上面code之中有講到trackException,大家可能會有點confused,
因為如果你在開發app時,error handling做不好的時候,可能會導致app crash!
那麼屬於這邊的exception 該怎麼抓到呢?
恩!在Google Analytics也有提供這樣的功能!
只要在上面的xml檔當中加入下面的element即可!

<!--Enable automatic exception tracking-->
<bool name="ga_reportUncaughtExceptions">true</bool>


上面就是一些稍微進階的Google Analytic的使用方式!



read more »


Install Android NDK on MAC

24 October 2012

這篇主要講怎麼安裝以及使用Android NDK,
Android NDK簡單地說,就是讓您能夠在你的app當中使用C/C++進行implementation,
它可以把您寫的C/C++ build出一個share object檔案 (*.so) 讓Java call!類似windows中的dll檔!
當然你也可以在JNI call Java method,也就是說是雙向的!
而使用NDK的好處是大概有下面兩個(我只能想到這兩個..)
  1. 效能較好(depends on situation)
  2. 可以控制到底層的裝置


不過在Android官網也指出
”you should understand that the NDK will not benefit most apps“
所以使用時機要自己斟酌,但我知道蠻多game都是用NDK去implement!
因為需要太多memory,靠自己free效能會較好!



首先先講Android NDK的安裝以及使用方法!

(1) 下載
下載頁面在http://developer.android.com/tools/sdk/ndk/index.html#Downloads
請選擇符合你自己OS的版本!
(如果你使用的是windows!請先下載cygwin,至於cygwin是什麼,前面很多篇文章已經敘述過,這裡不多加敘述)

(2)解壓縮
此篇是用mac,因此就下載osx的版本吧!
下載下來以後就進行解壓縮.
基本上其實就完成了!
在NDK r4之前還需要跑一隻setup script,但之後的就不用了!

其實解壓縮之後裡面就有很多doc可以看!不過都是英文!

(3)建立jni資料夾
在你的$project/底下建立一個jni資料夾!如下:
$project/jni

(4)撰寫C/C++
在$project/jni底下開始寫C/C++的code了!
先建立一個檔案叫做test-jni.c,
內容如下:
#include <string.h>
#include <jni.h>

jstring
Java_net_kenyang_jni_RunJNI_getText( JNIEnv* env,
jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
jstring是return type
Java_net_kenyang_jni_RunJNI_getText是這個method的命名規則!
這是JNI的規則,所以請遵守!

開頭一律Java_自己的package名稱_Class名稱_method名稱
你可以改成自己的!但記得後面的步驟也要記得改!



(5)建立Android.mk
一樣在$project/jni底下建立Android.mk檔案
Android.mk這個檔案是用來告訴NDK等等要去build哪些resource!
而我們目前只有一隻test-jni.c,所以檔案內容如下:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := test-jni
LOCAL_SRC_FILES := test-jni.c

include $(BUILD_SHARED_LIBRARY)




(6)開始build *.so檔案
先開啓你的terminate,然後cd到$project/jni底下
直接在該目錄底下用NDK的tool進行build!
這樣就會產生一個.so檔!
這個檔案會放在$project/lib/armeabi底下!
檔名一定會是lib開頭,.so結尾!
也就是說在這個範例build出來的.so檔案名稱為libtest-jni.so

而build指令如下:
cd xxx/project/jni
xxx/ndk/ndk-build




(7)開始寫code
在你的android project中直接建立一個activity(名稱為RunJNI)
我們將在這個activity中進行呼叫剛剛用c建立的method,
CODE如下:
public class RunJNI extends Activity {
// 宣告一個native method(就是剛剛用c寫的)
private native String getText();

// 載入剛剛的.so檔案!(這裡不需要加上lib,直接去掉就好
static {
System.loadLibrary("test-jni");
}


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.run_jni);

TextView tv = (TextView) findViewById(R.id.textView1);

// 呼叫method,把method回傳的字給textView進行設定
tv.setText(getText());

}
}



完成上面7個步驟就完成了!
直接點選run應該就可以看到下面畫面! 











      

read more »