2011年12月23日 星期五

來電警衛

由於我們需取得目前手機的通話狀態,因此必需在AndroidManifest.xml內新增一個讀取通話狀態的權限。
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

Caller.java
package com.demo.android.Caller;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.SimpleCursorAdapter;
import android.widget.AdapterView.OnItemClickListener;

public class CallerActivity extends Activity {
private PhoneState phoneState;

static String TABLE_NAME="Caller";
    static String ID="_id"; //使用SimpleCursorAdapter,欄位名稱必須為_id
    static String PHONE="phone";
    static String STATE="state";
 
    static String[] COLUMNS = { ID, PHONE, STATE };
    //android內建list樣式
    //android.R.layout.simple_list_item_2
    //android.R.id.hint
    //android.R.id.text1
    //android.R.id.text2
    static int[] TO = { android.R.id.hint, android.R.id.text1, android.R.id.text2};
    long selectedIndex = 0;//儲存點選ListView項目
 
    DBConnection dbconn;
     
    private Button InsBtn;
    private Button DelBtn;
    private RadioGroup stateRg;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
     
        phoneState = new PhoneState(this);
     
        TelephonyManager telMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        telMgr.listen(phoneState, PhoneState.LISTEN_CALL_STATE);
     
        //建立資料庫實體
        dbconn=new DBConnection(this);
        show();
     
        InsBtn = (Button)findViewById(R.id.InsBtn);
        DelBtn = (Button)findViewById(R.id.DelBtn);
        stateRg = (RadioGroup) findViewById(R.id.stateRg);
        ListView callerLv = (ListView)findViewById(R.id.callerLv);
     
        //建立新增按鈕事件
        InsBtn.setOnClickListener(new Button.OnClickListener(){
        @Override
public void onClick(View v) {
// TODO Auto-generated method stub
        //取得DatePicker設定的日期
        String phoneEt = ((EditText)findViewById(R.id.phoneEt)).getText().toString();
        String state = "";

//新增Note
switch(stateRg.getCheckedRadioButtonId()){
case R.id.normal:
state = "鈴聲";
break;
case R.id.vibrate:
state = "震動";
break;
case R.id.silent:
state = "無聲";
break;
}

insert( phoneEt, state);

//清除EditText
((EditText)findViewById(R.id.phoneEt)).setText("");
}
        });
     
        //建立刪除按鈕事件
        DelBtn.setOnClickListener(new Button.OnClickListener(){
        @Override
public void onClick(View v) {
// TODO Auto-generated method stub
        delete(selectedIndex);
}
        });
     
        callerLv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View view,
                                           int position, long id) {

//儲存點選編號
selectedIndex = id;
}
        });
     
     
    }
 
    //必須要覆寫OnResume,完成通話後才可以顯示資料表資料
    @Override
    protected void onResume() {
    super.onResume();
   
   
    show();
    }
 
    private void show() {
   
   
    SQLiteDatabase db=dbconn.getWritableDatabase();
        Cursor c=null;
     
        //查詢資料 SELECT _id, date, note FROM Notes
        c=db.query(TABLE_NAME, COLUMNS,null, null, null, null, null);  
     
      //使用SimpleCursorAdapter直接將資料表資料顯示至ListView上
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, c, COLUMNS, TO);
    ListView callerLv = (ListView)findViewById(R.id.callerLv);
    callerLv.setAdapter(adapter);
   
    //把建立的Cursor實體交給Activity管理,
    startManagingCursor(c);
   
    db.close();
    }
 
    private void insert(String phone, String state) {
    // 用ContentValues插入資料
    ContentValues values=new ContentValues();
values.put(PHONE,phone);
values.put(STATE,state);
SQLiteDatabase db = dbconn.getWritableDatabase();
db.insert(TABLE_NAME, null, values);
db.close();

//ListView顯示Caller表格內容
show();
    }
 
    private void delete(long id) {
    // 刪除代號為id的資料
    SQLiteDatabase db = dbconn.getWritableDatabase();
    db.delete(TABLE_NAME, "_id=?" , new String[]{Long.toString(id)});
db.close();

//ListView顯示Caller表格內容
show();
    }
}
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="電話號碼" />

        <EditText
            android:id="@+id/phoneEt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:inputType="phone">"

            <requestFocus />
        </EditText>
    </LinearLayout>
 

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/TextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:text="來電狀態" />

        <RadioGroup
            android:id="@+id/stateRg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <RadioButton
                android:id="@+id/normal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="鈴聲" />

            <RadioButton
                android:id="@+id/vibrate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="震動" />

            <RadioButton
                android:id="@+id/silent"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="無聲" />
        </RadioGroup>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/InsBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="新增" />

        <Button
            android:id="@+id/DelBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="刪除" />
    </LinearLayout>

    <ListView
        android:id="@+id/callerLv"
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:layout_weight="0.56" >
    </ListView>

