Android硬體 - 建國科技大學

stuckwarmersΚινητά – Ασύρματες Τεχνολογίες

14 Δεκ 2013 (πριν από 3 χρόνια και 8 μήνες)

249 εμφανίσεις

Android
硬體

建國科技大學資管系

饒瑞佶

2013/3 V1

Compass

實際硬體

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=
“Compass"


/>

<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"


/>

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>

implements SensorListener


SensorManager

sm
=
null
;




TextView

xViewA
;
// ACCELERATOR


TextView

yViewA
;


TextView

zViewA
;


TextView

xViewO
;
// ORIENTATION


TextView

yViewO
;


TextView

zViewO
;



@Override

protected

void

onCreate
(Bundle
savedInstanceState
) {

super
.onCreate
(
savedInstanceState
);

setContentView
(
R.layout.
compass
);

sm
=(
SensorManager
)
getSystemService
(
SENSOR_SERVICE
);
//
取得系統服務

xViewA
=(
TextView
)
findViewById
(
R.id.
xbox
);

yViewA
=(
TextView
)
findViewById
(
R.id.
ybox
);

zViewA
=(
TextView
)
findViewById
(
R.id.
zbox
);

xViewO
=(
TextView
)
findViewById
(
R.id.
xboxo
);

yViewO
=(
TextView
)
findViewById
(
R.id.
yboxo
);

zViewO
=(
TextView
)
findViewById
(
R.id.
zboxo
);

}

onSensorChanged


public void onSensorChanged(int sensor, float[] values) {


synchronized (this) {


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]);


}


}


}

onResume & onStop

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();


}

Camera

CameraAPI
專案

Camera


使用
Intent
機制


使用
API

Camera by Intent


xml
上需要一個
ImageView

Camera by Intent

Camera by Intent

public 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


}


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, "
使用
䥮瑥湴
拍照完成!
∬"T潡獴o䱅乇呈彌低䜩⹳G潷⠩㬠†


//
利用
ImageView
顯示照片


Bitmap bitmap = BitmapFactory.
decodeFile("/sdcard/test.jpg");


showimg
.setImageBitmap(bitmap); //
利用
ImageView
顯示拍攝的照片


}


}


Camera by API

Camera by API


UI
上設定
surfaceview


<SurfaceView


android:id=
"@+id/surface_view"


android:layout_width=
"wrap_content"


android:layout_height=
"wrap_content" />

Camera by API


開放權限



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



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



自動對焦




<uses
-
feature android:name=
"android.hardware.camera" />



<uses
-
feature
android:name=
"android.hardware.camera.autofocus" />


螢幕轉為橫向顯示


android:screenOrientation="landscape"

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>



<Button
android:text=
"
停止預覽
" android:id="@+id/button2"
android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>


<Button
android:text=
"
拍照
" android:id="@+id/button3" 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>

implements SurfaceHolder.Callback

自動加入

利用
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>

利用
SurfaceView
預覽


//
啟動預覽按鈕


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);

Button start;

Button stop;

Button takephoto;

SurfaceView surfaceView;

SurfaceHolder surfaceHolder;

啟動預覽按鈕

啟動預覽按鈕
-
code

android.hardware.Camera

camera
=
null
;

//
啟動預覽

private

void

start_camera
()


{


try
{


camera

=
android.hardware.Camera.
open
();


}
catch
(
RuntimeException

e){


return
;


}


android.hardware.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
;


}


}

停止預覽按鈕


//
停止預覽


private void stop_camera()


{


camera.stopPreview();


camera.release();


}

加入拍照按鈕


<Button
android:text=
"
拍照
"
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Bu
tton>

拍照按鈕

拍照按鈕

-

code


//
拍照


takephoto = (Button)findViewById(R.id.
button3);


takephoto.setOnClickListener(
new Button.OnClickListener()


{


public void onClick(View arg0) {


camera.takePicture(
shutterCallback, rawPictureCallback,
jpegPictureCallback);


}


});

加入需要的
shutterCallback, rawPictureCallback,
jpegPictureCallback



ShutterCallback shutterCallback =
new ShutterCallback(){



@Override



public void onShutter() {




//
TODO Auto
-
generated method stub


}


};




PictureCallback rawPictureCallback =
new PictureCallback(){

@Override

public void onPictureTaken(byte[] data, android.hardware.Camera camera)
{

//
TODO
自動產生的方法

却畢


}


};


