2013年4月28日 星期日

[Android] 撥放音效(play audio)

1.撥放音效第一個步驟,需要新建一個資料夾存放音效檔。
路徑為res/raw/xxx.wav(或xxx.mp3)。

2.在主程式裡要先開啟一個audio的服務,主要是用來管理音量,鈴聲模式及聲道等...
其次則需new SoundPool,主要是用來載入,撥放及停止音效等功能。
我們直接來看codes

MainActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;

public class MainActivity extends Activity {

 private Button bPlay;
 private Button bPause;
 private SoundPool spool;
 private int sourceid;

 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  bPlay = (Button) findViewById(R.id.btnPlay);
  bPause = (Button) findViewById(R.id.btnPause);
  // 聲音庫的最大音頻流數目為10,聲音品質為5
  spool = new SoundPool(10, AudioManager.STREAM_MUSIC, 5);
  sourceid = spool.load(this, R.raw.harm, 1);

  bPlay.setOnClickListener(new OnClickListener() {
   public void onClick(View v) {

    playSud(0);
   }
  });

  bPause.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View v) {

    spool.pause(sourceid);
   }
  });
 }

 public void playSud(int repeatTime) {
  AudioManager am = (AudioManager) getApplicationContext()
    .getSystemService(Context.AUDIO_SERVICE);
  // 獲取最大音量

  float audMaxVolumn = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
// 左右聲道值範圍為 0.0 - 1.0
  float volRatio = audCurrentVolumn / audMaxVolumn; 

 // 獲取目前音量
  float audCurrentVolumn = am.getStreamVolume(AudioManager.STREAM_MUSIC);
  
  // 播放音頻,左右音量,設置優先級,重撥次數,速率(速率最低0.5,最高為2,1代表正常速度)
  spool.play(sourceid, volRatio, volRatio, 1, repeatTime, 1);
 }
}

3.Layout的部分很簡單,加人撥放和暫停二個按鈕
res/layout/activity_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=".MainActivity" >

    <Button
        android:id="@+id/btnPlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="99dp"
        android:text="撥放(Play)" />

    <Button
        android:id="@+id/btnPause"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="暫停(Pause)" />
 
</RelativeLayout>

另外一個簡單的方法,也可以達到同樣的結果
這個方法直接讀取預設通知(default notification)的鈴聲來撥放
設定的路徑是為(設定>音效>預設通知)
 Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
 Ringtone ringTone = RingtoneManager.getRingtone(getApplicationContext(), notification);
        ringTone.play();

[Android] 動畫按鈕(animation button)

今天來實作一個可以放大縮小的動畫按鈕
1.首先先加入一個imagebutton,我們找一張並命名為fba.png
2.要加入二個xml檔,一個負責放大(to_large.xml),另一個負責縮小(to_small.xml)

 res/anim/to_large.xml
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:fromXScale="1.0" android:toXScale="2.0" android:fromYScale="1.0"
    android:toYScale="2.0" android:pivotX="50%" android:pivotY="50%"
    android:duration="500" />

<!-- android:fromXScale = "1.0" //fromXScale表示從什麼大小開始放大,1.0表示從原本圖的大小開始放大,
0.5則是初始值是原圖縮小一倍 -->
<!-- android:toXScale="2.0"  //toXScale表示放大到多大,2.0表示放大到原圖的2倍 -->

res/anim/to_small.xml
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:fromXScale="2.0" android:toXScale="1.0" android:fromYScale="2.0"
    android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%"
    android:duration="500" />


MainActivity.java
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Animation.AnimationListener;
import android.widget.ImageButton;

public class MainActivity extends Activity implements AnimationListener {
 private Animation toLargeAnimation;
 private Animation toSmallAnimation;
 private ImageButton imageView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  imageView = (ImageButton) findViewById(R.id.imageView);

  toLargeAnimation = AnimationUtils.loadAnimation(MainActivity.this,
    R.anim.to_large);
  toSmallAnimation = AnimationUtils.loadAnimation(MainActivity.this,
    R.anim.to_small);
  toLargeAnimation.setAnimationListener(MainActivity.this);
  toSmallAnimation.setAnimationListener(MainActivity.this);
  imageView.startAnimation(toSmallAnimation);