</LinearLayout>
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
DBConnection.java

package com.demo.android.Caller;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBConnection extends SQLiteOpenHelper {

private static final String DATABASE_NAME="CallerDB";
    private static final int DATABASE_VERSION=1;
public DBConnection(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}

@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
//建立表格
//空格一定要保留
String sql = "CREATE TABLE  Caller  ("
+ " _id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " phone text not null, "
+ " state text not null" + ");";

db.execSQL(sql);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub

}

}
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
package com.demo.android.Caller;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.AudioManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;

public class PhoneState extends PhoneStateListener {
private String stateStr;
private Context context;
private AudioManager audioManager;
public PhoneState(Context c){
super();
context = c;
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
}
@Override
public void onCallStateChanged(int state, String incomingNumber){
super.onCallStateChanged(state, incomingNumber);
switch(state){
case TelephonyManager.CALL_STATE_IDLE:
//待機
stateStr = "待機預設為震動模式";
//待機預設為震動模式
audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//通話中
stateStr = "通話中";
break;
case TelephonyManager.CALL_STATE_RINGING:
//來電
stateStr = GetStat(incomingNumber);
if(stateStr.equals("鈴聲")){
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}else if(stateStr.equals("震動")){
audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
}else if(stateStr.equals("無聲")){
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}
break;
}
Toast.makeText(context, stateStr, Toast.LENGTH_SHORT).show();
}
private String GetStat(String incomingNumber){
//建立資料庫實體
DBConnection dbconn = new DBConnection(context);
SQLiteDatabase db = dbconn.getReadableDatabase();
String state = "";
        //取得所有資料放在list
        Cursor c = db.query("Caller", new String[]{"state"}, "phone = ?", new String[]{incomingNumber}, null, null, null);
c.moveToFirst();
if( c.getCount() > 0 ){
state = c.getString(0);
}
c.close();
return state;
}

}

2011年12月16日 星期五

PhoneStateListener_手機通話狀態

手機通話狀態,必須繼承PhoneStateListener這個類別
以下為API的reference 

Class Overview


A listener class for monitoring changes in specific telephony states on the device, including service state, signal strength, message waiting indicator (voicemail), and others.


Override the methods for the state that you wish to receive updates for, and pass your PhoneStateListener object, along with bitwise-or of the LISTEN_ flags to TelephonyManager.listen().


Note that access to some telephony information is permission-protected. Your application won't receive updates for protected information unless it has the appropriate permissions declared in its manifest file. Where permissions apply, they are noted in the appropriate LISTEN_ flags.


在監測設備上的特定電話的國家,包括服務的狀態,信號強度,消息等待指示(語音信箱),及其他變化的一個監聽器類別。


如果是在覆蓋的狀態,您希望收到更新的方法,需透過 PhoneStateListener,或LISTEN_ flags TelephonyManager.listen()。


需要注意的是一些電話信息的接聽權限保護。您的應用程序將不會收到保護信息的更新,除非它已在其清單文件中聲明的適當的權限。


權限申請需要在適當的LISTEN_ flags。


由於我們需取得目前手機的通話狀態,因此必需在AndroidManifest.xml內新增一個讀取通話狀態的權限。


<uses-permission android:name="android.permission.READ_PHONE_STATE"/>