PictureCallback jpegPictureCallback =
new PictureCallback(){


@Override


public void onPictureTaken(byte[] arg0,
android.hardware.
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/DCI
M/abcd.jpg"));


imageFileOS.write(arg0);


imageFileOS.flush();


imageFileOS.close();


Toast.
makeText(CameraAPI.
this, "
拍照完成
!∬"潡獴o䱅乇呈彌低䜩⹳G潷⠩o


}
catch (FileNotFoundException e) {


e.printStackTrace();


}
catch (IOException e) {


e.printStackTrace();


}




}


};

Bluetooth

開啟權限



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



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



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

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"));

Result (I)


Emulator


無法實際動作

Result (II)

Samsung Nexus S


Android 4.1.1

HTC Desire


Android 2.3

提醒


手機需要開啟藍芽


需要設定成可以被偵測

Proximity

Proximity


接近感測器


偵測

Android
手機靠近臉時做一些動作,例
如禁用觸摸功能或關閉螢幕

建立
Proximity
物件

建立
Proximity
物件

-

code

SensorManager mySensorManager;
//
開啟
sensoe
管理器

Sensor myProximitySensor;
//
建立
proximity
物件

@Override

protected 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);

}

}

建立
listener
物件

建立
listener
物件

-

code

SensorEventListener 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


}


}


};

利用聲音來測試

ToneGenerator

tg
;

tg
=
new

ToneGenerator
(AudioManager.
STREAM_NOTIFICATION
,100);

利用聲音來測試

tg
.startTone
(
ToneGenerator.
TONE_PROP_BEEP
);

WiFi

WiFiDemo
專案

開啟權限


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



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

註冊
receiver


<receiver android:name=
".WiFiScanReceiver">


<intent
-
filter>


<action android:name=
"com.example" />


</intent
-
filter>


</receiver>

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>

private static final String
TAG = "WiFiDemo"; // log
記錄用

WifiManager wifi; // WiFi
管理者

BroadcastReceiver receiver; //
Brodcast


TextView textStatus;

Button buttonScan;

掃描
wifi

取得
wifi
狀態

@Override

protected

void

onCreate(Bundle savedInstanceState) {


super
.onCreate(savedInstanceState);


setContentView(R.layout.
wifi
);


//
對應
UI
上的
view


textStatus

= (TextView) findViewById(R.id.
textStatus
);


buttonScan

= (Button) findViewById(R.id.
buttonScan
);


buttonScan
.setOnClickListener(WIFI.
this
);



//
設定

WiFi


wifi

= (WifiManager) getSystemService(Context.
WIFI_SERVICE
);


//
取得

WiFi
狀態


WifiInfo info =
wifi
.getConnectionInfo();


textStatus
.append(
"
\
n
\
nWiFi
狀態
: "

+ info.toString());


//
列出可用的無線網路


List<WifiConfiguration> configs =
wifi
.getConfiguredNetworks();


for

(WifiConfiguration config : configs) {


textStatus
.append(
"
\
n
\
n"

+ config.toString());


}


//
註冊
Broadcast Receiver


if

(
receiver

==
null
)
receiver

=
new

WiFiScanReceiver(
this
);



registerReceiver(
receiver
,
new

IntentFilter(WifiManager.
SCAN_RESULTS_AVAILABLE_ACTION
));

}



public

void

onClick(View view) {


Toast.
makeText(
this
,
"
掃描完畢
℡™
ⱔ,慳琮
䱅L䝔䡟H低G
)⹳.潷⠩(


if

(view.getId() == R.id.
buttonScan
) {


wifi
.startScan();


}

}

Class WiFiScanReceiver

import

java.util.List;

import

android.content.BroadcastReceiver;

import

android.content.Context;

import

android.content.Intent;

import

android.net.wifi.ScanResult;

import

android.net.wifi.WifiManager;

import

android.widget.Toast;


public

class

WiFiScanReceiver
extends

BroadcastReceiver {


WIFI
wifiDemo
;



public

WiFiScanReceiver(WIFI 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

WiFi
網路,

%s
是訊號最強的一個
"
,


results.size(), bestSignal.
SSID
);


Toast.
makeText(
wifiDemo
, message, Toast.
LENGTH_LONG
).show();


}

}

Result

記得開
WiFi
功能