  addListenerOnButton();
 }

 public void onAnimationStart(Animation animation) {
  // TODO Auto-generated method stub

 }

 public void onAnimationEnd(Animation animation) {

  if (animation.hashCode() == toLargeAnimation.hashCode())
   imageView.startAnimation(toSmallAnimation);
  else
   imageView.startAnimation(toLargeAnimation);

 }

 public void onAnimationRepeat(Animation animation) {
  // TODO Auto-generated method stub

 }

 public void addListenerOnButton() {

  imageView.setOnClickListener(new OnClickListener() {

   public void onClick(View arg0) {
    // 按下按鈕要做的事,就寫在這裡

   }

  });

 }
}


res/layout/activity_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=".MainActivity" >

    <ImageButton
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginBottom="20dp"
        android:background = "#ffffff"
        android:src="@drawable/fba" />

</RelativeLayout>





參考連結
http://www.360doc.com/content/11/1208/16/8157240_170676944.shtml
http://www.pocketdigi.com/20110511/277.html

2013年4月27日 星期六

[Android] 自訂顯示快顯(custom toast)

一般預設的寫法是像這樣
Toast.makeText(getApplicationContext(), "預設的顯示快顯", Toast.LENGTH_SHORT).show();

今天來實作一個帶圖片的的toast
首先先加入toast要用的圖案,在這裡加入一個icon.png












MainActivity.java
package com.example.customtoast;

import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

    private Button mToastButton;
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToastButton = (Button) findViewById(R.id.toast_button);
        mToastButton.setOnClickListener(this);
       
    }

    @Override
    public void onClick(View v) {

        if(v.getId() == R.id.toast_button) {
            LayoutInflater inflater = getLayoutInflater();
            View layout = inflater.inflate(R.layout.custom_toast,
                    (ViewGroup) findViewById(R.id.custom_toast));
          
         Toast toast = new Toast(getApplicationContext());
          toast.setGravity(Gravity.CENTER, 0, 0);
          toast.setDuration(Toast.LENGTH_LONG);
          toast.setView(layout);
          toast.show();
        }
    }
}

制作一個toast的layout
res/layout/custom_toast.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/custom_toast"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:background="@android:color/black">

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/icon" />

    <TextView
        android:id="@+id/toast_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is a custom toast"
        android:textAppearance="@android:attr/textAppearanceLarge"
        android:textColor="@android:color/white" />
    
    </LinearLayout>

res/layout/activity_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=".MainActivity" >

    <Button
        android:id="@+id/toast_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="32dp"
        android:text="Click Here to show Toast" />

</RelativeLayout>

結果:

2013年4月25日 星期四

[Java] Java JNI error java.lang.UnsatisfiedLinkError的解決方法

簡單來說JNI即是JAVA用來跟C/C++等其他語言溝通的函式庫。Java.lang.UnsatisfiedLinkError這個問題雖然很多人也遇到,
不過剛好都不是我的root cause,在這裡留下我的解法

因為我一台電腦是JVM 32 bit,另一台是JVM 64 bit(可以java -d64 -version 指令來確認,如下圖)
,但我的dll是build成x86,導致我用JVM 64來跑時,就會出現這個錯誤。
解決的方法就是更改Visual studio的設定,重build一個x64的dll,就OK了
真是一個不注意就白花費了好多問題呵!












JNI is a bridge between JAVA and C/C++,
many people encounter the error as Java.lang.UnsatisfiedLinkError,
my root cause is that my PC is JVM 32 bit, but my dll is built into 64 bit(you could check what java JVM version you use with command "java -d64 -version"),
the solution is very simple that to rebuild the dll to 32 bit.



2013年4月22日 星期一

[Android] 圖片展示(ImageView)

我們來做個簡單的ImageView應用,
我們預設放一張紅色的花到ImageView,
當按下按鈕,即切換到藍色的花


1.加入Images到res/drawable-hdpi