package com.demo.android.PhoneStateListener;

import android.content.Context;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.TextView;
import android.widget.Toast;

public class PhoneState extends PhoneStateListener {
private TextView textView;
private Context context;

public PhoneState(Context c){
super();
context = c;
}

@Override
public void onCallStateChanged(int state, String incomingNumber){
super.onCallStateChanged(state, incomingNumber);

switch(state){
case TelephonyManager.CALL_STATE_IDLE:
//待機
textView.setText("待機");
break;

case TelephonyManager.CALL_STATE_OFFHOOK:
//通話中
textView.setText("通話中");
break;

case TelephonyManager.CALL_STATE_RINGING:
//來電
textView.setText(incomingNumber+"來電");

break;
}
Toast.makeText(context, textView.getText().toString(), Toast.LENGTH_SHORT).show();

}

public void setTextView(TextView tv){
textView = tv;
textView.setText("待機");
}

}

========================================================================

package com.demo.android.PhoneStateListener;

import android.app.Activity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.TextView;

public class PhoneStateListenerActivity extends Activity {
private PhoneState phoneState;
private TextView phoneStateTv;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        phoneStateTv = (TextView)findViewById(R.id.phoneStateTv);
        phoneStateTv.setText("123");
        
        phoneState = new PhoneState(this);
        phoneState.setTextView(phoneStateTv);
        
        TelephonyManager telMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        telMgr.listen(phoneState, PhoneState.LISTEN_CALL_STATE);
    }
}




鈴聲模式_AudioManager

AudioManager提供訪問量和振鈴模式控制。


使用Context.getSystemService(Context.AUDIO_SERVICE)來得到這個類別的一個實例。


由於我們需取得目前手機的通話狀態,因此必需在AndroidManifest.xml內新增一個讀取通話狀態的權限。


<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

package com.demo.android.RingerMode;

import android.app.Activity;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class RingerModeActivity extends Activity {
    /** Called when the activity is first created. */
//設定模式
private AudioManager audioManager;

private Button normalBtn;
private Button silentBtn;
private Button vibrateBtn;

private TextView ringerModeTv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
     
        normalBtn = (Button)findViewById(R.id.normalBtn);
        silentBtn = (Button)findViewById(R.id.silentBtn);
        vibrateBtn = (Button)findViewById(R.id.vibrateBtn);
     
        audioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
     
        ShowRingerMode();
     
        normalBtn.setOnClickListener(new Button.OnClickListener(){
        @Override
public void onClick(View v) {
// TODO Auto-generated method stub
        //RINGER_MODE_NORMAL 模式為可能發聲,可能震動
        audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
       
        ShowRingerMode();
}
        });
     
        silentBtn.setOnClickListener(new Button.OnClickListener(){
        @Override
public void onClick(View v) {
// TODO Auto-generated method stub
        //RINGER_MODE_SILEN模式為靜音
        audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
       
        ShowRingerMode();
}
        });
     
        vibrateBtn.setOnClickListener(new Button.OnClickListener(){
        @Override
public void onClick(View v) {
// TODO Auto-generated method stub
        //模式為靜音震動
        audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
       
        ShowRingerMode();
}
        });
    }
 
    private void ShowRingerMode(){
    ringerModeTv = (TextView)findViewById(R.id.ringerModeTv);
    int ringerMode = audioManager.getRingerMode();
   
    switch(ringerMode){
    case AudioManager.RINGER_MODE_NORMAL:
    ringerModeTv.setText("來電模式:鈴聲");
    break;
    case AudioManager.RINGER_MODE_SILENT:
    ringerModeTv.setText("來電模式:靜音");
    break;
   
    case AudioManager.RINGER_MODE_VIBRATE:
    ringerModeTv.setText("來電模式:震動");
    break;
    }
    }
}


2011年12月14日 星期三

SensorEventListener 感測器實作

