顯示具有 Android App 開發筆記 標籤的文章。 顯示所有文章
顯示具有 Android App 開發筆記 標籤的文章。 顯示所有文章

2014/04/06

android app開發 環境建置

1. 下載SDK, 解壓縮

2. 下載eclipse IDE for Java Developers, 解壓縮

3. 安裝JDK, 設定環境變數.
變數名稱:java_home
變數值: c:\program files\java

4.SDK Tools 安裝,(建議安裝最新版本)

5. 在eclipse設定 ADT plugin , 此時會判斷 SDK tools 的版本是否最新.
會建議要求更新..

6. 指定SDK的位置
eclipse > windows > preferences > android

7. 開啟android SDK manager 安裝軟體.

2013/02/03

Android - Handler activity設定時間後自動跳到另一activity

如何讓 Activity 執行後,可以在一定時間後自動跳到另一個 Activity。
這樣的想法可以使用 Handler 來完成這樣的工作。

我的想法是,當程式執行後先顯示 App 的 Logo 在跳到要使用的功能。

Layout.xml
1. main.xml
2. second.xml

Activity
1. MainActivity.java
2. Second.java

範例:
執行程式時,先執行 MainActivity.java。過了五秒後,自動跳轉到 second.java




MainActivity.java
package com.example.intent5sed;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.Intent;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                final Intent mainIntent = new Intent(MainActivity.this, Second.class);
                startActivity(mainIntent);
                finish();        // 當跳到另一 Activity 時,讓 MainActivity 結束。
                                // 這樣可以避免使用者按 back 後,又回到該 activity。
            }
        }, 5000);    
    }
}


Second.java
package com.example.intent5sed;

import android.app.Activity;
import android.os.Bundle;

public class Second extends Activity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);
    }
}



提醒:新增新的 class 別忘了到 AndroidManifest.xml 做適當的修改。

2013/01/05

Android - DatePicker:如何取得"日期"的資料


資料取得上,除一般透過輸入的資料外,也常會使用到時間的紀錄。
而時間的取得就可以透過 TimePicker 或 DatePicker 來即時取的當下的時間。
當然這時間可以再另做設定,只是透過這樣的方法,使用者在輸入資料的時候。
可以避免資料的輸入手誤或錯誤等等。

範例:
軟體一開啟時,使用 Calendar 取得當下的年月日,並顯示在textDate1。
之後更改 Datepicker 顯示的年月日,系統會觸發 OnDateChangedListener,
產生出年月日三個數值是,由於這數值屬性為 int,所以我們另用 DateFix 方法將時間更改為 String。
當然若數字小於 10 ,在數字前面我們就多加個 0。
將取得字串在設定到 TextView1。
另外,透過Button取得 DatePicker 送出來的資料,顯示在另一個 另一個 textDate2 上。


圖示:




main_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Date" >

    <DatePicker
        android:id="@+id/DatePicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/textData1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text" />

    <Button
        android:id="@+id/BtnGetDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="63dp"
        android:text="取得日期" />

    <TextView
        android:id="@+id/textData2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text" />

</LinearLayout>

date.java
package com.data;

import java.util.Calendar;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;


import android.widget.TextView;

public class Date extends Activity {

