2011年4月18日 星期一

OnTouchEvent偵測

OnTouchEvent偵測
透過下列程式,可偵測Touch的動作
MotionEvent.ACTION_DOWN:壓下時觸發
MotionEvent.ACTION_MOVE:移動時觸發
MotionEvent.ACTION_UP:離開時觸發
    public boolean onTouchEvent(MotionEvent event){
        switch(event.getAction()) {
        case MotionEvent.ACTION_DOWN :
            temp_x = (int) event.getX();
            temp_y = (int) event.getY();
            break;
        case MotionEvent.ACTION_MOVE :
            break;
        case MotionEvent.ACTION_UP :
            break;
        default :
            break;
        }
        return false; 
    }

event.getPointerCount() get count number

Accelerometer感測器

Accelerometer感測器
加速度感測器,主要運用於感應手機的運動
values[0]:空間座標中X軸方向上的加速度減去重力加速度在X軸的分量。
values[1]:空間座標中Y軸方向上的加速度減去重力加速度在Y軸的分量。
values[2]:空間座標中Z軸方向上的加速度減去重力加速度在Z軸的分量。

    // 設定感測器
    sm = (SensorManager) getSystemService(SENSOR_SERVICE);
    Sensor sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sm.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_NORMAL);

    // 接收感測器資訊
    SensorEventListener lsn = new SensorEventListener() {
        public void onAccuracyChanged(Sensor sensor, int accuracy) { }
        public void onSensorChanged(SensorEvent event) {
            gsensor_info.setText(
                "(x,y,z) = (" +  event.values[0] + "," + event.values[1] + "," + event.values[2] + ")");
        }
    };

Application類別

Application類別
新增一AP屬性的Class
然後可以透過getApplicationContext()的方式
即可使用共用的API

    API.java
    public class API extends Application {
        public void initial() {
            // write initial in this
        }
        public Class<?> next_test() {
            return finish.class;
        }
    }

    xxx.java
    API function = ((API)getApplicationContext());
    function.initial();

    Intent trigger = new Intent();
    trigger.setClass(xxx.this, function.next_test());
    startActivity(trigger);
    finish();

DisplayResolution資訊

DisplayResolution資訊
透過DisplayMetrics物件,可以抓取目前顯示面板的相關資訊

    public class displayresolution extends Activity {
        public void onCreate(Bundle savedInstanceState) {
            ..........
            DisplayMetrics dm = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(dm);
            textScreen.setText(
                "Screen Width: " + String.valueOf(dm.widthPixels) + "\n" +
                "Screen Height: " + String.valueOf(dm.heightPixels) + "\n" +
                "Density: " + String.valueOf(dm.density) + "\n" +
                "DensityDPI: " + String.valueOf(dm.densityDpi) + "\n" +
                "Scaled Density: " + String.valueOf(dm.scaledDensity) + "\n" +
                "X DPI: " + String.valueOf(dm.xdpi) + "\n" +
                "Y DPI: " + String.valueOf(dm.ydpi) + "\n");
        }
    }

2011年4月15日 星期五

Battery資訊

Battery資訊
利用BroadcastReceiverIntentFilter物件偵測Battery資訊
    public void onCreate() {
        .......
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(mBroadcastReceiver, filter);
    }

    public void onDestroy() {
        .............
        unregisterReceiver(mBroadcastReceiver);
    }

    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                // status
                switch (intent.getIntExtra("status", 0)) {
                case BatteryManager.BATTERY_STATUS_UNKNOWN:
                    statusString = "unknown";
                    break; 
                case BatteryManager.BATTERY_STATUS_CHARGING:
                    statusString = "charging";
                    break; 
                case BatteryManager.BATTERY_STATUS_DISCHARGING:
                    statusString = "discharging";
                    break;
                case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
                    statusString = "not charging";
                    break;
                case BatteryManager.BATTERY_STATUS_FULL:
                    statusString = "full";
                    break;
                default:
                    statusString = "unknown";
                    break;
                }
                // health
                switch (intent.getIntExtra("health", 0)) {
                case BatteryManager.BATTERY_HEALTH_UNKNOWN:
                    healthString = "unknown";
                    break;
                case BatteryManager.BATTERY_HEALTH_GOOD:
                    healthString = "good";
                    break;
                case BatteryManager.BATTERY_HEALTH_OVERHEAT:
                    healthString = "over heat";
                    break;
                case BatteryManager.BATTERY_HEALTH_DEAD:
                    healthString = "dead";
                    break;
                case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
                    healthString = "over voltage";
                    break;
                case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
                    healthString = "unspecified failure";
                    break;
                default:
                    healthString = "unknown";
                    break;
                }
                // plugged
                switch (intent.getIntExtra("plugged", 0)) {
                case BatteryManager.BATTERY_PLUGGED_AC:
                    acString = "plugged ac";
                    break;
                case BatteryManager.BATTERY_PLUGGED_USB:
                    acString = "plugged usb";
                    break;
                default :
                    acString = "disconnect";
                    break;
                }
                // others
                boolean present = intent.getBooleanExtra("present", false);
                int level = intent.getIntExtra("level", 0);
                int scale = intent.getIntExtra("scale", 0);
                int icon_small = intent.getIntExtra("icon-small", 0);
                int voltage = intent.getIntExtra("voltage", 0);
                int temperature = intent.getIntExtra("temperature", 0);
                String technology = intent.getStringExtra("technology");
            }
        }
    };