要使用Android陀螺儀須先下載sensorsimulator-2.0-rc1
1.解壓縮到C:\sensorsimulator-2.0-rc1,
2.開啟資料夾「C:\sensorsimulator-2.0-rc1\bin」找到「sensorsimulator-2.0-rc1.jar
3.記得要先將模擬器打開
4.將資料夾「C:\sensorsimulator-2.0-rc1\bin」底下的「sensorsimulator-2.0-rc1.apk」複製到  
    I:\eclipse\android-sdk-windows\platform-tools 下
5.開啟cmd 指向你的eclipse磁碟機 打上cd eclipse\android-sdk-windows\platform-tools
6.接著 輸入adb install sensorsimulator-2.0-rc1.apk
7.出現「Success」表示安裝成功
8.到主目錄會出現

9.按「Testing」然後再按「Connect


.使用模擬器 / 取得感測器服務 / 與感測器連線 /建立onResume()onPause()
.implements SensorEventListener必須實作onAccuracyChangedonSensorChanged
. onResume()onPause()之間,在這個時期的Activity是在所有的Activity的前面,並且直接跟使用者進行互動,所以這段時期指的就是Activity is running 一個Activity能很頻繁的在resumepause這兩個狀態切換。所以在onResume()onPause()裡實作的程式應盡量精簡。
onCreate()是程式的初始化動作,onDestory()就是將onCreate()時所要來的資料做釋放的動作,onPause()將需要保存的資料進行保存,onResume()把保存的資料取回使用。

先在AndroidManifest.xml中設定權限
</application>
<!-- 新增INTERNET的權限 -->
  <uses-permission android:name="android.permission.INTERNET"/>

接著XML設定
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/xyz"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />


    <ImageView
        android:id="@+id/img"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/ic_launcher" />
</LinearLayout>
java主介面
package com.demo.android.SensorA;

//使用模擬器
import org.openintents.sensorsimulator.hardware.Sensor;
import org.openintents.sensorsimulator.hardware.SensorEvent;
import org.openintents.sensorsimulator.hardware.SensorEventListener;
import org.openintents.sensorsimulator.hardware.SensorManagerSimulator;


import android.app.Activity;
import android.hardware.SensorManager;
/*在實機上
import java.util.List;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;*/
import android.os.Bundle;
import android.widget.ImageView;
//import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

//要使用感測器必須實作SensorEventListener介面
public class SensorAActivity extends Activity implements SensorEventListener {
    /** Called when the activity is first created. */
//private SensorManager sensorManager; //在實機上
private SensorManagerSimulator sensorManager; //使用模擬器
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //在實機上
        //取得感測器服務(Sensor service)
        //sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);//在實機上
        
        //使用模擬器
        //取得感測器服務(Sensor service)
        sensorManager = SensorManagerSimulator.getSystemService(this,SENSOR_SERVICE);
        //與感測模擬器連線
        sensorManager.connectSimulator();
    }
    
    @Override
    protected void onResume() {
    super.onResume();
   
    //註冊感應器
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
    }
    
    @Override
    protected void onPause() {
    super.onPause();
    //解除感應器註冊
   
    //在實機上
    //解除感應器註冊
    //sensorManager.unregisterListener(this);
   
    //使用模擬器
    //解除感應器註冊
    sensorManager.unregisterListener(this);
    //與感測模擬器斷線
    sensorManager.disconnectSimulator();
    }

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}

@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
//event:onSensorChanged傳入sensor的數值
float[] values = event.values;
//讀取感測器x軸,y軸,z軸的數值
String x = "X:" + String.valueOf(values[0])+"\n";
String y = "Y:" + String.valueOf(values[1])+"\n";
String z = "Z:" + String.valueOf(values[2])+"\n";
//顯示x軸,y軸,z軸在TextView上
TextView xyz=(TextView)findViewById(R.id.xyz);
xyz.setText(x+y+z);
ImageView img=(ImageView)findViewById(R.id.img);
//取得ImageView Layout的參數例如寬、高
LayoutParams params = (LayoutParams)img.getLayoutParams();
//利用X軸的數值設定imageview的寬、高,讓imageview放大縮小
params.width=(int)Math.abs(values[0])*20;
params.height=(int)Math.abs(values[0])*20;
//更新imageview的layout
img.setLayoutParams(params);
}
}












