在上一篇中有介紹了Wifi與網(wǎng)絡(luò)連接處理

成都創(chuàng)新互聯(lián)是一家專注于網(wǎng)站建設(shè)、成都做網(wǎng)站與策劃設(shè)計(jì),新干網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:新干等地區(qū)。新干做網(wǎng)站價(jià)格咨詢:18982081108
Android開發(fā)之WiFi與網(wǎng)絡(luò)連接處理
下面,來(lái)繼續(xù)說(shuō)說(shuō)Android中藍(lán)牙的基本使用。
Bluetooth是目前使用的最廣泛的無(wú)線通訊協(xié)議之一,主要針對(duì)短距離設(shè)備通訊(10米),常用于連接耳機(jī)、鼠標(biāo)和移動(dòng)通訊設(shè)備等。
值得一提的是:
android4.2新增了部分新功能,但是對(duì)于Bluetooth熟悉的人或許開始頭疼了,那就是Android4.2引入了一個(gè)新的藍(lán)牙協(xié)議棧針BLE。谷歌和Broadcom之間的合作,開發(fā)新的藍(lán)牙協(xié)議棧,取代了基于堆棧的Bluez。因此市場(chǎng)上出現(xiàn)了老設(shè)備的兼容問(wèn)題,很多藍(lán)牙設(shè)備在android4.2手機(jī)上不能正常使用。
BluetoothAdapter簡(jiǎn)單點(diǎn)來(lái)說(shuō)就是代表了本設(shè)備(手機(jī)、電腦等)的藍(lán)牙適配器對(duì)象。
first:we need permission
要操作藍(lán)牙,先要在AndroidManifest.xml里加入權(quán)限
**下面來(lái)看看如何使用藍(lán)牙。 **↓↓↓****
Demo已就緒:
返回值:如果設(shè)備具備藍(lán)牙功能,返回BluetoothAdapter 實(shí)例;否則,返回null對(duì)象。
打開藍(lán)牙設(shè)備的方式:
1.直接調(diào)用函數(shù)enable()去打開藍(lán)牙設(shè)備 ;
2.系統(tǒng)API去打開藍(lán)牙設(shè)備,該方式會(huì)彈出一個(gè)對(duì)話框樣式的Activity供用戶選擇是否打開藍(lán)牙設(shè)備。
注意: 1.如果藍(lán)牙已經(jīng)開啟,不會(huì)彈出該Activity界面。2.在目前大多數(shù)Android手機(jī)中,是不支持在飛行模式下開啟藍(lán)牙的。如果藍(lán)牙已經(jīng)開啟,那么藍(lán)牙的開關(guān) ,狀態(tài)會(huì)隨著飛行模式的狀態(tài)而發(fā)生改變。
1. 搜索藍(lán)牙設(shè)備
使用BluetoothAdapter的startDiscovery()方法來(lái)搜索藍(lán)牙設(shè)備
startDiscovery()方法是一個(gè)異步方法,調(diào)用后會(huì)立即返回。該方法會(huì)進(jìn)行對(duì)其他藍(lán)牙設(shè)備的搜索,該過(guò)程會(huì)持續(xù)12秒。該方法調(diào)用后,搜索過(guò)程實(shí)際上是在一個(gè)System Service中進(jìn)行的,所以可以調(diào)用cancelDiscovery()方法來(lái)停止搜索(該方法可以在未執(zhí)行discovery請(qǐng)求時(shí)調(diào)用)。
系統(tǒng)開始搜索藍(lán)牙設(shè)備
^( *  ̄(oo) ̄ ) ^ 系統(tǒng)會(huì)發(fā)送以下三個(gè)廣播:
2.掃描設(shè)備
3.定義廣播接收器接收搜索結(jié)果
4.注冊(cè)廣播
獲取附近的藍(lán)牙設(shè)備
第一步建立連接:首先Android sdk(2.0以上版本)支持的藍(lán)牙連接是通過(guò)BluetoothSocket建立連接,服務(wù)端BluetoothServerSocket和客戶端(BluetoothSocket)需指定同樣的UUID,才能建立連接,因?yàn)榻⑦B接的方法會(huì)阻塞線程,所以服務(wù)器端和客戶端都應(yīng)啟動(dòng)新線程連接。
(這里的服務(wù)端和客戶端是相對(duì)來(lái)說(shuō)的)
兩個(gè)藍(lán)牙設(shè)備之間的連接,則必須實(shí)現(xiàn)服務(wù)端與客戶端的機(jī)制。
當(dāng)兩個(gè)設(shè)備在同一個(gè)RFCOMM channel下分別擁有一個(gè)連接的BluetoothSocket,這兩個(gè)設(shè)備才可以說(shuō)是建立了連接。
服務(wù)端設(shè)備與客戶端設(shè)備獲取BluetoothSocket的途徑是不同的。
1,服務(wù)端設(shè)備是通過(guò)accepted一個(gè)incoming connection來(lái)獲取的,
2,客戶端設(shè)備則是通過(guò)打開一個(gè)到服務(wù)端的RFCOMM channel來(lái)獲取的。
服務(wù)端
通過(guò)調(diào)用BluetoothAdapter的listenUsingRfcommWithServiceRecord(String, UUID)方法來(lái)獲取BluetoothServerSocket(UUID用于客戶端與服務(wù)端之間的配對(duì))
客戶端
調(diào)用BluetoothService的createRfcommSocketToServiceRecord(UUID)方法獲取BluetoothSocket(該UUID應(yīng)該同于服務(wù)端的UUID)。
調(diào)用BluetoothSocket的connect()方法(該方法為block方法),如果UUID同服務(wù)端的UUID匹配,并且連接被服務(wù)端accept,則connect()方法返回。
數(shù)據(jù)傳遞,通過(guò)以上操作,就已經(jīng)建立的BluetoothSocket連接了,數(shù)據(jù)傳遞無(wú)非是通過(guò)流的形式
獲取流
該類就是關(guān)于遠(yuǎn)程藍(lán)牙設(shè)備的一個(gè)描述。通過(guò)它可以和本地藍(lán)牙設(shè)備---BluetoothAdapter連接通信。
好多東西我也不知道怎么描述,下面給出Demo:
剛好有剛學(xué)習(xí)的小伙伴問(wèn)我ListView怎么用,那我就用ListView。
源碼:
RairDemo
GitHub:
Coding:
1、現(xiàn)在Android智能手機(jī)的像素都會(huì)提供照相的功能,大部分的手機(jī)的攝像頭的像素都在1000萬(wàn)以上的像素,有的甚至?xí)摺K鼈兇蠖喽紩?huì)支持光學(xué)變焦、曝光以及快門等等。下面的程序Demo實(shí)例示范了使用Camera v2來(lái)進(jìn)行拍照,當(dāng)用戶按下拍照鍵時(shí),該應(yīng)用會(huì)自動(dòng)對(duì)焦,當(dāng)對(duì)焦成功時(shí)拍下照片。layout/activity_main.xml界面布局代碼如下:
2、上面的程序的界面提供了一個(gè)自定義TextureView來(lái)顯示預(yù)覽取景,十分簡(jiǎn)單。該自定義TextureView類的代碼如下:
3、接來(lái)了的MainActivity.java程序?qū)?huì)使用CameraManager來(lái)打開CameraDevice,并通過(guò)CameraDevice創(chuàng)建CameraCaptureSession,然后即可通過(guò)CameraCaptureSession進(jìn)行預(yù)覽或拍照了。
Android開發(fā)之ImageView播放GIF動(dòng)畫實(shí)例
Android的原生控件并不支持播放GIF格式的圖片,如果想在Android中顯示一張GIF動(dòng)態(tài)圖片,可以利用 ImageView控件來(lái)完成,但是放進(jìn)去之后,你會(huì)發(fā)現(xiàn),ImageView它只會(huì)顯示這張圖片的第一幀,不會(huì)產(chǎn)生任何的動(dòng)畫效果。我們必須通過(guò)自定義控件的方式來(lái)實(shí)現(xiàn)ImageView播放GIF 圖片的功能。
首先我們來(lái)編寫一個(gè)PowerImageView控件,讓它既能支持ImageView控件原生的所有功能,同時(shí)還可以播放GIF動(dòng)態(tài)圖片。
先新建一個(gè)項(xiàng)目PowerImageViewTest,這里使用Android 4.0+Eclipse。
由于是要自定義控件,會(huì)需要一些自定義的控件屬性,因此我們需要在values目錄下新建一個(gè)attrs.xml的文件,在這個(gè)文件中添加項(xiàng)目需要的自定義屬性。
這里我們目前暫時(shí)只需要一個(gè)自動(dòng)播放auto_play屬性,XML文件代碼如下:
?xml version="1.0" encoding="utf-8"?
這個(gè)文件完成之后,下面我們來(lái)開始編寫主類PowerImageView類,由于PowerImageView類需要支持ImageView的所有功能,我們必須要讓PowerImageView繼承自ImageView,代碼如下:
public class PowerImageView extends ImageView implements OnClickListener {
/**
* 播放GIF動(dòng)畫的關(guān)鍵類
*/
private Movie mMovie;
/**
* 開始播放按鈕圖片
*/
private Bitmap mStartButton;
/**
* 記錄動(dòng)畫開始的時(shí)間
*/
private long mMovieStart;
/**
* GIF圖片的寬度
*/
private int mImageWidth;
/**
* GIF圖片的高度
*/
private int mImageHeight;
/**
* 圖片是否正在播放
*/
private boolean isPlaying;
/**
* 是否允許自動(dòng)播放
*/
private boolean isAutoPlay;
/**
* PowerImageView構(gòu)造函數(shù)。
*
* @param context
*/
public PowerImageView(Context context) {
super(context);
}
/**
* PowerImageView構(gòu)造函數(shù)。
*
* @param context
*/
public PowerImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* PowerImageView構(gòu)造函數(shù),在這里完成所有必要的初始化操作。
*
* @param context
*/
public PowerImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PowerImageView);
int resourceId = getResourceId(a, context, attrs);
if (resourceId != 0) {
// 當(dāng)資源id不等于0時(shí),就去獲取該資源的流
InputStream is = getResources().openRawResource(resourceId);
// 使用Movie類對(duì)流進(jìn)行解碼
mMovie = Movie.decodeStream(is);
if (mMovie != null) {
// 如果返回值不等于null,就說(shuō)明這是一個(gè)GIF圖片,下面獲取是否自動(dòng)播放的屬性
isAutoPlay = a.getBoolean(R.styleable.PowerImageView_auto_play, false);
Bitmap bitmap = BitmapFactory.decodeStream(is);
mImageWidth = bitmap.getWidth();
mImageHeight = bitmap.getHeight();
bitmap.recycle();
if (!isAutoPlay) {
// 當(dāng)不允許自動(dòng)播放的時(shí)候,得到開始播放按鈕的圖片,并注冊(cè)點(diǎn)擊事件
mStartButton = BitmapFactory.decodeResource(getResources(),R.drawable.start_play);
setOnClickListener(this);
}
}
}
}
@Override
public void onClick(View v) {
if (v.getId() == getId()) {
// 當(dāng)用戶點(diǎn)擊圖片時(shí),開始播放GIF動(dòng)畫
isPlaying = true;
invalidate();
}
}
@Override
protected void onDraw(Canvas canvas) {
if (mMovie == null) {
// mMovie等于null,說(shuō)明是張普通的圖片,則直接調(diào)用父類的onDraw()方法
super.onDraw(canvas);
} else {
// mMovie不等于null,說(shuō)明是張GIF圖片
if (isAutoPlay) {
// 如果允許自動(dòng)播放,就調(diào)用playMovie()方法播放GIF動(dòng)畫
playMovie(canvas);
invalidate();
} else {
// 不允許自動(dòng)播放時(shí),判斷當(dāng)前圖片是否正在播放
if (isPlaying) {
// 正在播放就繼續(xù)調(diào)用playMovie()方法,一直到動(dòng)畫播放結(jié)束為止
if (playMovie(canvas)) {
isPlaying = false;
}
invalidate();
} else {
// 還沒(méi)開始播放就只繪制GIF圖片的第一幀,并繪制一個(gè)開始按鈕
mMovie.setTime(0);
mMovie.draw(canvas, 0, 0);
int offsetW = (mImageWidth - mStartButton.getWidth()) / 2;
int offsetH = (mImageHeight - mStartButton.getHeight()) / 2;
canvas.drawBitmap(mStartButton, offsetW, offsetH, null);
}
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mMovie != null) {
// 如果是GIF圖片則重寫設(shè)定PowerImageView的大小
setMeasuredDimension(mImageWidth, mImageHeight);
}
}
/**
* 開始播放GIF動(dòng)畫,播放完成返回true,未完成返回false。
*
* @param canvas
* @return 播放完成返回true,未完成返回false。
*/
private boolean playMovie(Canvas canvas) {
long now = SystemClock.uptimeMillis();
if (mMovieStart == 0) {
mMovieStart = now;
}
int duration = mMovie.duration();
if (duration == 0) {
duration = 1000;
}
int relTime = (int) ((now - mMovieStart) % duration);
mMovie.setTime(relTime);
mMovie.draw(canvas, 0, 0);
if ((now - mMovieStart) = duration) {
mMovieStart = 0;
return true;
}
return false;
}
/**
* 通過(guò)Java反射,獲取到src指定圖片資源所對(duì)應(yīng)的id。
*
* @param a
* @param context
* @param attrs
* @return 返回布局文件中指定圖片資源所對(duì)應(yīng)的id,沒(méi)有指定任何圖片資源就返回0。
*/
private int getResourceId(TypedArray a, Context context, AttributeSet attrs) {
try {
Field field = TypedArray.class.getDeclaredField("mValue");
field.setAccessible(true);
TypedValue typedValueObject = (TypedValue) field.get(a);
return typedValueObject.resourceId;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (a != null) {
a.recycle();
}
}
return 0;
}
}
這個(gè)類的代碼注釋已經(jīng)非常詳細(xì)了,我再來(lái)簡(jiǎn)單地解釋一下。可以看到,我們重寫了ImageView中所有的構(gòu)建函數(shù),使得 PowerImageView的用法可以和ImageView完全相同。在構(gòu)造函數(shù)中,則是對(duì)所有必要的數(shù)據(jù)進(jìn)行了初始化操作。首先,我們調(diào)用了 getResourceId()方法去獲取圖片資源對(duì)應(yīng)的id值,在getResourceId()方法內(nèi)部是通過(guò)Java的反射機(jī)制來(lái)進(jìn)行獲取的。得到了圖片資源的id后,我們將它轉(zhuǎn)換成InputStream,然后傳入到Movie.decodeStream()方法中以解碼出Movie對(duì)象。如果得到的Movie對(duì)象等于null,說(shuō)明這是一張普通的圖片資源,就不再進(jìn)行任何特殊處理,因?yàn)楦割怚mageView都幫我們處理好了。如果得到的 Movie對(duì)象不等于null,則說(shuō)明這是一張GIF圖片,接著就要去獲取是否允許自動(dòng)播放、圖片的寬高等屬性的值。如果不允許自動(dòng)播放,還要給播放按鈕 注冊(cè)點(diǎn)擊事件,默認(rèn)是不允許自動(dòng)播放的。
接下來(lái)會(huì)進(jìn)入到onMeasure()方法中。在這個(gè)方法中我們進(jìn)行判斷,如果這是一張GIF圖片,則需要將PowerImageView的寬高重定義,使得控件的大小剛好可以放得下這張GIF圖片。
再往后就會(huì)進(jìn)入到onDraw()方法中。在這個(gè)方法里同樣先判斷當(dāng)前是一張普通的圖片還是GIF圖片,如果是普通的圖片就直接調(diào)用 super.onDraw()方法交給ImageView去處理就好了。如果是GIF圖片,則先判斷該圖是否允許自動(dòng)播放,允許的話就調(diào)用 playMovie()方法去播放GIF圖片就好,不允許的話則會(huì)先在PowerImageView中繪制該GIF圖片的第一幀,并在圖片上繪制一個(gè)播放 按鈕,當(dāng)用戶點(diǎn)擊了播放按鈕時(shí),再去調(diào)用playMovie()方法去播放GIF圖片。
下面我們來(lái)看看playMovie()方法中是怎樣播放GIF圖片的吧。可以看到,首先會(huì)對(duì)動(dòng)畫開始的時(shí)間做下記錄,然后對(duì)動(dòng)畫持續(xù)的時(shí)間做下記 錄,接著使用當(dāng)前的時(shí)間減去動(dòng)畫開始的時(shí)間,得到的時(shí)間就是此時(shí)PowerImageView應(yīng)該顯示的那一幀,然后借助Movie對(duì)象將這一幀繪制到屏 幕上即可。之后每次調(diào)用playMovie()方法都會(huì)繪制一幀圖片,連貫起來(lái)也就形成了GIF動(dòng)畫。注意,這個(gè)方法是有返回值的,如果當(dāng)前時(shí)間減去動(dòng)畫 開始時(shí)間大于了動(dòng)畫持續(xù)時(shí)間,那就說(shuō)明動(dòng)畫播放完成了,返回true,否則返回false。
完成了PowerImageView的編寫,下面我們就來(lái)看一看如何使用它吧,其實(shí)非常簡(jiǎn)單,打開或新建activity_main.xml,代碼如下所示:
relativelayout p=""
android:layout_width="match_parent"
android:layout_height="match_parent"
com.example.powerimageviewtest.powerimageview p=""
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/anim"
/
可以看到,PowerImageView的用法和ImageView幾乎完全一樣,使用android:src屬性來(lái)指定一張圖片即可,這里指定的anim就是一張GIF圖片。然后我們讓PowerImageView在布局里居中顯示MainActivity中的代碼都是自動(dòng)生成的,這里就不再貼出來(lái)了。在AndroidManifest.xml中還有一點(diǎn)需要注意,有些4.0 以上系統(tǒng)的手機(jī)啟動(dòng)了硬件加速功能之后會(huì)導(dǎo)致GIF動(dòng)畫播放不出來(lái),因此我們需要在AndroidManifest.xml中去禁用硬件加速功能,可以通過(guò)指定android:hardwareAccelerated屬性來(lái)完成,代碼如下所示:
?xml version="1.0" encoding="utf-8"?
manifest p=""
package="com.example.powerimageviewtest"
android:versionCode="1"
android:versionName="1.0"
uses-sdk p=""
android:minSdkVersion="14"
android:targetSdkVersion="17" /
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:hardwareAccelerated="false"
android:name="com.example.powerimageviewtest.MainActivity"
android:label="@string/app_name"
現(xiàn)在可以來(lái)運(yùn)行一下代碼了,一打開程序你就會(huì)看到GIF圖片的第一幀,點(diǎn)擊圖片之后就可以播放GIF動(dòng)畫了。
然后我們還可以通過(guò)修改activity_main.xml中的代碼,給它加上允許自動(dòng)播放的屬性,代碼如下所示:
relativelayout p=""
xmlns:attr=""
android:layout_width="match_parent"
android:layout_height="match_parent"
com.example.powerimageviewtest.powerimageview p=""
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/anim"
attr:auto_play="true"
/
這里使用了剛才我們自定義的屬性,通過(guò)attr:auto_play來(lái)啟用和禁用自動(dòng)播放功能。現(xiàn)在將auto_play屬性指定成true后,PowerImageView上就不會(huì)再顯示一個(gè)播放按鈕,而是會(huì)循環(huán)地自動(dòng)播放動(dòng)畫。不僅如此,PowerImageView還繼承了ImageView原生的所有功能,只要指定的不是GIF圖 片,PowerImageView表現(xiàn)的結(jié)果就和ImageView完全一致,現(xiàn)在我們來(lái)放一張普通的PNG圖片,修改 activity_main.xml中的代碼,如下所示:
relativelayout p=""
android:layout_width="match_parent"
android:layout_height="match_parent"
com.example.powerimageviewtest.powerimageview p=""
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/myphoto"
/
這里在src屬性里面指定了一張名字為myphoto的PNG圖片,圖片在布局正中央顯示出來(lái)了,正是普通ImageView所具備的功能。我們還可以在PowerImageView中指定android:scaleType等屬性,用法和原生的ImageView完全一樣。
本文標(biāo)題:android開發(fā)實(shí)例,android開發(fā)實(shí)例大全源代碼
當(dāng)前URL:http://chinadenli.net/article33/dsejpps.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、關(guān)鍵詞優(yōu)化、網(wǎng)站改版、移動(dòng)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)