2.加入ImageView及一個按鈕
res/layout/activity_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=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="flower1" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/button1"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="17dp"
        android:src="@drawable/flower2" />

</RelativeLayout>


3. MainActivity.java
 

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

public class MainActivity extends Activity {
 Button button;
 ImageView image;
 boolean flowerImgShowed = false;

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

  addListenButton();
 }

 public void addListenButton() {

  image = (ImageView) findViewById(R.id.imageView1);

  button = (Button) findViewById(R.id.button1);
  button.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View arg0) {

    // 按下按鈕,來切換圖片
    if (!flowerImgShowed) {
     image.setImageResource(R.drawable.flower1);
     button.setText("Flower2);
     flowerImgShowed = true;
    } else {
     image.setImageResource(R.drawable.flower2);
     button.setText("Flower1");
     flowerImgShowed = false;
    }
   }

  });

 }

}

結果:
      

2013年4月19日 星期五

[Android] 手機資料傳到電腦(WiFi)

如何將手機資料經由WIFI傳到電腦呢?
我們可以利用ServerSocket(Server端)和socket(Client端)來實作一個例子
從手機裡選一張照片傳送到電腦,
這裡有一點要注意,Server和client需在同一個網址。

電腦端(Server):
先自訂一個port(這裡是設成1111), 然後new一個ServcerSocket,
再呼叫accept()方法,這個方法會一直等到client端連進來,
才會執行下一行程式。

這邊的build法,我是用eclipse,直接NEW->Java project,打入程式後,
直接按RUN(Ctrl+F11)去執行,然後等待Android端連進來。

DesktopServerTCP.java
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class DesktopServerTCP implements Runnable {

 public static final int SERVERPORT = 1111;

 // 最後要儲存照片的位置
 public static final String file_name = "C:\\Users\\Public\\Pictures\\Sample Pictures\\test.jpeg";

 public void run() {

  try {

   System.out.println("Server: Connecting...");
   ServerSocket serverSocket = new ServerSocket(SERVERPORT);

   while (true) {

    Socket client = serverSocket.accept();
    System.out.println("Server: Receiving...");

    OutputStream out = new FileOutputStream(file_name);
    byte buf[] = new byte[1024];
    int len;

    // 讀入從手機端傳來的照片
    InputStream inputStream = client.getInputStream();
    try {
     while ((len = inputStream.read(buf)) != -1) {
      // 將照片寫入到電腦裡
      out.write(buf, 0, len);
     }
     out.close();
     inputStream.close();

    } catch (IOException e) {
     e.printStackTrace();
    } finally {

     client.close();
     System.out.println("Server: Done.");

    }

   }

  } catch (Exception e) {

   System.out.println("Server: Error");
   e.printStackTrace();

  }

 }

 public static void main(String str[]) {

  Thread desktopSerThread = new Thread(new DesktopServerTCP());
  desktopSerThread.start();

 }
}

Android端(Client):
這邊我設計成,程式一啟動,就選一張照片傳送到電腦端,
分成二個階段:
第一個階段時,new一個socket,然後帶入Server端的IP位址及Port number,
第二個階段,先將照片讀入後,存在buffer裡,
然後在利用outputstream輸出至Server端。

MainActivity.java
package com.example.socketclient;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {

 Socket socket;
 //從手機裡的"我的檔案"選張照片,準備傳到電腦,
 //因不同的手機路徑可能不同,可自行修改。
 public static final String file_name = "//storage//sdcard0//Download//images.jpeg";

 @Override
 public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  Thread test = new Thread(clientSocket);
  test.start();

 }

 Runnable clientSocket = new Runnable() {

  @Override
  public void run() {

   try {

    InetAddress serverAddr = InetAddress.getByName("192.168.1.104");
    Log.e("Socket", "Client: Connecting...");

    try {

     socket = new Socket(serverAddr, 1111);
     OutputStream outputstream = socket.getOutputStream();

     File myFile = new File(file_name);

     if (myFile.exists()) {

      byte[] mybytearray = new byte[(int) myFile.length()];
      FileInputStream fis = new FileInputStream(myFile);

      BufferedInputStream bis = new BufferedInputStream(fis,
        8 * 1024);
      bis.read(mybytearray, 0, mybytearray.length);
      //輸出到電腦
      outputstream.write(mybytearray, 0, mybytearray.length);
      outputstream.flush();

     } else
      Log.e("Socket", "file doesn't exist!");

    } catch (Exception e) {

     Log.e("Socket", "Client: Error", e);

    } finally {

     socket.close();

    }
   } catch (Exception e) {

   }

  }

 };

}