2011年12月9日 星期五

利用Intent傳送簡訊(以模擬器測試)

利用Intent傳送簡訊(以模擬器測試)

當一個SMS訊息被接收時,一個新的Intent由android.provider.Telepony.SMS_RECEIVED動作觸發。現在我們就開始建置一個SMS接收程序:
1)、跟SMS發送程序類似,要在清單文件AndroidManifest.xml中指定權限允許接收SMS:
<uses-permission android:name="android.permission.RECEIVER_SMS"/>

XML

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/widget1" >

    <TextView android:id="@+id/widget2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="寫訊息:"
        android:textSize="16sp"
        android:layout_x="0px"
        android:layout_y="12px"
      >
      </TextView>  
    <EditText android:id="@+id/phone"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:textSize="18sp"
        android:layout_x="60px"
        android:layout_y="2px"
        />
    <EditText android:id="@+id/message"
        android:layout_width="fill_parent"
        android:layout_height="223px"
        android:text=""
        android:textSize="18sp"
        android:layout_x="0px"
        android:layout_y="52px"
        />
 
    <Button android:id="@+id/submit"
        android:layout_width="162px"
        android:layout_height="wrap_content"
        android:text="送出"
        android:layout_x="80px"
        android:layout_y="302px"
        />
</AbsoluteLayout>

JAVA檔

package com.demo.android.Message;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.telephony.gsm.SmsManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MessageActivity extends Activity {
private Button submit;
private EditText phone;
private EditText message;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //利用  findViewById建構子建構元件
        submit = (Button) findViewById(R.id.submit);
        phone = (EditText) findViewById(R.id.phone);
        message = (EditText) findViewById(R.id.message);

        submit.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            //傳入的訊息轉成文字
                String pphone = phone.getText().toString();
                String pmessage = message.getText().toString();
             
                if (phoneNo.length() > 0 && pmessage.length() > 0) {
                //利用Intent傳送資料,創造解析特定編碼URI
                     Intent sms=new Intent(Intent.ACTION_SENDTO,
                    Uri.parse("sms:"+phone.getText().toString()));
                     sms.putExtra("putsms",message.getText().toString());
                     MessageActivity.this.startActivity(sms);
                } else
                    Toast.makeText(getBaseContext(),
                            ".......................................................",
                            Toast.LENGTH_SHORT).show();
             
                phone.setText(" ");
                message.setText(" ");
            }
        });
    }
}




利用Intent將我們的訊息傳遞给內建SMS客戶端發送我們SMS。如果要做到這樣效果,就必須要用到startActivity("指定一個Intent")方法,且指定Intent的動作為Intent.ACTION_SENDTO,用sms:指定目標手機號,用sms_body指定信息內容。


2011年12月5日 星期一

ListView&DateSpicker連接SQLite使用

XML
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
android:id="@+id/absolute"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>

<DatePicker
    android:id="@+id/dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_x="11dp"
    android:layout_y="20dp" />

<Button
    android:id="@+id/insert"
    android:layout_width="77px"
    android:layout_height="wrap_content"
    android:layout_x="26dp"
    android:layout_y="300dp"
    android:text="新增" />
<EditText
    android:id="@+id/note"
    android:layout_width="262px"
    android:layout_height="129px"
    android:layout_x="12dp"
    android:layout_y="158dp"
    android:textSize="18sp" >
</EditText>
<Button
    android:id="@+id/delete"
    android:layout_width="77px"
    android:layout_height="wrap_content"
    android:layout_x="120dp"
    android:layout_y="300dp"
    android:text="刪除" />
<ListView
    android:id="@+id/lv"
    android:layout_width="283dp"
    android:layout_height="136dp"
    android:layout_x="20dp"
    android:layout_y="332dp"
    android:scrollbars="horizontal|vertical" >
</ListView>
</AbsoluteLayout>