MediaPlayer物件

MediaPlayer物件
Audio Play
    使用MediaPlayer物件撥放聲音,可以從不同的來源設定,其使用的方式也不相同。
    1. 本地端(包含在APK裡的檔案)
        private MediaPlayer mediaPlayer = null;

        // Start Play Audio
        private OnClickListener start = new OnClickListener() {
            public void onClick(View v) {
                // 直接從本地端讀取音源檔
                mediaPlayer = MediaPlayer.create(AudioPlay.this, R.raw.test);
                try {
                    mediaPlayer.start();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
                btn_start.setEnabled(false);
                btn_stop.setEnabled(true);
            }
        };

        // Stop Play Audio
        private OnClickListener stop = new OnClickListener() {
            public void onClick(View v) {
                mediaPlayer.stop();
                // 結束時把控制全釋放,避免占用資源
                mediaPlayer.release();
                mediaPlayer = null;
                btn_start.setEnabled(true);
                btn_stop.setEnabled(false);
            }
        };

        // 銷毀,當不正常結束的情形發生時的處理動作
        public void onDestroy() {
            super.onDestroy();
            // 避免物件為"空"時,使用屬性發生錯誤
            if (mediaPlayer != null) {
                mediaPlayer.stop();
                mediaPlayer.release();
                mediaPlayer = null;
            }
        }

    2. 外部裝置或路徑
        // Use sd card resource
        bplay.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {
                try {
                    mp.setDataSource("/sdcard/Christina - Fighter.mp3");
                    mp.prepare();
                    mp.start();
                    bmsg.setText("Playing...");
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

Video Play
撥放影音需用到SurfaceView物件
    main.xml    <SurfaceView
        android:id="@+id/surface"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_gravity="center"/>

    Xxx.java
    private MediaPlayer mMediaPlayer;
    private SurfaceView mPreview;
    private SurfaceHolder holder;

    // 初始化,並設定holder
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mPreview = (SurfaceView) findViewById(R.id.surface);
        holder = mPreview.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    }

    // 初始化及設定MediaPlayer物件
    private void playVideo() {
        doCleanUp();
        try {
            path = "/sdcard/test.mp4";
            // Create a new media player and set the listeners
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(path);
            mMediaPlayer.setDisplay(holder);
            mMediaPlayer.prepare();
            mMediaPlayer.setOnBufferingUpdateListener(this);
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setOnVideoSizeChangedListener(this);
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
        catch (Exception e) {
        }
    }

    // Called to update status in buffering a media stream(非必要)
    public void onBufferingUpdate(MediaPlayer arg0, int percent) { }

    // 當影片播放結束,進入onCompletion狀態(非必要)
    // 若是要重複播放,可以參考下列流程控制
    // 或是在playVideo加入"mMediaPlayer.setLooping(true)"
    public void onCompletion(MediaPlayer arg0) {
        mMediaPlayer.stop();
        try {
            mMediaPlayer.prepare();
        }
        catch (IllegalStateException e) { }
        catch (IOException e) { }
        mMediaPlayer.start();
    }

    // 讀取影片畫面大小
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        if (width == 0 || height == 0) {
            return;
        }
        mIsVideoSizeKnown = true;
        mVideoWidth = width;
        mVideoHeight = height;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
            startVideoPlayback();
        }
    }

    // 準備狀態
    public void onPrepared(MediaPlayer mediaplayer) {
        mIsVideoReadyToBePlayed = true;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
            startVideoPlayback();
        }
    }

    // for "SurfaceHolder.Callback" use
    public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) { }
    public void surfaceDestroyed(SurfaceHolder surfaceholder) { }
    public void surfaceCreated(SurfaceHolder holder) {
        playVideo();
    }

    protected void onDestroy() {
        super.onDestroy();
        releaseMediaPlayer();
        doCleanUp();
    }

    private void releaseMediaPlayer() {
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    private void doCleanUp() {
        mVideoWidth = 0;
        mVideoHeight = 0;
        mIsVideoReadyToBePlayed = false;
        mIsVideoSizeKnown = false;
    }

    // strat to play
    private void startVideoPlayback() {
        holder.setFixedSize(mVideoWidth, mVideoHeight);
        mMediaPlayer.start();
    }

KeyEven接收

KeyEven接收
擷取按Key的動作

    public boolean dispatchKeyEvent(KeyEvent event) {
        switch (event.getKeyCode()){
        case KeyEvent.KEYCODE_MENU:
            break;
        case KeyEvent.KEYCODE_BACK:
            break;
        case KeyEvent.KEYCODE_VOLUME_UP:
            break;
        case KeyEvent.KEYCODE_VOLUME_DOWN:
            break;
        default:
            break;
        }
    }

// 目前"POWER"及"HOME"還不清楚要怎麼做
// Android OS限制?