    String Year,Mon,Day;
    private DatePicker DatePicker;
    private TextView textData1;
    private TextView textData2;
    private Button BtnGetDate;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);
        
        Calendar TodayDate = Calendar.getInstance();    //透過Calendar取的資料
        int sYear = TodayDate.get(Calendar.YEAR);       //一開啟軟體即取得年的數值
        int sMon  = TodayDate.get(Calendar.MONTH) + 1;  //一開啟軟體即取得月的數值
                                                        //月的起始是0,所以+1.
        int sDay = TodayDate.get(Calendar.DAY_OF_MONTH);//一開啟軟體即取得日的數值
        //將取得的數字轉成String.
        Year = DateFix(sYear);    
        Mon  = DateFix(sMon);
        Day  = DateFix(sDay);
        
        textData1     = (TextView)findViewById(R.id.textData1);
        textData2    = (TextView)findViewById(R.id.textData2);
        BtnGetDate    = (Button)findViewById(R.id.BtnGetDate);
        //一開始就將年月日寫入 textDate1
        textData1.setText( Year + "/" + Mon + "/" + Day );
        
        BtnGetDate.setOnClickListener(GDListener);
        
        DatePicker     = (DatePicker)findViewById(R.id.DatePicker);        
        DatePicker.init(TodayDate.get(Calendar.YEAR),TodayDate.get(Calendar.MONTH),
                        TodayDate.get(Calendar.DAY_OF_MONTH),    
        //DatePicker年月日更改後,會觸發作以下的事情。
        new DatePicker.OnDateChangedListener() {
            @Override
            public void onDateChanged(DatePicker view, int year, int monthOfYear, 
                    int dayOfMonth) {
                Year = DateFix(year);
                Mon  = DateFix(monthOfYear + 1); //月的初始是0,所以先加 1。
                Day  = DateFix(dayOfMonth);
                textData1.setText( Year + "/"+Mon+"/"+Day);
            }
        });   
    }  
    
    //按下Button,將年月日的值,設定到 textData2
    private Button.OnClickListener GDListener = new Button.OnClickListener(){

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            textData2.setText(Year+"/"+Mon+"/"+Day);
        }
    };        
    //方法DateFix:將傳送進來的年月日轉成String,在判斷是否前面需要加0。
    private static String DateFix(int c){
        if (c >= 10)
            return String.valueOf(c);
        else
            return "0" + String.valueOf(c);
    }
}

2013/01/04

Android - TimePicker:如何取得時間的資料

資料取得上,除一般透過輸入的資料外,也常會使用到時間的紀錄。
而時間的取得就可以透過TimePicker來即時取的當下的時間。
當然這時間可以再另做設定,只是透過這樣的方法,使用者在輸入資料的時候。
可以避免資料的輸入手誤或錯誤等等。

範例:
使用 Timepicker 顯示的時間,當我們更改時間即會觸發 setOnTimeChangedListener。
產生出來的數值是 int,所以我們另用 TimeFix 將時間更改為 String。
當然若數字小於 10 ,在數字前面我們就多加個 0。
將取得字串在設定到 TextView1。
另外,透過Button取得 TimePicker 送出來的資料,顯示在另一個 TextView 上。

圖示:一個是在 Android 2.3的樣式,一個是 4.1 的樣式。

main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Time" >

    <TimePicker
        android:id="@+id/timePicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" />

    <Button
        android:id="@+id/BtnGetTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textTime1"
        android:layout_marginTop="31dp"
        android:text="Button" />

    <TextView
        android:id="@+id/textTime1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/timePicker"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/textTime2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/BtnGetTime"
        android:layout_toRightOf="@+id/BtnGetTime"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

time.java
package com.example.time;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.TimePicker.OnTimeChangedListener;

public class Time extends Activity {
    private TimePicker timePicker;
    private TextView textTime1,textTime2;
    private Button     BtnGetTime;
    String H;
    String M;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);
        
        textTime1    =    (TextView)findViewById(R.id.textTime1);        //自動取得時間
        textTime2    =    (TextView)findViewById(R.id.textTime2);        //透過按鈕取得時間
        BtnGetTime   =    (Button)findViewById(R.id.BtnGetTime);
        BtnGetTime.setOnClickListener(GTimeListener);
        
        timePicker    =    (TimePicker)findViewById(R.id.timePicker);
        //timepicker時間更改時,執行下面的動作。
        timePicker.setOnTimeChangedListener(new OnTimeChangedListener(){
            @Override
            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
                // TODO Auto-generated method stub
                //取得 hour的值,透過TimeFix方法。轉換成String.並初始H。
                H = TimeFix(hourOfDay);
                //取得 minute的值,透過TimeFix方法。轉換成String.並初始M。
                M = TimeFix(minute);
                //將取得的資料設定到 textTime1
                textTime1.setText(H + ":" +M);
            }
        });
    }
    
    private Button.OnClickListener GTimeListener = 
            new Button.OnClickListener(){
        //按下按鈕後將先前Timepicker取得的值 H和M,
        //設定到 textTime2
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            switch (v.getId())
            {
                case R.id.BtnGetTime:
                {
                    textTime2.setText(H + ":" +M);
                    break;
                }
            }
        }
    };
        
    //Timepicker取得的資料為int,但時間數字小於10,是不會有像06這樣的情況。
    //所以透過TimeFix這個方法將送過來的數字轉換成String,在判斷是否需要加0。
    private static String TimeFix(int c){
        if (c >= 10)
            return String.valueOf(c);
        else
            return "0" + String.valueOf(c);
    }    
}