package com.demo.android.Note;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class NoteActivity extends Activity {
static String TABLE_NAME="Notes";
     static String ID="_id"; //使用SimpleCursorAdapter欄位名稱必須為_id
     static String DATE="date";
     static String NOTE="note";
     static String[] COLUMNS = { ID, DATE, NOTE };
     //android內建list樣式 
     //android.R.layout.simple_list_item_2
     //android.R.id.hint
     //android.R.id.text1
     //android.R.id.text2
     static int[] TO = { android.R.id.hint, android.R.id.text1, android.R.id.text2};
     long selectedIndex = 0;//儲存點選ListView項目
     
          
     DBConnection dbconn;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
                   
        OnClickListener OnInsertClick=null;
        OnClickListener OnDeleteClick=null;
        //建立資料庫實體
        dbconn=new DBConnection(this);
        
        //ListView顯示Notes表格內容
        show();
        
                
        //建立onInsertclick事件
        OnInsertClick=new OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//取得DatePicker設定的日期
DatePicker dp = (DatePicker)findViewById(R.id.dp); 
String date = dp.getYear()+"/"+(dp.getMonth()+1)+"/"+dp.getDayOfMonth();
String note = ((EditText)findViewById(R.id.note)).getText().toString();
//新增Note
insert( date, note);
//清除EditText
((EditText)findViewById(R.id.note)).setText("");
}
       
        };
        
        //Insert Button 繫結至onInsertclick事件
        Button insert=(Button)findViewById(R.id.insert);
        insert.setOnClickListener(OnInsertClick);
        
      //建立onDelectclick事件
        OnDeleteClick = new OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//刪除所選的資料
delete(selectedIndex);
}
       
        };
        
      //Delete Button 繫結至onDeleteclick事件
        Button delete=(Button)findViewById(R.id.delete);
        delete.setOnClickListener(OnDeleteClick);
        
        ListView lv = (ListView)findViewById(R.id.lv);
        //設定點選ListView的Item事件
        lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View view,
                                           int position, long id) {

//儲存點選編號
selectedIndex = id;
}
        });

        
    }
    
    
    private void show() {
   
   
    SQLiteDatabase db=dbconn.getWritableDatabase();
        Cursor c=null;
        
        //查詢資料 SELECT _id, date, note FROM Notes
        c=db.query(TABLE_NAME, COLUMNS,null, null, null, null, null);     
        
      //使用SimpleCursorAdapter直接將資料表資料顯示至ListView上
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, c, COLUMNS, TO);
    ListView lv = (ListView)findViewById(R.id.lv);
    lv.setAdapter(adapter);
   
    //把建立的Cursor實體交給Activity管理,這樣Cursor對象的生命週期就能和當前的Activity同步
    startManagingCursor(c);
   
    db.close();
    }
    
    private void insert(String date, String note) {
    // 用ContentValues插入資料
    ContentValues values=new ContentValues();
values.put(DATE,date);
values.put(NOTE,note);
SQLiteDatabase db = dbconn.getWritableDatabase();
db.insert(TABLE_NAME, null, values);
db.close();
//ListView顯示Notes表格內容
show();
    }
    
    private void delete(long id) {
    // 刪除代號為id的資
    SQLiteDatabase db = dbconn.getWritableDatabase();
    db.delete(TABLE_NAME, "_id=?" , new String[]{Long.toString(id)});
db.close();
//ListView顯示Notes表格內容
show();
    }
    
}
整個程式流程: 





package com.demo.android.Note;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBConnection extends SQLiteOpenHelper {
 private static final String DATABASE_NAME="FileDB";
    private static final int DATABASE_VERSION=2;
 public DBConnection(Context context) {
  super(context, DATABASE_NAME, null, DATABASE_VERSION);
  // TODO Auto-generated constructor stub
 }
 @Override
 public void onCreate(SQLiteDatabase db) {
  // TODO Auto-generated method stub
  //建立表格
  //空格一定要保留
  String sql = "CREATE TABLE  Notes  (" 
    + " _id INTEGER PRIMARY KEY AUTOINCREMENT, "
    + " date text not null, "
    + " note text not null" + ");";

  db.execSQL(sql);
 }
 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  // TODO Auto-generated method stub

 }
}