2010年2月21日星期日

Androidology - Android平台概覽系列.

第1部分, Android系統架構概述.


第2部分, 通過不同的應用程序, 解釋應用程序(application)和進程(process)的生命週期(lifecycle).


第3部分, 概述幾個Android 2.0平台上可用API.




2010年2月20日星期六

Android 2.0服務應用程序接口(Service API)的變更

Android 2.0在服務應用程序接口(Service API)中,引入了一些對於開發人員和用戶的變更, 其主要為:

* 不推薦(deprecated)使用Service.setForeground(), 在2.0中不執行任何操作.
* 在2.0以前, 很容易意外地離開服務; 新的2.0應用程序接口使其更容易處理.
* Android 2.0還為用戶引入了一個新的用戶界面, 監控和管理正在運行中的服務.

詳情>>>



2010年2月16日星期二

2009 Google 開發者日

2009 Google 開發者日: 頭三場
2009年4月6日

Google 開發者日這個在全球各地舉行的開發者活動回來了!和去年一樣,Google為有經驗的程式師設計了這些活動,以討論Google的 API、開發者工具和應用。

Google會在以下城市舉辦開發者日活動:中國北京(6 月5日)、日本東京(6月9日)和巴西聖保羅(6月29日);如果您在美國,Google鼓勵您來參加5月27號至28號在舊金山舉行的 Google I/O。

詳情請見 Google Code 部落格

2010年2月12日星期五

startActivityForResult 和 onActivityResult

上兩篇文章"活動(activity)和意圖(intent)"和"包裹(Bundle)"使用startActivity(Intent)啟動另一項新活動, 原本的活動不會收到任何有關新活動退出時的信息. 這篇文章使用startActivityForResult(Intent, int)啟動新活動, 並重寫onActivityResult(int, int, Intent)方法. 當該新活動退出時, 會回調onActivityResult(int, int, Intent)方法.



修改主佈局(main.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Your Name?"
/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/inamefield"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Launch Activity2"
android:id="@+id/launchbutton"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id = "@+id/phonenumber"
android:text=""
/>
</LinearLayout>


修改主活動代碼:
package com.AndroidIntent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class AndroidIntent extends Activity {

int REQUEST_CODE = 0;
TextView phoneNumber;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button launchButton = (Button)findViewById(R.id.launchbutton);
final EditText iNameField = (EditText)findViewById(R.id.inamefield);
phoneNumber = (TextView)findViewById(R.id.phonenumber);
launchButton.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent newIntent = new Intent(AndroidIntent.this, Activity2.class);
newIntent.putExtra("name", iNameField.getText().toString());

startActivityForResult(newIntent, REQUEST_CODE);
}});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);

if(requestCode == REQUEST_CODE){
if(resultCode==RESULT_OK){
Bundle extras = data.getExtras();
if (extras != null){
phoneNumber.setText("Phone #: " + extras.getString("phonenumber"));
}
}
}
}
}


修改layout2.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="It's Activity2"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/onamefield"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="what's your phone number?"
/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/phonenumberfield"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="OK"
android:id="@+id/okbutton"
/>
</LinearLayout>


修改Activity2代碼:
package com.AndroidIntent;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;


public class Activity2 extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.layout2);
TextView oNameField = (TextView)findViewById(R.id.onamefield);
final EditText phoneNumber = (EditText)findViewById(R.id.phonenumberfield);
Button okButton = (Button)findViewById(R.id.okbutton);

Bundle extras = getIntent().getExtras();
oNameField.setText("Hello " + extras.getString("name"));

okButton.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Bundle bundle = new Bundle();
bundle.putString("phonenumber", phoneNumber.getText().toString());
Intent intent = new Intent();
intent.putExtras(bundle);
setResult(RESULT_OK, intent);
finish();
}});
}
}
記住, 需要修改清單文件(AndroidManifest.xml)加入ctivity2, 參考"活動(activity)和意圖(intent)".

2010年2月8日星期一

包裹(Bundle)

包裹(Bundle)

包裹(Bundle)是字符串值(String value)對各種可包裹類型的映射(Mapping). 在活動(Activity)之間的數據傳遞就往往用上包裹(Bundle).

修改變先前的應用程序"活動(activity)和意圖(intent)", 以使用包裹傳遞數據.



修改主佈局(main.xml), 添加一個編輯文本(EditText).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Your Name?"
/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/inamefield"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Launch Activity2"
android:id="@+id/launchbutton"
/>
</LinearLayout>


修改主活動代碼, 使用Intent.putExtra()傳遞數據給Activity2.
package com.AndroidIntent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class AndroidIntent extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button launchButton = (Button)findViewById(R.id.launchbutton);
final EditText iNameField = (EditText)findViewById(R.id.inamefield);
launchButton.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent newIntent = new Intent(AndroidIntent.this, Activity2.class);
newIntent.putExtra("name", iNameField.getText().toString());
startActivity(newIntent);
}});
}
}


修改layout2.xml, 添加一個文本視圖(TextView).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="It's Activity2"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/onamefield"
/>
</LinearLayout>