Blog 圖片大小 寬600像素

Blog 圖片大小 寬600像素

2012/09/26

android app的程式檔案特性與敘述


AndroidManifest.xml
The manifest file describes the fundamental characteristics of the app and defines each of its components. You'll learn about various declarations in this file as you read more training classes.
manifest file敘述了app的基本特性並定義每一個元件。
src/
Directory for your app's main source files. By default, it includes an Activity class that runs when your app is launched using the app icon.
該資料夾有app的主要來源檔案。預設下,包含了當app透過icon被執行所需要的 Activity 宣告。
res/
Contains several sub-directories for app resources. Here are just a few:
包含了一些app resources的子資料夾. 如下
drawable-hdpi/
Directory for drawable objects (such as bitmaps) that are designed for high-density (hdpi) screens. Other drawable directories contain assets designed for other screen densities.
layout/
Directory for files that define your app's user interface.
定義app的使用者介面。
values/
Directory for other various XML files that contain a collection of resources, such as string and color definitions.
該資料夾針對不同的XML檔案( 包含了資源的聚集,比如string, 顏色的定義),
When you build and run the default Android app, the default Activity class starts and loads a layout file that says "Hello World." The result is nothing exciting, but it's important that you understand how to run your app before you start developing.
當建立和執行預設的 Android app,預設的Activity class 會開始讀取一個 layout 檔( 輸出 Hello World.)。
結果或許沒那麼令人興奮,但這對於了解程式開發是很重要的。


資料來源
http://developer.android.com/training/basics/firstapp/running-app.html

2012/09/20

AVD - android虛擬機的 SD Card,上傳下載檔案


android 虛擬機的SD Card位置在
%ANDROID_SDK_HOME%\.android\avd\"android虛擬機名稱資料夾"\sdcard.img

adb指行路徑
C:\Users\user\AppData\Local\Android\android-sdk\platform-tools


  • 上傳檔案


進入命令提示字元,並到 android虛擬機 的資料夾。
%ANDROID_SDK_HOME%\.android\avd\2.3.3.avd>adb push d:\android-test\pic.jpg /sdcard/pic.jpg
63 KB/s (606196 bytes in 9.369s)

%ANDROID_SDK_HOME%\.android\avd\2.3.3.avd>adb shell      #進入 android虛擬機的console畫面
# cd sdcard
# pwd
pwd
/mnt/sdcard
# ls
ls
LOST.DIR
Android
sd
DCIM
pic.jpg                                #可以看到上傳上來的pic.jpg
# exit
exit

d:\My Documents\user\.android\avd\2.3.3.avd>


  • 下載檔案


%ANDROID_SDK_HOME%\.android\avd\2.3.3.avd>adb pull /sdcard/pic.jpg .     #將pic.jpg下載到現行的目錄
58 KB/s (606196 bytes in 10.147s)

d:\My Documents\user\.android\avd\2.3.3.avd>dir pic.jpg
 磁碟區 D 中的磁碟是 新增磁碟區
 磁碟區序號:  284B-45B5

 d:\My Documents\user\.android\avd\2.3.3.avd 的目錄

2012/09/20  下午 02:43           606,196 pic.jpg
               1 個檔案         606,196 位元組
               0 個目錄  293,739,872,256 位元組可用

d:\My Documents\user\.android\avd\2.3.3.avd>





2012/09/19

AVD - 如何安裝 .apk 檔到 android虛擬機


將要安裝的apk檔放到如下位置:
C:\Users\user\AppData\Local\Android\android-sdk\platform-tools\

執行如下指令:
C:\Users\user\AppData\Local\Android\android-sdk\platform-tools\adb -s emulator-"執行序號" install filename.apk      #指定安裝到特定的VM

ex :
d:\Android_Developments>adb -s emulator-5554 install test.apk
74 KB/s (76025 bytes in 0.999s)
        pkg: /data/local/tmp/test.apk