最後,因為我們有用到網路傳輸,
所以記得在xml加入INTERNET,和讀取SD卡的的權限。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.socketclient"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.socketclient.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>     
    </application>
   <uses-permission android:name="android.permission.INTERNET" /> 
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    </manifest>

2013年4月17日 星期三

[Android] 核取對話框(checkbox dialog box)

核取對話框或勾選對話框,不是很確定是不是翻成這樣。

我們來舉一個例子:
每次啟動應用程式(APP),都詢問是否瀏覽GOOGLE首頁,
當使用者勾選"不再顯示",下一次進入到程式時,即不會再顯示此對話框。

MainActivity.java
package com.example.time;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;

public class MainActivity extends Activity {
 boolean skipMessage;
 AlertDialog.Builder alert;
 public CheckBox dontShowAgain;

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

  // 宣告對話框
  CKDiagbox();

  // 如果沒有勾選"不再顯示",則顯示對話框
  if (!isCheckboxStateEnabled())
   alert.show();

 }

 public void CKDiagbox() {

  alert = new AlertDialog.Builder(this);
  LayoutInflater adbInflater = LayoutInflater.from(this);
  View checkboxLayout = adbInflater.inflate(R.layout.checkbox, null);
  dontShowAgain = (CheckBox) checkboxLayout.findViewById(R.id.skip);
  alert.setView(checkboxLayout);
  alert.setTitle(R.string.settitle);
  alert.setIcon(android.R.drawable.ic_dialog_alert);
  alert.setMessage(R.string.toGoogle);

  alert.setPositiveButton("離開", new DialogInterface.OnClickListener() {
   public void onClick(DialogInterface dialog, int which) {

    boolean checkBoxResult = false;
    if (dontShowAgain.isChecked())
     checkBoxResult = true;

    setCheckboxState(checkBoxResult);

    // 關閉對話框
    finish();
   }
  });

  alert.setNegativeButton("進入", new DialogInterface.OnClickListener() {
   public void onClick(DialogInterface dialog, int which) {
    boolean checkBoxResult = false;

    if (dontShowAgain.isChecked())
     checkBoxResult = true;

    setCheckboxState(checkBoxResult);

    Uri uri = Uri.parse("http://www.google.com/");
    Intent it = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(it);

   }
  });

 }

 public void setCheckboxState(boolean chk) {
  // 記錄勾選方塊是否被打勾
  SharedPreferences settings = getSharedPreferences("showit", 0);
  SharedPreferences.Editor editor = settings.edit();
  editor.putBoolean("skipMessage", chk);
  editor.commit();
 }

 public boolean isCheckboxStateEnabled() {
  // 讀取勾選方塊是否被打勾,預設值是未打勾(fasle)
  SharedPreferences settings = getSharedPreferences("showit", 0);
  skipMessage = settings.getBoolean("skipMessage", false);

  return skipMessage;
 }

}

加入核取方塊 res/layout/checkbox.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:paddingLeft="10dp"
    android:paddingRight="10dp" >
   
    <CheckBox
        android:id="@+id/skip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/checkbox" >
    </CheckBox>

</LinearLayout>
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">checkbox dialog box</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="checkbox">不在顯示</string>
    <string name="toGoogle">是否前往GOOGLE首頁</string>
 <string name="settitle">歡迎</string>
</resources>
結果:

2013年4月16日 星期二

[Android] 偏好設定(SharedPreferences)

偏好設定提供一個簡易的方式來儲存應用程式的設定值,
有點類似在C++開啟一個檔案來儲存資料。

