至從更新 ADT 到某版之後,每次建立新專案都會自動蹦出一個 appcompat_v7 專案,
後來找到解決的方式,只要在建立新專案時,最低 SDK 版本 (Minimum Required SDK)
指定為 API 14(即 Android 4.0),就不會出現appcompat_v7。
2014年9月12日 星期五
2014年8月11日 星期一
How to get an unique ID from Android device?
我們有時候會想要取得一組 UID,來判斷是否為不同的 Android 裝置,除了
Java 本身提供的 UUID,是不是還有其他的方法呢?
以下整理了五種方法(Test with Sony ZL 4.4.2):
Ref: http://android-developers.blogspot.tw/2011/03/identifying-app-installations.html
Java 本身提供的 UUID,是不是還有其他的方法呢?
以下整理了五種方法(Test with Sony ZL 4.4.2):
- UUID
利用 UUID 類別的方法 randomUUID() 產生一組 128-bit 組成的 UUID:String uuid = UUID.randomUUID().toString(); Log.d(TAG, "UUID: " + uuid); // UUID: faffffe6-a504-4252-b92a-c5b555811123
- IMEI/MEID/ESN
利用 TelephonyManager 類別的方法 getDeviceId(),在 GSM 的手機上取得 IMEI 或
在 CDMA 的手機上取得 MEID 或 ESN 的值:// Required permission: android.permission.READ_PHONE_STATE TelephonyManager telManager=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); String imei = telManager.getDeviceId(); Log.d(TAG, "IMEI: " + imei); // IMEI: 3553XXXXXXXXXXX
- Android ID
取得由靜態類別 Secure 的靜態變數 ANDROID_ID 所表示的 16進位字串。String androidID = Secure.getString(this.getBaseContext().getContentResolver(), Secure.ANDROID_ID) Log.d(TAG, "Android ID: " + imei); // Android ID: 826458105eXXXXXX
Note: 有些廠商的手機的 Android ID 有重複出現的情況,而且一但使用者回復原廠設定
時,此 ID 有可能會改變。
- Wifi Mac
透過 WifiInfo 類別的方法 getMacAddress() 取得 Mac Address:// Required permission: android.permission.ACCESS_WIFI_STATE WifiManager wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); Log.d(TAG, "MacAddress: " + wifiInfo.getMacAddress()); // MacAddress: b4:XX:XX:XX:42:fc
Note: 沒有開啟 Wifi 時可能會回傳 null,但 Sony ZL 是都要的到。
- Serial
透過 Build 類別的靜態變數 SERIAL 取得手機的硬體序號:String buildSerial = android.os.Build.SERIAL; Log.d(TAG, "BuildSerial: " + buildSerial); // BuildSerial: EP7323XXXX
Note: API Level 9 以上才支援,不保證每台裝置都有。
Ref: http://android-developers.blogspot.tw/2011/03/identifying-app-installations.html
RFC 1867 - Form-based File Upload in HTML
在 RFC 1867 被提出之前,Form 的 INPUT 的類別僅有八種: CHECKBOX, HIDDEN, IMAGE,
PASSWORD, RADIO, RESET, SUBMIT, TEXT。在這之中似乎少了 FILE 可以讓使用者上傳檔
案。於是這份 RFC 便提出了兩個提案:
所以也定義了新的 MIME 類別 multipart/form-data。
當撰寫 HTML 的程式設計師想向使用者請求一或多個檔案便可以寫成:
multipart/form-data 根據表單欄位包含了許多個部分,每個部分都應帶有:
實際從 Client 端傳回 Server 端的資料如下:
如果使用者選擇了多個檔案,如多選了一個 file2.gif,則資料如下:
Ref:
PASSWORD, RADIO, RESET, SUBMIT, TEXT。在這之中似乎少了 FILE 可以讓使用者上傳檔
案。於是這份 RFC 便提出了兩個提案:
- 使 INPUT 多一個 FILE 的選項。
- 允許 INPUT 有一 ACCEPT 的屬性,指定可上傳的檔案類別。
所以也定義了新的 MIME 類別 multipart/form-data。
當撰寫 HTML 的程式設計師想向使用者請求一或多個檔案便可以寫成:
<FORM ACTION="http://server.dom/cgi/handle" ENCTYPE="multipart/form-data" METHOD=POST> What is your name? <INPUT TYPE=TEXT NAME=submitter> What files are you sending? <INPUT TYPE=FILE NAME=pics>
multipart/form-data 根據表單欄位包含了許多個部分,每個部分都應帶有:
- Header: content-disposition: form-data; name="xxxxx",name 即是該欄位在表單中的名稱。
- boundart: 自定義但不能出現在內文的的邊界字串。
實際從 Client 端傳回 Server 端的資料如下:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
content-disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x--
如果使用者選擇了多個檔案,如多選了一個 file2.gif,則資料如下:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
content-disposition: form-data; name="pics"
Content-type: multipart/mixed, boundary=BbC04y
--BbC04y
Content-disposition: attachment; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--BbC04y
Content-disposition: attachment; filename="file2.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary
...contents of file2.gif...
--BbC04y--
--AaB03x--
Ref:
2014年7月16日 星期三
[Python] 跟檔案有關的常用函式
os.path.join('c' 'folder') # 'c\\folder'
os.path.join('c:' 'folder') # 'c:folder'
# Get file name.
os.path.basename('C:\\Windows\\123.txt') # '123.txt'
# Get file path and file extension.
filePath, fileExtension = os.path.splitext('C:\\Windows\\123.txt') # 'C:\\Windows\\123', '.txt'
# Get directory path.
os.path.dirname('C:\\Windows\\123.txt') # 'C:\\Windows'
# Get modify time from epoch time.
os.path.getmtime('C:') # 1409646173.7839031
# Traverse a directory.
for root, subdirs, files in os.walk("C:\\Pictures"):
print root, subdirs, files
2014年7月4日 星期五
[Python] How to get the last day of the month
想要知道某個特定月份有幾天,可以直接呼叫 calendar.monthrange(2014, 2),
會回傳第一天是禮拜幾和該月有幾天。
範例:
會回傳第一天是禮拜幾和該月有幾天。
範例:
import calendar calendar.monthrange(2014, 2) # (5, 28) # 禮拜六,28天 calendar.monthrange(2014, 3) # (5, 31) # 禮拜六,31天 calendar.monthrange(2014, 4) # (1, 30) # 禮拜二,30天
2014年5月13日 星期二
Can's see the newly created picture in Android's default gallery.
當我們寫了一個會儲存圖片在裝置上的 APP 時,卻在開啟 Android gallery 或其他專門
瀏覽圖片的 APP 時看不到圖片,是因為系統還沒將其掃進 MediaStore,想必如果系統
不斷的掃描檔案和操作資料庫是相當耗資源與沒有效率的。所以,Android 會在每次
開機時做一次掃描,如果 APP 想要系統對某個檔案做即時的掃描,可以加上下面的
程式碼:
Ref: http://developer.android.com/reference/android/media/MediaScannerConnection.html
瀏覽圖片的 APP 時看不到圖片,是因為系統還沒將其掃進 MediaStore,想必如果系統
不斷的掃描檔案和操作資料庫是相當耗資源與沒有效率的。所以,Android 會在每次
開機時做一次掃描,如果 APP 想要系統對某個檔案做即時的掃描,可以加上下面的
程式碼:
MediaScannerConnection.scanFile(activity, new String[]{path}, null,
new MediaScannerConnection.OnScanCompletedListener() {
@Override
public void onScanCompleted(final String path, final Uri uri) {
...
}
}
);
Ref: http://developer.android.com/reference/android/media/MediaScannerConnection.html
2014年5月10日 星期六
Launch Mode for Activity
Activity 的 launch mode 可以透過 android:launchMode 來設定,總共有四種 launch mode:
- standard
這是 default 的 launch mode,Activity 每次都會建立一個新的實體。
EX1: A -> B(standard),在 B 啟動 B,A -> B -> B。
EX2: A(standard) -> B,返回上層,Activity A 會被重新建立。 - singleTop
如果當下的 Activity 在 stack 的最上面,則不會建立新的實體,反之則會。
EX1: A(singleTop) -> B -> C,在 C 啟動 A,A -> B -> C -> A。
EX2: A(singleTop) -> B,返回上層,Activity A 不會被重新建立。 - singleTask
不會建立新的實體,而且總是在 stack 中的最前頭(下層)。
(Google 說總是在 stack 中的最前頭(下層) 也不全然正確)
EX1: A -> B(singleTask) -> C -> D ,在 D 啟動 B,A -> B,C 和 D 會被移除。 - singleInstance
不會建立新的實體,而且是 stack 中唯一的 Activity。
EX1: A -> B -> C ,在 C 啟動 D(singleInstance),[A -> B -> C] -> [D]。
訂閱:
文章 (Atom)