第一篇:Android開發中顏色的自定義方法
歡迎登錄清源教育官方網站www.tmdps.cn 查看更多視頻教程
Android開發中顏色的自定義方法
1、使用Color類的常量,如:
int color = Color.BLUE;// 創建一個藍色 是使用Android提供的顏色
int color = Color.RED;int color = Color.WHITE;
2、通過ARGB構建,如:
int color = Color.argb(127, 255, 0, 255);// 半透明的紫色
其中第一個參數表示透明,0表示完全透明,255(ff)表示完全不透明;后三位分別代表RGB的值了。
3、使用XML資源文件來定義顏色
該方法擴展性好,便于修改和共享,如在values目錄下創建一個color.xml:
android:textColor= “@drawable/mycolor” Java代碼中可以使用ResourceManager類中的getColor來獲取該顏色:
int color = getResources().getColor(R.color.mycolor);
這與第二種方法得到的值是一樣的,getResources()方法返回當前活動Activity的ResourceManager類實例。
說明:XML定義方法接受6位和8位兩種表示法,而且開頭必須是#,8位定義時前兩位表示透明。
4、直接定義色值,如:
int color = 0xff00ff00;這種方法必須使用0x開頭,而不是用我們常用的#。與方法3不一樣,值也必須用8位表示,不接受6位的顏色表示。分組一下0x|ff|ff00ff,0x是代表顏色整數的標記,ff是表示透明度,ff00ff表示RGB顏色值。
=======================
補充一點Android布局中背景圖片的設置(編輯LinearLayout):
* 可以使用純色:android:background=“@drawable/mycolor”(XML資源文件中定義的顏色)* 也可使用圖片:android:background=“@drawable/bg”(需要將一個名為bg.jpg或png的圖片拷貝到res/drawable-hdpi目錄下)
來源:清源教育
第二篇:android 開發心得
即 使你的應用程序是快速且響應靈敏的,但一些設計仍然會給用戶造成問題——與其它應用程序或對話框未事先計劃的交互,意外的數據丟失,意料之外的阻塞等等。避免這些問題,有助于理解應用程序運行的上下文和系統的交互過程,而這些又正影響著你的應用程序。簡而言之,你應該竭盡全力去開發一個與系統和其它應用程 序流暢交互的應用程序。
一 個常見的流暢問題是,一個應用程序的后臺處理——例如,一個 Service或者
BroadcastReceiver——彈出一個對話框來響應一些事件。這可能看起來沒啥大礙,尤其是你在模擬器上單獨地構建和測試你 的應用程序的時候。然而,當你的應用程序運行在真機上時,有可能你的應用程序在沒有獲得用戶焦點時后臺處理顯示了一個對話框。因此,可能會出現在活躍的應 用程序后方顯示了你的應用程序的對話框,或者從當前應用程序奪取焦點顯示了一個對話框,而不管當前用戶正在做什么(例如,正在打電話)。那種行為,對應用 程序或用戶來說,就不應該出現。
為了避免這些問題,你的應用程序應該使用合適的系統資源來通知用戶——Notification類。使用Notification,你的應用程序可以在狀態欄顯示一個 icon來通知用戶已經發生的事情,而不是奪取焦點和打斷用戶。
另 一個流暢問題的例子是未能正確實現Activity的 onPause()和其它生命周期方法而造成意外丟失了狀態或用戶數據。又或者,如果你的應用程序想暴露數據給其它應用程序使用,你應該通過 ContentProvider來暴露,而不是(舉例)通過一個可讀的原始文件或數據庫來實現。
這 些例子的共同點是它們都應該與系統和其它應用程序協作好。Android系統設計時,就把應用程序看作是一堆松散耦合的組件,而不是一堆黑盒代碼。作為開 發者來說,允許我們把整個系統看作是更大的組件集合。這有益于我們可以與其它應用程序進行清晰無縫的集成,因此,作為回報,我們應該更好的設計我們的代 碼。
下面將討論常見的流暢問題以及如何避免它們:
一 定要記住Android是一個移動平臺??梢燥@而易見地說,其它Activity(例如,“Incoming Phone Call”應用程序)可能會在任何時候彈出來遮蓋你的Activity,記住這個事實很重要。因為這個過程將觸發 onSaveInstanceState()和 onPause()方法,并可能導致你的應用程序
被殺死。
如 果用戶在你的應用程序中正在編輯數據時,其它 Activity出現了,這時,你的應用程序被殺死時可能丟失那些數據。當然了,除非你事先保存了正在進行的工作?!癆ndroid方式”是這樣做的:能 接收和編輯用戶輸入的 Android應用程序應該重寫 onSaveInstanceState()方法,并以恰當的方式保存它們的狀態。當用戶重新訪問應用程序時,她能得到她的數據。進行這種處理方式最經典的例子是 mail應用程序。如果用戶正在輸入 email,這時其它 Activity啟動了,mail應用程序應該把正在編輯的email以草稿的方式保存起來。
如果你不想穿著內衣在大街上溜達的話,你的數據也不應該這樣。盡管可能存在暴露應用程序的某種形式給其它應用程序,但這通常不是最好的主意。暴露原始數據,要求其它應用程序能夠理解你的數據的格式;如果你變更了格式,那么,你將破壞那些沒有進行同步更新的應用程序。
“Android 方式”是創建一個 ContentProvider,以一種清晰的、深思熟慮的和可維護的API方式暴露你的數據給其它應用程序。使用 ContentProvider,就好像是插入Java接口來分離和組裝兩片高耦合的代碼。這意味著你可以修改數據的內部格式,而不用修改由 ContentProvider暴露的接口,這樣,也不會影響其它應用程序。
如果用戶正在運行一個應用程序(例如,Phone程序),斷定對用戶操作的目的才是安全的。這也就是為什么必須避免創建Activity,而是直接在當前的 Activity中響應用戶的輸入。那 就是說,不要在 BroadcastReceiver或在后臺運行的 Service中調用 callActivity()。這么做會中斷當前運行的應用程序,并導致用戶惱怒。也許更糟糕的是,你的 Activity可能成為“按鍵強盜”,竊取了用戶要提供給前一個 Activity的輸入。視乎你的應用程序所做的事情,這可能是個壞消息。
不 選擇在后臺直接創建 Activity UI,取而代之的是,應該使用NotificationManager來設置 Notification。它們會出現在狀態欄,并且用戶可以在他空閑的時候點擊它們,來查看你的應用程序向他顯示了什么。(注意,如果你的 Activity已經在前臺了,以上將不適用:這時,對于用戶的輸入,用戶期望的是看到下一個 Activity來響應)
如果你的應用程序需要執行一些昂貴或耗時的計算的話,你應該盡可能地將它挪到線程里。這將阻止向用戶顯示可怕的“Application Not Responding”對話框,如果不這樣做,最終的結果會導致你的應用程序完全終止。
一 般情況下,Activity中的所有代碼,包括它的 View,都運行在相同的線程里。在這個線程里,還需要處理UI事件。例如,當用戶按下一個按鍵,一個 key-down事件就會添加到 Activity的主線程隊列里。事件處理系統需要很快讓這個事件出列并得到處理;如果沒有,系統數秒后會認為應用程序已經掛起并為用戶提供殺死應用程序 的機會。
如果有耗時的代碼,內聯在Activity上運行也就是運行在事件處理線程里,這在很大程度上阻塞了事件處理。這會延遲輸入處理,并導致ANR對話框。為了避免這個,把你的計算移到線程里。
任 何值得使用的應用程序都可能有幾個不同的屏幕。當設計UI屏幕時,請一定要使用多個Activity對象實例。依賴于你的開發背景,你可能理解 Activity類似于 Java Applet,它是你應用程序的入口點。然而,那并不精確:Applet子類是一個 Java Applet的單一入口點,而一個Activity應該看作是你的應用程序多個潛在入口點之一。你的“main”Activity和其它之間的唯一不同點 是“main”Activity正巧是在AndroidManifest.xml文件中唯一對“android.intent.action.MAIN”動作感興趣的Activity。因此,當設計你的應用程序的時候,把你的應用程序看作是Activity對象的 集合。從長遠來看,這會使得你的代碼更加方便維護。
當 談到 UI觀感時,巧妙地交融非常重要。用戶在使用與自己期望相反的 UI的應用程序時,會產生不愉快的感覺。當設計你的 UI時,你應該盡量避免太多自己的主題。相反的,使用同一個主題。你可以重寫或擴展你需要的主題部分,但至少在與其它應用程序相同的 UI基礎上開始。
不 同的 Android設備可能支持不同的屏幕分辨率。甚至一些可以自己變更分辨率,例如,切換到風景模式。確保你的布局和圖片能足夠靈活地在不同的設備屏幕上正 常顯示。幸運的是,這很容易做到。簡而言之,你需要做的是為主要分辨率提供不同版本的作品,然后為不同的尺寸設計你的布局。(例如,避免使用硬編碼位置而 使用相對布局。)如果那樣做的話,系統會處理剩下的部分,而且你的應用程序在任何設備上都看起來很棒。
Android設備會有多種網絡連接選項。所有的都提供數據訪問,但之間肯定有更快的。其中,速度最慢的是GPRS,GSM網絡的非 3G數據服務。即使具備 3G能力的設備在非3G的網絡上也會花費很多的時間,所以,網絡很慢仍然是一個長期存在的事實。
這 就是為什么你應該按照最小化的網絡訪問和帶寬來編寫你的代碼。你不能假設網絡是快速的,所以,你應該總是計劃它是慢的。如果你的用戶碰巧在一個快速的網絡 上,那很好——他們的用戶體驗會提升。你要避免相反的情形:在不同的地點和不同時間,應用程序有時可用,有時慢得令人抓狂,這樣的程序可能不會受歡迎。
還 有一個潛在的地方是,如果你正在使用模擬器,那么你很容易受它迷糊,因為模擬器使用電腦的網絡連接。這比手機網絡快很多,所以,你需要修改模擬器設定來模 擬較低的網絡速度。你可以在 Eclipse中做到這點,在啟動選項的模擬器設置頁里設置或者在啟動模擬器時通過命令行選項設置。
Android 可以支持多種外觀形狀。也就是說,一些Android設備擁有全“QWERTY”鍵盤,而其它可能會有40鍵、12鍵或其它鍵盤設置。同樣的,一些設備可 能有觸摸屏,但一些也會沒有。當創建你的應用程序的時候,記住這一點。不要假定特定的鍵盤布局——除非你真的想限定你的應用程序只運行在某些設備上。
如 果移動設備經常插在墻上,那么,它也就不是很“移動”。移動設備是電池供電的,如果我們能讓每次充電的電池使用得更持久一些,那么每個人都會更加開心—— 尤其是用戶。
其中兩大耗電硬件是處理器和無線;這也就是我們為什么要寫盡可能少做工作、盡可能少去使用網絡的應用程序的重要原因。
如 何讓你的應用程序最小化的占用處理器,歸根結底還是要寫高效代碼。為了減少無線的電量消耗,確保對錯誤條件進行正確的處理,并只獲取你要的東西。例如,如 果某一個網絡操作失敗了,不要不斷地進行重試。如果失敗了一次,有可能是用戶不受歡迎,因此,如果你再以正確的方式操作,有可能還會失??;所有你做的都是 在浪費電池。
用戶是相當聰明的:如果你的程序高耗電,他們是一定會發現的。到那個時點,你唯一可以確定的是,你的程序將很快被卸載掉。
第三篇:關于Android 開發環境的構建方法總結
關于Android開發環境的構建方法總結
作者: 曹亮 發布時間: 2010-03-25 21:31 閱讀: 745 次 原文鏈接 字體: 大 中 小 [收藏]
本方法適用于Android SDK 2.1環境下的程序開發
安裝JDK
? 在java.sun.com下載JDK并安裝。
? 在“系統屬性”的“高級”選項卡中點擊“環境變量”,然后添加如下系統環境變量:
1.在PATH環境變量后追加 JDK安裝路徑中的bin路徑,本機為: C:Program FilesJavajdk1.6.0_18bin 2.新建CLASSPATH環境變量或在CLASSPATH環境變量后追加JDK安裝路徑中的lib路徑和demo路徑,本機為:
C:Program FilesJavajdk1.6.0_18demo;C:Program FilesJavajdk1.6.0_18lib 安裝Eclipse
? 在eclipse.org下載Eclipse IDE for Java Developers的Windows 32bit版本。
? 下載完成后解壓即可使用。
安裝Android SDK OR 離線安裝
? 在Android Developers下載android-sdk_r05-windows.zip,下載完成后解壓到任意路徑。
? 運行SDK Setup.exe,點擊Available Packages,如果沒有出現可安裝的包請點擊Settings,選中Misc中的“Force https://...”這項,再點擊Available Packages。
? 選擇希望安裝的SDK及其文檔或者其它包,點擊Installation Selected、Accept All、Install Accepted,開始下載安裝所選包
? 添加SDK安裝目錄中的tools文件夾路徑至系統PATH環境變量,本機為: C:Androidandroid-sdk-windowstools 關于離線安裝
用上面方法更新的時候速度很慢。
更要等很久。所以我們可以直接把那些包下載下來安裝。地址就是 https://dl-ssl.google.com/androi...2.0_r01-windows.zip https://dl-ssl.google.com/androi...2.1_r01-windows.zip https://dl-ssl.google.com/androi...-1.1_r1-windows.zip https://dl-ssl.google.com/androi...1.5_r03-windows.zip https://dl-ssl.google.com/androi...1.6_r02-windows.zip https://dl-ssl.google.com/androi...ver_r03-windows.zip https://dl-ssl.google.com/androi...ogle_apis-6_r01.zip https://dl-ssl.google.com/androi...ogle_apis-5_r01.zip https://dl-ssl.google.com/androi...ogle_apis-4_r02.zip https://dl-ssl.google.com/androi...ogle_apis-7_r01.zip 下完之后,名字以android的,解壓到platforms里面; 以google_apis開頭的,解壓到addons里面。usb 驅動的,直接解壓到根目錄。
安裝Eclipse插件 ADT
? Start Eclipse, then select Help > Install New Software.? In the Available Software dialog, click Add...? In the Add Site dialog that appears, enter a name for the remote site(for example, “Android Plugin”)in the “Name” field.In the “Location” field, enter this URL: https://dl-ssl.google.com/android/eclipse/ 如 果無法通過上面的地址獲得插件,可將https替換為http。(https is preferred for security reasons)? Back in the Available Software view, you should now see “Developer Tools” added to the list.? Select the checkbox next to Developer Tools, which will automatically select the nested tools Android DDMS and Android Development Tools.Click Next.? In the resulting Install Details dialog, the Android DDMS and Android Development Tools features are listed.? Click Next to read and accept the license agreement and install any dependencies, then click Finish.? Restart Eclipse.配置ADT
在Eclipse中:
? 選擇Window > Preferences...? 在左邊的面板選擇Android,然后在右側點擊Browse...并選中SDK路徑,本機為:
C:Androidandroid-sdk-windows ? 點擊Apply、OK。配置完成。創建AVD
為使Android應用程序可以在模擬器上運行,必須創建AVD。
? 在Eclipse中。選擇Windows > Android SDK and AVD Manager ? 點擊左側面板的Virtual Devices,在右側點擊New ? 填入Name,選擇Target的API,SD Card大小任意,Skin隨便選,Hardware目前保持默認值
? 點擊Create AVD即可完成創建AVD Create a New Android Project
After you've created an AVD, the next step is to start a new Android project in Eclipse.1.From Eclipse, select File > New > Project.If the ADT Plugin for Eclipse has been successfully installed, the resulting dialog should have a folder labeled “Android” which should contain “Android Project”.(After you create one or more Android projects, an entry for “Android XML File” will also be available.)2.Select “Android Project” and click Next.3.Fill in the project details with the following values: o Project name: HelloAndroid o Application name: Hello, Android o Package name: com.example.helloandroid(or your own private namespace)o Create Activity: HelloAndroid o Min SDK Version: 7 Click Finish.Here is a description of each field:
Project Name
This is the Eclipse Project name — the name of the directory that will contain the project files.Application Name
This is the human-readable title for your application — the name that will appear on the Android device.Package Name
This is the package namespace(following the same rules as for packages in the Java programming language)that you want all your source code to reside under.This also sets the package name under which the stub Activity will be generated.Your package name must be unique across all packages installed on the Android system;for this reason, it's very important to use a standard domain-style package for your applications.The example above uses the “com.example” namespace, which is a namespace reserved for example documentation — when you develop your own applications, you should use a namespace that's appropriate to your organization or entity.Create Activity
This is the name for the class stub that will be generated by the plugin.This will be a subclass of Android's Activity class.An Activity is simply a class that can run and do work.It can create a UI if it chooses, but it doesn't need to.As the checkbox suggests, this is optional, but an Activity is almost always used as the basis for an application.Min SDK Version(這個是 設置程序希望運行在的系統版本)================================== Tips: 這里的Min SDK Version會根據我們選擇的Build Target改變,表示程序將運行在哪個系統版本之上,對應的數值關系如下: Android 1.5:Level API 3 Android 1.6:Level API 4 Android 2.01:Level API 6 Android 2.1:Level API 7 我們這里選擇Android 2.1,故Min SDK Version為7
================================== This value specifies the minimum API Level required by your application.If the API Level entered here matches the API Level provided by one of the available targets, then that Build Target will be automatically selected(in this case, entering “2” as the API Level will select the Android 1.1 target).With each new version of the Android system image and Android SDK, there have likely been additions or changes made to the APIs.When this occurs, a new API Level is assigned to the system image to regulate which applications are allowed to be run.If an application requires an API Level that is higher than the level supported by the device, then the application will not be installed.Other fields: The checkbox for “Use default location” allows you to change the location on disk where the project's files will be generated and stored.“Build Target” is the platform target that your application will be compiled against(this should be selected automatically, based on your Min SDK Version).Notice that the “Build Target” you've selected uses the Android 1.1 platform.This means that your application will be compiled against the Android 1.1 platform library.If you recall, the AVD created above runs on the Android 1.5 platform.These don't have to match;Android applications are forward-compatible, so an application built against the 1.1 platform library will run normally on the 1.5 platform.The reverse is not true.Your Android project is now ready.It should be visible in the Package Explorer on the left.Open the HelloAndroid.java file, located inside HelloAndroid > src > com.example.helloandroid).It should look like this: 下面是點完Finish按鈕之后自動生成的代碼: package com.example.helloandroid;import android.app.Activity;import android.os.Bundle;public class HelloAndroid extends Activity { /** Called when the activity is first created.*/ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.main);} } Notice that the class is based on the Activity class.An Activity is a single application entity that is used to perform actions.An application may have many separate activities, but the user interacts with them one at a time.The onCreate()method will be called by the Android system when your Activity starts — it is where you should perform all initialization and UI setup.An activity is not required to have a user interface, but usually will.Now let's modify some code!構建 UI
Take a look at the revised code below and then make the same changes to your HelloAndroid class.The bold items are lines that have been added.下面讓我們修改一下代碼:
package com.android.helloandroid;import android.app.Activity;import android.os.Bundle;import android.widget.TextView;public class HelloAndroid extends Activity { /** Called when the activity is first created.*/ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);TextView tv = new TextView(this);tv.setText(“Hello, Android”);setContentView(tv);} } 執行代碼:Hello,Android
Eclipse的插件使得你的程序很容易運行。選擇Run>Open Run Dialog菜單。(Eclipse3.4版本中,菜單為Run->Run Configurations)可以看到這樣的對話框。
下一步,選擇“Android Application”,點擊在左上角(按鈕像一張紙上有個“+”號)或者雙擊“Android Application”。有個新的選項“New_configuration”。
將名字改得更形象一點,如“Hello,Android”,然后按Browse按鈕選擇你的項目,(如果你Eclipse里有多個Android項 目需要打開,確定要選擇正確)插件會會自動掃描你項目里的活動子類,然后在“活動”的下拉菜單里加載。如果你的“Hello,Android”項目只有一 個,它將被設置為默認項目,然后你可以繼續。
點擊“Apply”按鈕,這里有個例子: 這樣就可以了,點擊“Run”按鈕,Android的模擬器啟動。一啟動你的程序就會出現,當一切OK,你可以看到: 這樣就可以了,點擊 “Run”按鈕,Android的模擬器啟動。啟動完畢后你的程序就會出現,如果不出現,有時候是因為有鍵盤鎖的原因,用鼠標將 鍵盤鎖解開就一切OK,你可以看到:Hello Android.使用XML構建UI
你剛 剛完成的“Hello, World”的例子使用的是我們稱為“可編程”的UI層,意思是你通過編寫代碼來組建UI層。當你開發了足夠多的UI程序,你會發現一些很糟糕的現象: 一些小的變化需要你做大量的代碼改動。你常常會忘記將View連接起來,這樣會導致一些錯誤,浪費你很多時間去調試代碼。這就是Android為 什么提供一個可變化的UI開發模塊:基于XML的文件。最簡單解釋這個概念就是演示個例子。這里有個XML的文件,它能達到和你剛才完成代碼同樣的效果:
在這個例子里,有4個XML屬 性,下面是屬性的大概意思:
xmlns:android 這是一個XML命名空間,告訴Android開發工具你準備使用Android命名空間里的一些通用屬性。在所有Android XML設計文件中最外層的標記必須使用這個屬性。
android:layout_width 這個屬性定義了這個視圖需要占用的屏幕寬度。在這個例子中,我們僅有的一個視圖可以占用整個屏幕,那就是“fill_parent”的意思。
android:layout_height 這個和“layout_width”差不多,表示占用屏幕的高度。
android:text 這個設置文本顯示內容,在這個例子里,我們使用“Hello,Android”。
這就是XML的布局,你需要把這個文件放在什么位 置? 放在你的工程/res/layout下就可以。“res”是“resource”的簡稱,這個目錄包含了所有應用程序需要的非代碼部分。比如圖片、字符 串、XML文件。
Eclipse插件為你創建了這些XML文件中的一個。在我們上面的范例,我們根本沒有使用過它。在包的管理器里,展開 目錄/res/layout,編輯main.xml文件,替換上面的文本然后保存修改。
在從代碼目錄里打開 HelloAndroid/gen/com.example.helloandroid/R.java文件,你可以看到他們像這樣: public final class R { public static final class attr { };public static final class drawable { public static final int icon=0x7f020000;};public static final class layout { public static final int main=0x7f030000;};public static final class string { public static final int app_name=0x7f040000;};};R.java是文件中所有資源的索引界定值定義。你在代碼中使用這個類,就像在你的項目里使用一個簡潔的方法表示你 的資源。在Eclipse這樣的IDE工具里,這個方式對于代碼自動完成功能還是非常有效的,因為這能讓你快速得定位你要尋找的東西。
有個重要點 需要注意的是有個內部類“main”,是“layout”的成員類。Eclipse插件提醒你加了一個新的XML文件,然后生成R.java文件,當你加 入其他資源到你的工程里,你可以看到R.java在同步更改。
第四篇:Android藍牙開發小結
學習之前先了解兩個基本概念:
一、RFCOMM協議:
一個基于歐洲電信標準協會ETSI07.10規程的串行線性仿真協議。此協議提供RS232控制和狀態信號,如基帶上的損壞,CTS以及數據信號等,為上層業務(如傳統的串行線纜應用)提供了傳送能力。
RFCOMM是一個簡單傳輸協議,其目的是針對如何在兩個不同設備上的應用之間保證一條完整的通信路徑,并在它們之間保持一通信段。
RFCOMM是為了兼容傳統的串口應用,同時取代有線的通信方式,藍牙協議棧需要提供與有線串口一致的通信接口而開發出的協議。RFCOMM協議提供對基于L2CAP協議的串口仿真,基于ETSI07.10??芍С衷趦蓚€BT設備之間同時保持高達60路的通信連接。
RFCOMM只針對直接互連設備之間的連接,或者是設備與網絡接入設備之間的互連。通信兩端設備必須兼容于RFCOMM協議,有兩類設備:DTE(Data Terminal Endpoint,通信終端,如PC,PRINTER)和DCE(Data Circuit Endpoint,通信段的一部分,如Modem)。此兩類設備不作區分。
二、MAC硬件地址
MAC(Medium/MediaAccess Control, 介質訪問控制)MAC地址是燒錄在NetworkInterfaceCard(網卡,NIC)里的.MAC地址,也叫硬件地址,是由48比特長(6字節),16進制的數字組成.0-23位叫做組織唯一標志符(organizationally unique,是識別LAN(局域網)節點的標識.24-47位是由廠家自己分配。其中第40位是組播地址標志位。網卡的物理地址通常是由網卡生產廠家燒入網卡的EPROM(一種閃存芯片,通常可以通過程序擦寫),它存儲的是傳輸數據時真正賴以標識發出數據的電腦和接收數據的主機的地址。
Android平臺提供的藍牙API去實現藍牙設備之間的通信,藍牙設備之間的通信主要包括了四個步驟:設置藍牙設備、尋找局域網內可能或者匹配的設備、連接設備和設備之間的數據傳輸。以下是建立藍牙連接的所需要的一些基本類:
BluetoothAdapter類:代表了一個本地的藍牙適配器。它是所有藍牙交互的的入口點。利用它你可以發現其他藍牙設備,查詢綁定了的設備,使用已知的MAC地址實例化一個藍牙設備和建立一個BluetoothServerSocket(作為服務器端)來監聽來自其他設備的連接。
BluetoothDevice類:代表了一個遠端的藍牙設備,使用它請求遠端藍牙設備連接或者獲取遠端藍牙設備的名稱、地址、種類和綁定狀態。(其信息是封裝在bluetoothsocket中)。
Bluetoothsocket類:代表了一個藍牙套接字的接口(類似于tcp中的套接字),它是應用程序通過輸入、輸出流與其他藍牙設備通信的連接點。
Blueboothserversocket類:代表打開服務連接來監聽可能到來的連接請求(屬于server端),為了連接兩個藍牙設備必須有一個設備作為服務器打開一個服務套接字。當遠端設備發起連接連接請求的時候,并且已經連接到了的時候,Blueboothserversocket類將會返回一個bluetoothsocket。
Bluetoothclass類:描述了一個藍牙設備的一般特點和能力。它的只讀屬性集定義了設備的主、次設備類和一些相關服務。然而,它并沒有準確地描述所有該設備所支持的藍牙文件和服務,而是作為對設備種類來說的一個小小暗示。下面說說具體的編程實現 1.啟動藍牙功能:
首先通過調用靜態方法getDefaultAdapter()獲取藍牙適配器BluetoothAdapter,以后你就可以使用該對象了。如果返回為空,the story is over。例如:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if(mBluetoothAdapter == null){ // Device does not support Bluetooth } 其次,調用isEnabled()來查詢當前藍牙設備的狀態,如果返回為false,則表示藍牙設備沒有開啟,接下來你需要封裝一個ACTION_REQUEST_ENABLE請求到intent里面,調用startActivityForResult()方法使能藍牙設備,例如:
if(!mBluetoothAdapter.isEnabled()){ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);}
2.查找設備:
使用BluetoothAdapter類里的方法,你可以查找遠端設備(大概十米以內)或者查詢在你手機上已經匹配(或者說綁定)的其他手機了。當然需要確定對方藍牙設備已經開啟或者已經開啟了“被發現使能”功能(對方設備是可以被發現的是你能夠發起連接的前提條件)。如果該設備是可以被發現的,會反饋回來一些對方的設備信息,比如名字、MAC地址等,利用這些信息,你的設備就可以選擇去向對方初始化一個連接。
如果你是第一次與該設備連接,那么一個配對的請求就會自動的顯示給用戶。當設備配對好之后,他的一些基本信息(主要是名字和MAC)被保存下來并可以使用藍牙的API來讀取。使用已知的MAC地址就可以對遠端的藍牙設備發起連接請求。
匹配好的設備和連接上的設備的不同點:匹配好只是說明對方設備發現了你的存在,并擁有一個共同的識別碼,并且可以連接。連接上:表示當前設備共享一個RFCOMM信道并且兩者之間可以交換數據。也就是是說藍牙設備在建立RFCOMM信道之前,必須是已經配對好了的。
3.查詢匹配好的設備:
在建立連接之前你必須先查詢配對好了的藍牙設備集(你周圍的藍牙設備可能不止一個),以便你選取哪一個設備進行通信,例如你可以你可以查詢所有配對的藍牙設備,并使用一個數組適配器將其打印顯示出來:
Set
4.掃描設備:
掃描設備,只需要簡單的調用startDiscovery()方法,這個掃描的過程大概持續是12秒,應用程序為了ACTION_FOUND動作需要注冊一個BroadcastReceiver來接受設備掃描到的信息。對于每一個設備,系統都會廣播ACTION_FOUND動作。例如: // Create a BroadcastReceiver for ACTION_FOUND private final BroadcastReceiver mReceiver = new BroadcastReceiver(){ public void onReceive(Context context, Intent intent){ String action = intent.getAction();// When discovery finds a device if(BluetoothDevice.ACTION_FOUND.equals(action)){ // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);// Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName()+ “n” + device.getAddress());} } };// Register the BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);registerReceiver(mReceiver, filter);// Don't forget to unregister during onDestroy 注意:掃描的過程是一個很耗費資源的過程,一旦你找到你需要的設備之后,在發起連接請求之前,確保你的程序調用cancelDiscovery()方法停止掃描。顯然,如果你已經連接上一個設備,啟動掃描會減少你的通信帶寬。
5.使能被發現:Enabling discoverability 如果你想使你的設備能夠被其他設備發現,將ACTION_REQUEST_DISCOVERABLE動作封裝在intent中并調用startActivityForResult(Intent, int)方法就可以了。他將在不使你應用程序退出的情況下使你的設備能夠被發現。缺省情況下的使能時間是120秒,當然你可以可以通過添加EXTRA_DISCOVERABLE_DURATION字段來改變使能時間(最大不超過300秒,這是出于對你設備上的信息安全考慮)。例如: Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);startActivity(discoverableIntent);運行該段代碼之后,系統會彈出一個對話框來提示你啟動設備使能被發現(此過程中如果你的藍牙功能沒有開啟,系統會幫你開啟),并且如果你準備對該遠端設備發現一個連接,你不需要開啟使能設備被發現功能,因為該功能只是在你的應用程序作為服務器端的時候才需要。
6.連接設備:
在應用程序中,想建立兩個藍牙設備之間的連接,必須實現客戶端和服務器端的代碼(因為任何一個設備都必須可以作為服務端或者客戶端)。一個開啟服務來監聽,一個發起連接請求(使用服務器端設備的MAC地址)。當他們都擁有一個藍牙套接字在同一RFECOMM信道上的時候,可以認為他們之間已經連接上了。服務端和客戶端通過不同的方式或其他們的藍牙套接字。當一個連接監聽到的時候,服務端獲取到藍牙套接字。當客戶可打開一個FRCOMM信道給服務器端的時候,客戶端獲取到藍牙套接字。
注意:在此過程中,如果兩個藍牙設備還沒有配對好的,android系統會通過一個通知或者對話框的形式來通知用戶。RFCOMM連接請求會在用戶選擇之前阻塞。如下圖:
7.服務端的連接:
當你想要連接兩臺設備時,一個必須作為服務端(通過持有一個打開的BluetoothServerSocket),目的是監聽外來連接請求,當監聽到以后提供一個連接上的BluetoothSocket給客戶端,當客戶端從BluetoothServerSocket得到BluetoothSocket以后就可以銷毀BluetoothServerSocket,除非你還想監聽更多的連接請求。
建立服務套接字和監聽連接的基本步驟:
首先通過調用listenUsingRfcommWithServiceRecord(String, UUID)方法來獲取BluetoothServerSocket對象,參數String代表了該服務的名稱,UUID代表了和客戶端連接的一個標識(128位格式的字符串ID,相當于PIN碼),UUID必須雙方匹配才可以建立連接。其次調用accept()方法來監聽可能到來的連接請求,當監聽到以后,返回一個連接上的藍牙套接字BluetoothSocket。最后,在監聽到一個連接以后,需要調用close()方法來關閉監聽程序。(一般藍牙設備之間是點對點的傳輸)
注意:accept()方法不應該放在主Acitvity里面,因為它是一種阻塞調用(在沒有監聽到連接請求之前程序就一直停在那里)。解決方法是新建一個線程來管理。例如: private class AcceptThread extends Thread { private final BluetoothServerSocket mmServerSocket;public AcceptThread(){ // Use a temporary object that is later assigned to mmServerSocket, // because mmServerSocket is final BluetoothServerSocket tmp = null;try { // MY_UUID is the app's UUID string, also used by theclient code tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);} catch(IOException e){ } mmServerSocket = tmp;} public void run(){ BluetoothSocket socket = null;// Keep listening until exception occurs or a socket is returned while(true){ try { socket = mmServerSocket.accept();} catch(IOException e){ break;} // If a connection was accepted if(socket!= null){ // Do work to manage the connection(in a separate thread)manageConnectedSocket(socket);mmServerSocket.close();break;} } } /** Will cancel the listening socket, and cause the thread to finish */ public void cancel(){ try { mmServerSocket.close();} catch(IOException e){ } } }
8.客戶端的連接:
為了初始化一個與遠端設備的連接,需要先獲取代表該設備的一個BluetoothDevice對象。通過BluetoothDevice對象來獲取BluetoothSocket并初始化連接,具體步驟:
使用BluetoothDevice對象里的方法createRfcommSocketToServiceRecord(UUID)來獲取BluetoothSocket。UUID就是匹配碼。然后,調用connect()方法來。如果遠端設備接收了該連接,他們將在通信過程中共享RFFCOMM信道,并且connect()方法返回。例如: private class ConnectThread extends Thread { private final BluetoothSocket mmSocket;private final BluetoothDevice mmDevice;public ConnectThread(BluetoothDevice device){ // Use a temporary object that is later assigned to mmSocket, // because mmSocket is final BluetoothSocket tmp = null;mmDevice = device;// Get a BluetoothSocket to connect with the given BluetoothDevice try { // MY_UUID is the app's UUID string, also used by the server code tmp = device.createRfcommSocketToServiceRecord(MY_UUID);} catch(IOException e){ } mmSocket = tmp;}
public void run(){ // Cancel discovery because it will slow down the connection mAdapter.cancelDiscovery();try { // Connect the device through the socket.This will block // until it succeeds or throws an exception mmSocket.connect();} catch(IOException connectException){ // Unable to connect;close the socket and get out try { mmSocket.close();} catch(IOException closeException){ } return;} // Do work to manage the connection(in a separate thread)manageConnectedSocket(mmSocket);}
注意:conncet()方法也是阻塞調用,一般建立一個獨立的線程中來調用該方法。在設備discover過程中不應該發起連接connect(),這樣會明顯減慢速度以至于連接失敗。且數據傳輸完成只有調用close()方法來關閉連接,這樣可以節省系統內部資源。
9.管理連接(主要涉及數據的傳輸):
當設備連接上以后,每個設備都擁有各自的BluetoothSocket?,F在你就可以實現設備之間數據的共享了。
1> 首先通過調用getInputStream()和getOutputStream()方法來獲取輸入輸出流。然后通過調用read(byte[])和write(byte[]).方法來讀取或者寫數據。
2> 實現細節:以為讀取和寫操作都是阻塞調用,需要建立一個專用現成來管理。3>
private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket;private final InputStream mmInStream;private final OutputStream mmOutStream;public ConnectedThread(BluetoothSocket socket){ mmSocket = socket;InputStream tmpIn = null;OutputStream tmpOut = null;// Get the input and output streams, using temp objects because // member streams are final try { tmpIn = socket.getInputStream();tmpOut = socket.getOutputStream();} catch(IOException e){ } mmInStream = tmpIn;mmOutStream = tmpOut;} public void run(){ byte[] buffer = new byte[1024];// buffer store for the stream int bytes;// bytes returned from read()// Keep listening to the InputStream until an exception occurs while(true){ try { // Read from the InputStream bytes = mmInStream.read(buffer);// Send the obtained bytes to the UI Activity mHandler.obtainMessage(MESSAGE_READ, bytes,-1, buffer).sendToTarget();} catch(IOException e){ break;} } } /* Call this from the main Activity to send data to the remote device */ public void write(byte[] bytes){ try { mmOutStream.write(bytes);} catch(IOException e){ } } /* Call this from the main Activity to shutdown the connection */ public void cancel(){ try { mmSocket.close();} catch(IOException e){ } } }
第五篇:Android 嵌入式開發心得體會
Android 嵌入式開發心得體會
剛開始接觸Android感覺到它很有意思,在界面開發上和web也可以形成了相通的架構,更加方便,視覺上也是非常的酷,在前期我通過的大量的Android SDK開發范例大全中的例子以及Android提供的APIDEMOS進行學習,盡管例子之間的連接比較零散,不過通過這些例子的學習我可以學習到了很多和以前java上相通的思想,因為Android在現在也是全新的技術和框架,在其中我也學到了如何用單例模式、工廠模式等常用的設計模式進行學習,通過API進行開發客戶端,對Request發送,Response處理中通過比較方便的JSON對象傳輸,以及對XML、JSON、圖片、業務等下載處理,對API接口調用等問題處理,學習Android心得體會。首先在界面上,我們同樣可以通過不同布局進行設計非??岬慕缑妫@些界面可以通過include進行引入,和jsp、html也有相通的地方,同樣在android上可以用到自定義的樣式這和css也有比較相通的地方,我們可以通過一些公用的方法寫個BaseActivity這個基類,通過繼承方式比較不錯的實現了Activity的界面,因為這樣你可以Header(頭部)和Footer(尾部)進行處理一些觸發事件或者特效等,布局模式以相對模式為主,線線布局模式可以在比較簡單的include進行完成,最重要的一點就是:我們可以自己通過重寫方法或者通過實現View或者Layout等類進行擴充項目需要的布局(或者控件),在學習界面中,我發現Android為我們提供了很好的類似反射機制,通過Layout文件夾下的配置文件,可以快速的形成界面,在配置文件可以設置屬性或者樣式都是很快捷方便。對比較特殊的界面也可以通過處理嵌入到指定的界面,同樣你可以通過java代碼直接創建View進行添加,不過這種方式比較復雜。對一些點擊、選中、按鍵等處理的事件,界面之間的跳轉Intent管理,通過Bundle對數據在界面之間進行傳輸。其次在手機交互式通信服務中,學習了Android手機之間進行短信發送、廣播、對廣播的監聽、服務等,在Service類中沒有context,可以通過Handler來每秒反復運行,自動送出系統廣播信息,同時在這里我們也知道可以設計一個常用的變量類,設計一個當前的CurrentActivity這個變量進行控制,進行處理。
總而言之,Android設計還是比較自由開闊的,只要有想法,自己動手便能實現。