修改Activity2代碼, 使用getIntent().getExtras()獲得數據, 並顯示在文本視圖(TextView)中.
package com.AndroidIntent;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;


public class Activity2 extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.layout2);
TextView oNameField = (TextView)findViewById(R.id.onamefield);

Bundle extras = getIntent().getExtras();
oNameField.setText("Hello " + extras.getString("name"));
}
}


記住, 需要修改清單文件(AndroidManifest.xml)加入ctivity2, 參考"活動(activity)和意圖(intent)".

相關文章: startActivityForResult 和 onActivityResult



活動(activity)和意圖(intent)

一個活動(Activity)是一個用戶可以做的單一的,集中的事. 幾乎所有的活動都與用戶交互,活動類負責創建一個窗口(window), 可以通過setContentView(View)放置用戶界面(UI). 雖然活動往往呈現全屏幕窗口給用戶,但也可以其他方式呈現: 通過windowIsFloating的主題呈現浮動窗口, 或使用ActivityGroup嵌入到另一個活動中.

意圖(Intent)是一個要執行的操作的抽象描述. 它為不同的應用代碼之間提供後期運行時綁定(late runtime binding). 這基本上是一個被動數據結構, 它持有一個要執行的操作的抽象描述.

startActivity是啟動一項新活動的方法, 將不會收到任何有關活動退出時的信息.

在這實例中, 主活動通過startActivity啟動另一個活動, 為了簡單, 這實例中不會在活動之間傳遞數據.



在一個應用程序, 如果需要一個額外的活動, 需要在清單文件(AndroidManifest.xml)中申報.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.AndroidIntent"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AndroidIntent"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Activity2" />
</application>
<uses-sdk android:minSdkVersion="7" />

</manifest>


創建一個新的活動Activity2.java和相應的佈局layout2.xml

Activity2.java
package com.AndroidIntent;
import android.app.Activity;
import android.os.Bundle;


public class Activity2 extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.layout2);
}

}


layout2.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="It's Activity2"
/>
</LinearLayout>


修改主佈局(main.xml), 添加一個按鈕來啟動另一個活動.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Launch Activity2"
android:id="@+id/launchbutton"
/>
</LinearLayout>


修改主活動代碼
package com.AndroidIntent;

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

public class AndroidIntent extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button launchButton = (Button)findViewById(R.id.launchbutton);
launchButton.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent newIntent = new Intent(AndroidIntent.this, Activity2.class);
startActivity(newIntent);
}});
}
}


相關文章: 包裹(Bundle)



2010年2月6日星期六

圖像視圖(ImageView)

圖像視圖(ImageView)

很簡單, 圖像視圖(ImageView)就是顯示圖像的視圖. 圖像視圖類可以從不同來源加載圖像, 如資源(resources)或內容提供商(內容提供商).



加載圖片來自不同來源(如資源或內容提供商)

佈局(main.xml)
<ImageView  
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"
/>




評級條(RatingBar)

評級條(RatingBar)是進度條(ProgressBar)和拖動條(SeekBar)的擴展類,它以星星圖案顯示評級.

評級條(RatingBar)

使用默認風格(ratingBarStyle)時, 用戶可以觸摸/拖動, 或使用箭頭鍵, 來設定評級. 較小的ratingBarStyleSmall風格和只作指標的ratingBarStyleIndicator風格只作為指標使用, 不支持用戶交互.

佈局(main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<RatingBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:attr/ratingBarStyleIndicator"
android:id="@+id/ratingbar_Indicator"
/>
<RatingBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:attr/ratingBarStyleSmall"
android:id="@+id/ratingbar_Small"
/>
<RatingBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:attr/ratingBarStyle"
android:id="@+id/ratingbar_default"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ratingbutton"
android:text="Rate It"
/>
</LinearLayout>


主程序
package com.AndroidRatingBar;

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

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

final RatingBar ratingBar_Small = (RatingBar)findViewById(R.id.ratingbar_Small);
final RatingBar ratingBar_Indicator = (RatingBar)findViewById(R.id.ratingbar_Indicator);
final RatingBar ratingBar_default = (RatingBar)findViewById(R.id.ratingbar_default);
Button ratingButton = (Button)findViewById(R.id.ratingbutton);

ratingButton.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
float rating = ratingBar_default.getRating();
ratingBar_Small.setRating(rating);
ratingBar_Indicator.setRating(rating);
}});
}
}




2010年2月2日星期二

拖動條(SeekBar)

拖動條(SeekBar)是進度條(ProgressBar)的擴展類,它增加了一個拖動拇指. 用戶可以拖動拇指向左或向右(或使用箭頭鍵)來設置目前的進度.



main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10px"
android:id="@+id/seekbar"
android:max="100"
android:progress="50"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/seekbarvalue"
android:text="50"
/>
</LinearLayout>


主程序
package com.AndroidSeekBar;

import android.app.Activity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;

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

SeekBar seekBar = (SeekBar)findViewById(R.id.seekbar);
final TextView seekBarValue = (TextView)findViewById(R.id.seekbarvalue);

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
seekBarValue.setText(String.valueOf(progress));
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
});
}
}