Success

執行序號如下圖紅框的數字。


======================================================
adb執行檔的路經,事先我已設定到環境變數的path。
所以我可以直接在 apk檔的位置直接安裝。
這樣可以省去 apk 搬來搬去的麻煩。

AVD - 快速更改 android虛擬機的螢幕


#emulator -avd "vm-name" -skin WVGA854
執行後,會VM會自動開啟一個新的,並套用新的skin。

-skin 參數可以參考如下的內容
http://maksim28.blogspot.tw/2012/09/avd-id.html

AVD - id 與系統版本的對應平台


可以透過指令來確認  #android list target 可以顯示id 相對應的版本平台.
依經驗,不同的SDK對應會略有不同,所以可以透過指令來確認。

C:\Users\user\AppData\Local\Android\android-sdk\tools>android list targets
Available Android targets:
----------
id: 1 or "android-8"
     Name: Android 2.2
     Type: Platform
     API level: 8
     Revision: 3
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WVGA800 (default), WVGA854
     ABIs : armeabi
----------
id: 2 or "Google Inc.:Google APIs:8"
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 2
     Description: Android + Google APIs
     Based on Android 2.2 (API level 8)
     Libraries:
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: WVGA854, WQVGA400, HVGA, WQVGA432, WVGA800 (default), QVGA
     ABIs : armeabi
----------
id: 3 or "KYOCERA Corporation:DTS Add-On:8"
     Name: DTS Add-On
     Type: Add-On
     Vendor: KYOCERA Corporation
     Revision: 1
     Description: DTS Add-On
     Based on Android 2.2 (API level 8)
     Libraries:
      * com.kyocera.dualscreen (dualscreen.jar)
          Dual Screen optional platform library
     Skins: DTS400 (default), WVGA854, WQVGA400, HVGA, DTS800, WQVGA432, WVGA800, QVGA
     ABIs : armeabi
----------
id: 4 or "LGE:Real3D Add-On:8"
     Name: Real3D Add-On
     Type: Add-On
     Vendor: LGE
     Revision: 1
     Description: Real3D add-on
     Based on Android 2.2 (API level 8)
     Libraries:
      * com.lge.real3d (real3d.jar)
          Real3D library
     Skins: WVGA854, WQVGA400, Optimus3D (default), HVGA, WQVGA432, WVGA800, QVGA
     ABIs : armeabi
----------
id: 5 or "Samsung Electronics Co., Ltd.:GALAXY Tab Addon:8"
     Name: GALAXY Tab Addon
     Type: Add-On
     Vendor: Samsung Electronics Co., Ltd.
     Revision: 1
     Based on Android 2.2 (API level 8)
     Skins: WVGA854, WQVGA400, GALAXY Tab (default), HVGA, WQVGA432, WVGA800, QVGA
     ABIs : armeabi
----------
id: 6 or "android-10"
     Name: Android 2.3.3
     Type: Platform
     API level: 10
     Revision: 2
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WVGA800 (default), WVGA854
     ABIs : armeabi
----------
id: 7 or "Google Inc.:Google APIs:10"
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 2
     Description: Android + Google APIs
     Based on Android 2.3.3 (API level 10)
     Libraries:
      * com.android.future.usb.accessory (usb.jar)
          API for USB Accessories
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: WVGA854, WQVGA400, HVGA, WQVGA432, WVGA800 (default), QVGA
     ABIs : armeabi
----------
id: 8 or "Intel Corporation:Intel Atom x86 System Image:10"
     Name: Intel Atom x86 System Image
     Type: Add-On
     Vendor: Intel Corporation
     Revision: 1
     Description: Intel Atom x86 System Image
     Based on Android 2.3.3 (API level 10)
     Skins: WVGA854, WQVGA400, HVGA, WQVGA432, WVGA800 (default), QVGA
     ABIs : x86
----------
id: 9 or "KYOCERA Corporation:DTS Add-On:10"
     Name: DTS Add-On
     Type: Add-On
     Vendor: KYOCERA Corporation
     Revision: 1
     Description: DTS Add-On
     Based on Android 2.3.3 (API level 10)
     Libraries:
      * com.kyocera.dualscreen (dualscreen.jar)
          Dual Screen optional platform library
     Skins: DTS400 (default), WVGA854, WQVGA400, HVGA, DTS800, WQVGA432, WVGA800, QVGA
     ABIs : armeabi
