android 硬體
DESCRIPTION
Android 硬體. 建國科技大學資管系 饒瑞佶 2013/3 V1. Camera. CameraAPI 專案. Camera. 使用 Intent 機制 使用 API. Camera by Intent. Main.xml 上需要一個 ImageView. Camera by Intent. Camera by Intent. public class HelloCamera extends Activity { private static int TAKE_PICTURE = 1; //Intent 回應 - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/1.jpg)
Android 硬體
建國科技大學資管系饒瑞佶
2013/3 V1
![Page 2: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/2.jpg)
CameraCameraAPI 專案
![Page 3: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/3.jpg)
Camera
• 使用 Intent 機制• 使用 API
![Page 4: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/4.jpg)
Camera by Intent
• Main.xml 上需要一個 ImageView
![Page 5: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/5.jpg)
Camera by Intent
![Page 6: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/6.jpg)
Camera by Intentpublic class HelloCamera extends Activity { private static int TAKE_PICTURE = 1; //Intent回應 private Uri outputFileUri; public ImageView showimg; // 顯示拍攝的照片
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.hello_camera); showimg=(ImageView)findViewById(R.id.imageView1); // 顯示照片用 TakePhoto(); // 呼叫 Intent }
![Page 7: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/7.jpg)
Camera by Intent // 拍照用 Intent private void TakePhoto() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 儲存到 sdcard 上,檔名為 test.jpg File file = new File(Environment.getExternalStorageDirectory(), "test.jpg"); outputFileUri = Uri.fromFile(file); intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); startActivityForResult(intent, TAKE_PICTURE); }
// Intent 完成後 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ if (requestCode == TAKE_PICTURE){ //顯示儲存照片路徑與檔名 Toast.makeText(this, "使用 Intent拍照完成! ", Toast.LENGTH_LONG).show(); // 利用 ImageView 顯示照片 Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test.jpg"); showimg.setImageBitmap(bitmap); // 利用 ImageView 顯示拍攝的照片 } }}
![Page 8: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/8.jpg)
Camera by API
![Page 9: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/9.jpg)
Camera by API
• UI 上設定 surfaceview
<SurfaceView android:id="@+id/surface_view" android:layout_width="wrap_content" android:layout_height="wrap_content" />
![Page 10: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/10.jpg)
Camera by API
• 開放權限– <uses-permission
android:name="android.permission.CAMERA"/>– <uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
• 自動對焦 – <uses-feature android:name="android.hardware.camera" />
– <uses-feature
android:name="android.hardware.camera.autofocus" />• 螢幕轉為橫向顯示
– android:screenOrientation="landscape"
![Page 11: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/11.jpg)
Camera by API• UI
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:weightSum="1"> <LinearLayout android:layout_height="wrap_content" android:id="@+id/linearLayout1" android:layout_width="fill_parent"> <SurfaceView android:id="@+id/surfaceView1" android:layout_width="250dp" android:layout_height="250dp" /> <Button android:text=" 拍照 " android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> <ImageView android:id="@+id/imageView1" android:layout_width="250dp" android:layout_height="250dp" /> </LinearLayout></LinearLayout>
![Page 12: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/12.jpg)
implements SurfaceHolder.Callback
自動加入
![Page 13: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/13.jpg)
利用 SurfaceView 預覽• UI 上加上兩個按鈕
– <Button android:text=" 啟動預覽 " android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
– <Button android:text=" 停止預覽 " android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
![Page 14: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/14.jpg)
利用 SurfaceView 預覽
![Page 15: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/15.jpg)
利用 SurfaceView 預覽 -code // 啟動預覽按鈕 start = (Button)findViewById(R.id.button1); start.setOnClickListener(new Button.OnClickListener() { public void onClick(View arg0) { start_camera(); } }); // 停止預覽 stop = (Button)findViewById(R.id.button2); stop.setOnClickListener(new Button.OnClickListener() { public void onClick(View arg0) { stop_camera(); } }); surfaceView = (SurfaceView)findViewById(R.id.surfaceView1); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
![Page 16: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/16.jpg)
啟動預覽按鈕
![Page 17: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/17.jpg)
啟動預覽按鈕 -code // 啟動預覽 private void start_camera() { try{ camera = Camera.open(); }catch(RuntimeException e){ return; } Camera.Parameters param; param = camera.getParameters(); // 設定參數 param.setPreviewFrameRate(20); param.setPreviewSize(176, 144); camera.setParameters(param); try { camera.setPreviewDisplay(surfaceHolder); camera.startPreview(); } catch (Exception e) { return; } }
![Page 18: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/18.jpg)
停止預覽按鈕
// 停止預覽 private void stop_camera() { camera.stopPreview(); camera.release(); }
![Page 19: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/19.jpg)
加入拍照按鈕• <Button android:text=" 拍照 "
android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
![Page 20: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/20.jpg)
拍照按鈕
![Page 21: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/21.jpg)
拍照按鈕 - code
// 拍照 takephoto = (Button)findViewById(R.id.button3); takephoto.setOnClickListener(new Button.OnClickListener() { public void onClick(View arg0) { camera.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback); } });
![Page 22: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/22.jpg)
加入需要的 shutterCallback, rawPictureCallback, jpegPictureCallback
![Page 23: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/23.jpg)
ShutterCallback shutterCallback = new ShutterCallback(){ @Override public void onShutter() { // TODO Auto-generated method stub } }; PictureCallback rawPictureCallback = new PictureCallback(){ @Override public void onPictureTaken(byte[] arg0, Camera arg1) { // TODO Auto-generated method stub } };
![Page 24: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/24.jpg)
PictureCallback jpegPictureCallback = new PictureCallback(){ @Override public void onPictureTaken(byte[] arg0, Camera arg1) { // TODO Auto-generated method stub Bitmap bitmapPicture = BitmapFactory.decodeByteArray(arg0, 0, arg0.length); // 存檔到 sdcard OutputStream imageFileOS; try { imageFileOS = new FileOutputStream(String.format("/sdcard/DCIM/abcd.jpg")); imageFileOS.write(arg0); imageFileOS.flush(); imageFileOS.close(); Toast.makeText(CameraAPI.this, "拍照完成 !",Toast.LENGTH_LONG).show(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } };
![Page 25: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/25.jpg)
Compasseyeeyes 專案
![Page 26: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/26.jpg)
UI (I)<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="Accelerometer" /><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="X Value" android:id="@+id/xbox" /><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Y Value" android:id="@+id/ybox" />
![Page 27: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/27.jpg)
UI (II)<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Z Value" android:id="@+id/zbox" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Orientation" /><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="X Value" android:id="@+id/xboxo" /><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Y Value" android:id="@+id/yboxo" /><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Z Value" android:id="@+id/zboxo" />
</LinearLayout>
![Page 28: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/28.jpg)
implements SensorListener
![Page 29: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/29.jpg)
onSensorChanged
public void onSensorChanged(int sensor, float[] values) { synchronized (this) { Log.d(tag, "onSensorChanged: " + sensor + ", x: " + values[0] + ", y: " + values[1] + ", z: " + values[2]); if (sensor == SensorManager.SENSOR_ORIENTATION) { xViewO.setText("Orientation X: " + values[0]); yViewO.setText("Orientation Y: " + values[1]); zViewO.setText("Orientation Z: " + values[2]); } if (sensor == SensorManager.SENSOR_ACCELEROMETER) { xViewA.setText("Accel X: " + values[0]); yViewA.setText("Accel Y: " + values[1]); zViewA.setText("Accel Z: " + values[2]); } } }
![Page 30: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/30.jpg)
onResume & onStop
![Page 31: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/31.jpg)
onResume & onStop - code
@Override protected void onResume() { super.onResume(); sm.registerListener(this, SensorManager.SENSOR_ORIENTATION | SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onStop() { sm.unregisterListener(this); super.onStop(); }
![Page 32: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/32.jpg)
BluetoothBT_Intent 專案
![Page 33: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/33.jpg)
開啟權限– <uses-permission
android:name="android.permission.BLUETOOTH"/>
– <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
– <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
![Page 34: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/34.jpg)
BT by Intent
Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://mnt/sdcard/test.txt")); startActivity(Intent.createChooser(intent, "xxxxx"));
![Page 35: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/35.jpg)
Result (I)
• Emulator
• 無法實際動作
![Page 36: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/36.jpg)
Result (II)
Samsung Nexus S – Android 4.1.1 HTC Desire– Android 2.3
![Page 37: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/37.jpg)
提醒• 手機需要開啟藍芽• 需要設定成可以被偵測
![Page 38: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/38.jpg)
ProximityHello_proximity 專案
![Page 39: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/39.jpg)
Proximity
• 接近感測器• 偵測 Android 手機靠近臉時做一些動作,例如禁用觸摸功能或關閉螢幕
![Page 40: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/40.jpg)
建立 Proximity 物件
![Page 41: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/41.jpg)
建立 Proximity 物件 - codeSensorManager mySensorManager; // 開啟 sensoe 管理器Sensor myProximitySensor; // 建立 proximity 物件
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.hello_proximity);
mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);myProximitySensor = mySensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); if (myProximitySensor == null){ // 沒有 Proximity 感測器 }else{ mySensorManager.registerListener(proximitySensorEventListener, myProximitySensor,SensorManager.SENSOR_DELAY_NORMAL);}}
![Page 42: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/42.jpg)
建立 listener 物件
![Page 43: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/43.jpg)
建立 listener 物件 - codeSensorEventListener proximitySensorEventListener = new SensorEventListener(){ @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub } @Override public void onSensorChanged(SensorEvent event) { // TODO Auto-generated method stub if(event.sensor.getType()==Sensor.TYPE_PROXIMITY){ //do something } } };
![Page 44: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/44.jpg)
利用聲音來測試
![Page 45: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/45.jpg)
利用聲音來測試
![Page 46: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/46.jpg)
WiFiWiFiDemo 專案
![Page 47: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/47.jpg)
開啟權限– <uses-permission
android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
– <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
![Page 48: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/48.jpg)
註冊 receiver
<receiver android:name=".WiFiScanReceiver"> <intent-filter> <action android:name="com.example" /> </intent-filter> </receiver>
![Page 49: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/49.jpg)
Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/buttonScan" android:text="Scan"></Button> <ScrollView android:id="@+id/ScrollView01" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/textStatus" android:text="WiFiDemo" /> </ScrollView>
</LinearLayout>
![Page 50: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/50.jpg)
private static final String TAG = "WiFiDemo"; // log記錄用WifiManager wifi; // WiFi 管理者BroadcastReceiver receiver; // Brodcast
TextView textStatus;Button buttonScan;
![Page 51: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/51.jpg)
![Page 52: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/52.jpg)
@Overridepublic void onStop() {unregisterReceiver(receiver);}
public void onClick(View view) {Toast.makeText(this, "On Click Clicked. Toast to that!!!",Toast.LENGTH_LONG).show();
if (view.getId() == R.id.buttonScan) {Log.d(TAG, "onClick() wifi.startScan()");wifi.startScan();}}
![Page 53: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/53.jpg)
Class WiFiScanReceiver
![Page 54: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/54.jpg)
Class WiFiScanReceiver - demopublic class WiFiScanReceiver extends BroadcastReceiver { private static final String TAG = "WiFiScanReceiver"; WiFiDemo wifiDemo;
public WiFiScanReceiver(WiFiDemo wifiDemo) { super(); this.wifiDemo = wifiDemo; }
@Override public void onReceive(Context c, Intent intent) { List<ScanResult> results = wifiDemo.wifi.getScanResults(); ScanResult bestSignal = null; for (ScanResult result : results) { if (bestSignal == null || WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0) bestSignal = result; }
String message = String.format("%s networks found. %s is the strongest.", results.size(), bestSignal.SSID); Toast.makeText(wifiDemo, message, Toast.LENGTH_LONG).show();
Log.d(TAG, "onReceive() message: " + message); }
}
![Page 55: Android 硬體](https://reader033.vdocuments.net/reader033/viewer/2022061503/5681349a550346895d9b9249/html5/thumbnails/55.jpg)
Result
記得開 WiFi 功能