我們來舉個記錄當下日期時間的例子:
MainActivity.java
package com.example.time;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.text.format.Time;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
 SharedPreferences dateFile;
 Button writeDate, readDate;

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

  // 指定一個檔案來儲存
  dateFile = this.getSharedPreferences("DateFile", 0);

  // 宣告按鈕
  writeDate = (Button) findViewById(R.id.button1);
  writeDate.setOnClickListener(new Button.OnClickListener() {
   public void onClick(View v) {
    //記錄當下時間日期
    writeDate();
   }
  });

  readDate = (Button) findViewById(R.id.button2);
  readDate.setOnClickListener(new Button.OnClickListener() {
   public void onClick(View v) {
    //讀取時間日期
    readDate();
   }
  });

 }

 public void writeDate() {
  // 取得時間
  Time t = new Time();
  t.setToNow();
  String dateInfo = t.toString();

  // 將字串寫入date裡
  SharedPreferences.Editor e = dateFile.edit();
  e.putString("date", dateInfo);
  e.commit();
  Toast.makeText(this, "record Date is successful", Toast.LENGTH_LONG)
    .show();
 }
 
 public void readDate() {
  String lastday = dateFile.getString("date", "2012"); // 讀取date裡的資料,如果date裡沒有資料,則會讀取預設值2012
  Toast.makeText(this, lastday, Toast.LENGTH_LONG).show();
 }

}

res/layout/activity_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=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="56dp"
        android:text="記錄日期undefinedrecord date)" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/textView1"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="22dp"
        android:text="讀取日期undefinedread date)" />

</RelativeLayout>
結果:

2013年4月15日 星期一

[Android] 對話框(dialog)

MainActivity.java
package com.example.alertdialog;
package com.example.alertdialog;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.view.Menu;

public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  //呼叫對話框
  AlertDialog dialog = getAlertDialog("Hello", "I am a dialog");
  dialog.show();
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.activity_main, menu);
  return true;
 }

 //自定一個對話框的方法
 private AlertDialog getAlertDialog(String title, String message) {

  Builder builder = new AlertDialog.Builder(this);
  builder.setTitle(title);
  builder.setMessage(message);
  builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
   public void onClick(DialogInterface dialog, int which) {
    //當按下OK鍵,即結束對話框
    dialog.dismiss();
   }
  });

  return builder.create();
 }
}
結果:

2013年4月7日 星期日

[Android] 建立執行緒(create Thread)

實作thread
class threadTest implements Runnable {
  public void run() {
  //要做的事寫在這邊
  }
 };


啟動thread
Thread thread = new Thread(new threadTest());
thread.start();


中斷thread
if (thread != null) {
  thread.interrupt();
  thread = null;
}

2013年4月5日 星期五

[Android] eclipse debug


Key 功能
F5 從你選擇的那一行開始debug,然後一行一行向下執行。如果有遇到函式(function),則會跳到函式程式片段裡面。
F6 和F5很類似,差別在不會進入到函式的程式片段。
F7 當在函式程式片段裡面時,按下F7,即會跳出該函式,回到目前此函式的呼叫者(caller of this function)
F8 直接跳到下一個斷點(breakpoint/watchpoint)

2013年4月2日 星期二

[Win32] 高精確度計算程式執行時間 (QueryPerformanceCounter)

舉例來說,我們想來計算一個函式(function)執行所花的時間

LARGE_INTEGER g_lStartTime
LARGE_INTEGER g_lEndTime;
LARGE_INTEGER g_lFreq;

void sample()

{

 //取得目前 CPU frequency

 QueryPerformanceFrequency( &g_lFreq);

 // 取得目前開始時間

 QueryPerformanceCounter( &g_lStartTime);

//你的程式

 for ( i = 0 ; i < 5000 ; i++)

       i = i+1;

//取得執行後的時間

QueryPerformanceCounter( &g_lEndTime );

//計算一共花了多少時間

double dElapsedTime = (g_lEndTime.QuadPart - g_lStartTime.QuadPart) * 1000.0 / g_lFreq.QuadPart;

 //列印出來

printf( "Elapsed time = %lf millisecond\n", dElapsedTime );

}