----------
id: 10 or "LGE:Real3D Add-On:10"
     Name: Real3D Add-On
     Type: Add-On
     Vendor: LGE
     Revision: 1
     Description: Real3D add-on
     Based on Android 2.3.3 (API level 10)
     Libraries:
      * com.lge.real3d (real3d.jar)
          Real3D library
     Skins: WVGA854, WQVGA400, Optimus3D (default), HVGA, WQVGA432, WVGA800, QVGA
     ABIs : armeabi
----------
id: 11 or "android-15"
     Name: Android 4.0.3
     Type: Platform
     API level: 15
     Revision: 3
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800
     ABIs : armeabi-v7a, mips, x86
----------
id: 12 or "Google Inc.:Google APIs:15"
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 2
     Description: Android + Google APIs
     Based on Android 4.0.3 (API level 15)
     Libraries:
      * com.google.android.media.effects (effects.jar)
          Collection of video effects
      * com.android.future.usb.accessory (usb.jar)
          API for USB Accessories
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: WVGA854, WQVGA400, WSVGA, WXGA720, HVGA, WQVGA432, WVGA800 (default), QVGA, WXGA800
     ABIs : armeabi-v7a
----------
id: 13 or "Motorola Mobility, LLC.:ICS_R2:15"
     Name: ICS_R2
     Type: Add-On
     Vendor: Motorola Mobility, LLC.
     Revision: 2
     Description: Android 4.0.4 phone
     Based on Android 4.0.3 (API level 15)
     Skins: WVGA854, WQVGA400, WSVGA, WXGA720, HVGA, ATRIX-HD (default), WQVGA432, WVGA800, QVGA, WXGA800
     ABIs : armeabi-v7a
----------
id: 14 or "android-16"
     Name: Android 4.1
     Type: Platform
     API level: 16
     Revision: 2
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
     ABIs : armeabi-v7a, mips, x86
----------
id: 15 or "Google Inc.:Google APIs:16"
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 2
     Description: Android + Google APIs
     Based on Android 4.1 (API level 16)
     Libraries:
      * com.google.android.media.effects (effects.jar)
          Collection of video effects
      * com.android.future.usb.accessory (usb.jar)
          API for USB Accessories
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: WVGA854, WQVGA400, WSVGA, WXGA800-7in, WXGA720, HVGA, WQVGA432, WVGA800 (default), QVGA, WXGA800
     ABIs : armeabi-v7a

C:\Users\user\AppData\Local\Android\android-sdk\tools>

AVD - 如何產生新的 Android 虛擬機


C:\Users\user\AppData\Local\Android\android-sdk\tools>android create avd -n test -t 1
Auto-selecting single ABI armeabi
Android 2.2 is a basic Android platform.
Do you wish to create a custom hardware profile [no]no  #不客製化#
Created AVD 'test' based on Android 2.2, ARM (armeabi) processor,
with the following hardware config:
hw.lcd.density=240
vm.heapSize=24

C:\Users\user\AppData\Local\Android\android-sdk\tools>

android 指令
參數入下:
create : 產生新的VM.
-n : VM的名字.
-t : 指定開發平台的版本.

2012/09/17

啟動AVD PANIC: Could not open: C:\Documents and Settings\Administrator\.android/avd/vm.ini

啟動 AVD的VM發生如下的訊息
PANIC: Could not open: C:\Documents and Settings\Administrator\.android/avd/vm.ini

但是我的VM位置是在 D:\My Documents\user\.android\avd
此時我需要該更環境參數,讓AVD的位置指到正確的地方去才行

境變數的設定
開始 > 電腦 (按右鍵) > 內容 > 進階系統設定.

















進入系統內容,選擇頁籤 ( 進階) ,點選在該頁籤最下面的"環境變數"。
於使用者變數那新增一個變數,點選新增。
變數名稱:ANDROID_SDK_HOME
變數值:D:\My Documents\user










設定完成後,重新啟動AVD Manager。