當前位置:首頁 » 安卓系統 » queryforandroid

queryforandroid

發布時間: 2023-05-29 03:05:51

A. android 資料庫怎麼監聽數據變化

在android中經常會用到改變資料庫內容後再去使用資料庫更新的內容,很多人會重新去query一遍,但是這樣的問題就是程序會特別占內存,而且有可能會摟關cursor而導致程序內存未釋放等等。其實android內部提供了一種ContentObserver的東西來監聽資料庫內容的變化。
ContentObserver的構造函數需要一個參數Hanlder,因為ContentObserver內部使用了一個實現Runnable介面的內部類NotificationRunnable,來實現資料庫內容的變化。需要使用hanlder去post消息。注冊ContentObserver的方法是:getContentResolver().registerContentObserver(uri, notifyForDescendents, observer).
上面3個參數為:uri----Uri類型,是需要監聽的資料庫的uri.
notifyForDescendents---boolean true的話就會監聽所有與此uri相關的uri。false的話則是直接特殊的uri才會監聽。一般都設置為true.
observer-----ContentObserver 就是需要的contentobserver.
初始化一個ContentObserver對象,重載onChange(boolean ),在這個方法里去操作資料庫的使用,針對變化後的使用。

B. 安卓開發五大關鍵字(比如activity)

可以說是五個吧:
1. Activity
2. Service
3. Broadcast Receiver
4. Content Provider
5. Intent
c) 該方法啟動的Service,可以通過Context對象調用stopService來關閉,也可以通過Service自身調用stopSelf()或stopSelfResult()來關閉,關閉之前調用onDestory方法。
2. 調用bindService方法,使當前Context對象通過一個ServiceConnection的對象綁定到所指定的Service
a) 若Service沒有啟動,則首先會調用消念擾該Service的onCreate方法初始化啟動,然後調用Service的onBind方法初始化綁定。
b) 如果綁定Service的Context對象被銷毀時,被綁定的Service也會調用onUnbind 和 onDestroy方法停止運行
c) 注意: BroadcastReceiver是不能綁定服務的。
d) 一個綁定Service的Context對象還可以通過unbindService()來取消對服務的綁定。
e) 取消時,Service會調用unbind方法,若Service是通過bindService來啟動的,還會調用onDestroy方法來高局停止服務。
Service狀態回調:
l onCreate
l onStart
l onBind
l onRebind
l onUnbind
l onDestroy

Broadcast Receiver——用戶接收廣播通知的組件(基類BroadcastReceiver)
Android中的廣播要麼來自於系統,要麼來自普通應用程序。
很多事件都可能導致系統廣播,如手機所在時區發生變化,電池電量低,用戶改變系統語言設置等。
來自普通應用程序,如一個應用程序通知其他應用程序某些數據已經下載完畢。
為了響應不同的事件通知,應用程序可以注冊不同的Broadcast Receiver。所有的Broadcast Receiver都繼承自基類BroadcastReceiver。
BroadcastReceiver自身並不實現圖形用戶界面,但是當它收到某個通知後,BroadcastReceiver可以啟動Activity作為響應,或者通過NotificationMananger提醒用戶。
BroadcastReceiver是對發送出來的Broadcast進行過濾接收並響應的一類組件。

發送Broadcast信息
1. 把要發送的信息和用於過濾得信息(如Action、Category)裝入一個Intent對象
2. 調用Context.sendBroadcast()、sendOrderBroadcast()、sendStickyBroadcast()方法,廣播該Intent對象
3. 使用sendBroadcast() 或sendStickyBroadcast()方法發出去的Intent,所有滿足條件的BroadcastReceiver都會隨機地執行其onReceive()方法;
4. 而sendOrderBroadcast()發出去的Intent,會根據BroadcastReceiver注冊時IntentFilter設置的優先順序拿旦的順序來執行,相同優先順序的BroadcastReceiver則是隨機執行
5. sendStickyBroadcast()方法主要的不同是,Intent在發送後一直存在,並且在以後調用registerReceiver()注冊相匹配的Intent時會把這個Intent直接返回。
6. 若在使用sendBroadcast()方法時指定了接收的許可權,這只有在AndroidManifest.xml中用<uses-permission>標簽聲明了擁有此許可權的BroadcastReceiver才會有可能接收到發送來Broadcast。
7. 若在注冊BroadcastReciever時,指定了可接收的Broadcast的許可權,則只有在包內的AndroidManifest.xml中用<uses-permission>標簽聲明了,擁有此許可權的Context對象所發送的Broadcast才有可能被這個BroadcastReceiver所接收。
接收Broadcast消息
1. 繼承BroadcastReceiver 類,並實現onReceive方法
2. 注冊Broadcast Receiver(有2種方法:一種方法是,靜態地在AndroidManifest.xml中用<receiver>標簽聲明,並在標簽內用<intent-filter>標簽設置過濾器;另一種方法,動態地在代碼中先定義並設置好一個IntentFilter對象,然後再需要注冊的地方調用Context.registerReceiver()方法)(取消注冊時,調用Context.unregisterReceiver()方法)

Content Provider——為解決應用程序間數據通信、共享的問題(基類ContentProvider)
在Android中,每個應用程序都是用自己的用戶ID並在自己的進程中運行。這樣的好處是,可以有效地保護系統及應用程序,避免被其他不正常德應用程序所影響,每個進程都擁有獨立的進程地址空間和虛擬空間。
Content Provider可以將應用程序特定的數據提供給另一個應用程序使用。其數據存儲方式可以是Android文件系統、sqlite資料庫或者其他合理的方式。
當數據需要在應用程序間共享時,我們就可以利用ContentProvider為數據定義一個URI。之後,其他應用程序對數據進行查詢或者修改時,只需要從當前上下文對象獲得一個ContentResolver, 然後傳入響應的URI就可以了。
Content Provider 繼承自基類ContentProvider,並且實現了一組標准介面。通過這組介面,其他應用程序能對數據進行讀寫和存儲。然而,需要使用數據的應用程序並不是直接調用這組方法,而是通過調用ContentResolver對象的方法來完成。ContentResolver對象可以與任意ContentProvider通信。
要為當前應用程序的私有數據定義URI,就需要專門定義一個繼承自ContentProvider的類,然後根據不同的操作調用的方法去實現這些方法的功能。
ContentResolver類為應用程序提供了接入Content機制的方法。要構造一個ContentResolver對象可以為構造方法ContentResolver(Contextcontext)傳入一個Context對象,也可以直接通過Context對象調用getContentResolver()方法獲得——有的ContentResolver對象後,就可以通過調用其query()、insert()、update()等方法來對數據進行操作了。

一旦需要以上4種Android應用程序基本組件完成請求,Android會首先確認該組件所在進程是否運行,如果沒有運行,Android將先啟動進程,同時確認被請求組件的實例是否存在,否則將創建一個新的組件實例。

Intent ——連接組件的紐帶
以上4種基本組件中,除了ContentProvider是通過Content Resolver激活外,其他3種組件Activity、Service和BroadcastReceiver都是由Intent非同步消息激活的。
Intent在不同的組件之間傳遞消息,將一個組件的請求意圖傳給另一個組件。因此,Intent是包含具體請求信息的對象。
針對不同的組件,Intent所包含的消息內容有所不同,且不同組件的激活方式也不同,且不同類型組件有傳遞Intent的不同方式。
Intent是一種運行時綁定(runtime binding)機制,它能夠在程序運行的過程中連接兩個不同的組件。通過Intent,你的程序可以向Android表到某種請求或者意願,Android會根據意願的內容選擇適當的組件來處理請求。
l 激活一個新的Activity,或者讓一個現有的Activity執行一個新的操作,可以通過調用如下兩種方法(這兩匯總方法需要傳入的Intent參數稱為Activity Action Intent):
1. Context.startActivity()
2. Activity.startActivityForResult()
l 啟動一個新的服務,或者向一個已有的服務傳遞新的指令,可以調用如下兩種方法:
1. Context.startService()
2. Context.bindService()
l 發送廣播Intent(所有已注冊的擁有與之相匹配IntenFilter的BroadcastReceiv就會被激活),可以調用如下三種方法:
1. Context.sendBroadcast()
2. Context.sendOrderBroadcast()
3. Context.sendStickBroadcast()
Intent一旦發出,Android都會准確找到相匹配的一個或多個Activity、Service或BroadcastReceiver作響應。所以,不同類型的Intent消息不會出現重疊,BroadcastIntent消息只會發送給BroadcastReceiver,而絕不可能發送給Activity或Server。有startActivity()傳遞的消息也只可能發送給Activity,由startService()傳遞的Intent只可能發送給Service。

Intent對象抽象地描述了執行操作,Intent的主要組成部分;
1. 目標組件名稱。[可選項]
a) 組件名稱是一個ComponentName對象,是目標組件類名和目標組件所在應用程序包的組合
b) 組件中的包名不一定要和manifes文件中包名完全匹配
c) 如果Intent消息中指明了目標組件的名稱,這就是一個顯示消息,Intent會傳遞給指明的組件。
d) 如果目標組件名稱並沒有指定,Android則通過Intent內的其他信息和已注冊的IntentFilter的比較來選擇合適的目標組件
2. Action [隱式比較]
a) 描述Intent所觸發動作的名字字元串。
b) 理論上Action可以為任何字元串,而與Android系統應用有關的Action字元串以靜態字元串常量的形式定義在了Intent類中。
3. Data [隱式比較]
a) 描述Intent要操作的的數據的URI和數據類型。
b) 正確設置Intent的數據對於Android尋找系統中匹配Intent請求的組件很重要。
4. Category [隱式比較]
a) 是對被請求組件的額外描述信息。
b) Android也在Intent類中定義了一組靜態字元串常量表示Intent不同的類別。
5. Extra
a) 當我們使用Intent連接不同組件時,有時需要在Intent中附加額外的信息,以便將數據傳遞給目標Activity。
b) Extra用鍵值對結構保存在Intent對象當中,Intent對象通過調用方法putExtras()和 getExtras()來存儲和獲取Extra
c) Extra是以Bundle對象的形式來保存的,Bundle對象提供了一系列put和get方法來設置、提取相應鍵值信息。
d) 在Intent類中同樣為Android系統應用的一些Extra的鍵值定義了靜態字元串常量。
6. Flag

決定Intent目標組件的因素:
n 在顯式Intent消息中,決定目標組件的唯一要素就是組件名稱(不用再定義其他Intent內容)
n 而隱式Intent消息中,由於沒有目標組件名稱,所以必須由Android系統幫助應用程序尋找與Intent請求意圖最匹配的組件。
n 隱式Intent消息中目標組件具體選擇方法是:android將Intent的請求內容和一個叫做IntentFilter的過濾器比較,IntentFilter中包含系統中所有可能的待選組件。如果IntentFilter中某一個組件匹配隱式Intent請求內容,那麼Android就選擇該組件作為該隱式Intent的目標組件。

IntenFilter
應用程序的組件為了告訴Android自己能響應、處理哪些隱式Intent請求,可以聲明一個甚至多個IntentFilter。
每個IntentFilter描述該組件所能響應Intent請求的能力——組件希望接收什麼類型的請求行為,什麼類型的請求數據。
隱式Intent和IntentFilter進行比較時的三要素:Action、Data、Category。
一個隱式Intent請求要能夠傳遞給目標組件,必需通過以上三個方面的檢查。如果任何一方面不匹配,Android都不會將該隱式Intent傳遞給目標組件。
<intent-filter>
<action android:name=」」/>
<category android:name=」」/>
<data android:type=」」 android:scheme=」」android:authority=」」 android:path=」」/>
</intent-filter>
1. 動作測試
a) 一條 <intent-filter> 中至少應該包含一個<action>, 否則任何Intent請求都不能和該<intent-filter> 匹配。
b) 如果IntentFilter 中沒有包含任何Actino類型,那麼無論什麼Intent請求都無法和這條IntentFilter匹配。
c) 如果Intent請求中沒有設定Action類型,那麼只要IntentFilter中包含有Action類型,這個Intent請求將順利通過IntentFilter的測試。
2. 類別測試
a) 只有當Intent請求中所有的Category與組件中的某一個IntentFilter的category完全匹配,才會讓該Intent請求通過測試,IntentFilter中的多餘category聲明並不會導致匹配失敗。
b) 一個沒有指定任何類別的IntentFilter僅僅只會匹配沒有設置類別的Intent請求。
3. 數據測試
a) <data>元素指定了希望接受的Intent請求的數據URI和數據類型:URI被分成三部分類進行匹配,scheme、authority和 path.
b) 使用 setData設定的Intent請求的URI數據類型和scheme,必須與IntentFilter中指定的一致
若IntentFilter中還指定了authority或path,他們也需要相匹配才會通過測試。

C. Android 手機自動化測試工具有哪幾種

Feb 23 2012更新: 還有Sikuli (http://sikuli.org),基於優秀的圖像對比庫opencv的測試工具,測試腳本使用Python編寫,非常強大。如果你的app沒有源碼,可以選擇它;或者你想做系統測試(跨app的測試),也可以選擇它。其它的還是用下面說的那些個吧。
我通過其核心包sikuli-script.jar實現了android的sikuli化,暫時不打算開源。其實原理挺簡單的,認真看過sikuli源碼的應該都能寫出來。

看lz的意思應該只是想問應用層的,我來說點應用層的
先說說開源的吧:
Robotium
Monkeyrunner
Robolectric
CTS
還有個新興的測試工具,以前在GitHub看到,現在找不到了,好像是BDD類型的語法;現在還不成熟。

另外基於web的測試也有基於Selenium Webdriver 的 Android WebDriver:
有兩種:
基於Remote Server的:官方提供了java介面的,但是Python版的官方裡面卻沒有。我非常喜歡Python,所以自己實現了並且開源到了GitHub:https://github.com/truebit/AndroidWebDriver4Python 有問題大家可以提到上面

基於Instrumentation的:已經在Android SDK r14裡面可以安裝了
不開源的就多了,不過我見過的一般是以下幾種思路:
1. 基於Android Java Instrumentation框架:
基於Robotium,比如bitbar的產品:http://bitbar.com/procts
基於Instrumentation,那就海了去了,很多公司自家寫的工具都基於這個;另外Robotium就是基於這個的
2. 基於Android lib層的各種命令,比如sendevent,getevent, monkey, service這些,然後用各種語言封裝

MonkeyRunner還是很有前景的,Google自己弄的。現在最新的dev版本已經有支持UI的id操作的EasyMonkey了。可以git clone git://http://android.kernel.org/platform/sdk.git看看

編輯於 2012-02-23 7 條評論 • 作者保留權利

贊同23反對,不會顯示你的姓名
乙醇,打雜的......
落小雪、蔣金龍、Reeta L 等人贊同
appium是最近我關注的一個不錯的移動端自動化測試工具,支持android和ios。
放上兩段視頻。第一段是講解appium的原理及quick start;第二段講解了appium的源碼結構和具體實現。有興趣可以看一下,相信應該有收獲。

1,appium 原理與quick start

乙醇的appium視頻教程之appium入門及原理剖析
http://v.youku.com/v_show/id_XNjQzMjI4NDcy.html?firsttime=2212
2,appium源碼解析

乙醇的appium源碼解讀
http://v.youku.com/v_show/id_XNjQzODIwMzA4.html?firsttime=0

發布於 2013-12-07 5 條評論 • 作者保留權利

贊同25反對,不會顯示你的姓名
知乎用戶,Coding/Reading/Hiking/Running
知乎用戶、曹媛媛、石存灃 等人贊同
1、Monkey是Android SDK自帶的測試工具,在測試過程中會向系統發送偽隨機的用戶事件流,如按鍵輸入、觸摸屏輸入、手勢輸入等),實現對正在開發的應用程序進行壓力測試,也有日誌輸出。實際上該工具只能做程序做一些壓力測試,由於測試事件和數據都是隨機的,不能自定義,所以有很大的局限性。
2、MonkeyRunner也是Android SDK提供的測試工具。嚴格意義上來說MonkeyRunner其實是一個Api工具包,比Monkey強大,可以編寫測試腳本來自定義數據、事件。缺點是腳本用Python來寫,對測試人員來說要求較高,有比較大的學習成本。
3、Instrumentation是早期Google提供的Android自動化測試工具類,雖然在那時候JUnit也可以對Android進行測試,但是Instrumentation允許你對應用程序做更為復雜的測試,甚至是框架層面的。通過Instrumentation你可以模擬按鍵按下、抬起、屏幕點擊、滾動等事件。Instrumentation是通過將主程序和測試程序運行在同一個進程來實現這些功能,你可以把Instrumentation看成一個類似Activity或者Service並且不帶界面的組件,在程序運行期間監控你的主程序。缺點是對測試人員來說編寫代碼能力要求較高,需要對Android相關知識有一定了解,還需要配置AndroidManifest.xml文件,不能跨多個App。
4、UiAutomator也是Android提供的自動化測試框架,基本上支持所有的Android事件操作,對比Instrumentation它不需要測試人員了解代碼實現細節(可以用UiAutomatorviewer抓去App頁面上的控制項屬性而不看源碼)。基於Java,測試代碼結構簡單、編寫容易、學習成本,一次編譯,所有設備或模擬器都能運行測試,能跨App(比如:很多App有選擇相冊、打開相機拍照,這就是跨App測試)。缺點是只支持SDK 16(Android 4.1)及以上,不支持Hybird App、WebApp。
5、Espresso是Google的開源自動化測試框架。相對於Robotium和UIAutomator,它的特點是規模更小、更簡潔,API更加精確,編寫測試代碼簡單,容易快速上手。因為是基於Instrumentation的,所以不能跨App。配合Android Studio來編寫測試的簡單例子
6、Selendroid:也是基於Instrumentation的測試框架,可以測試Native App、Hybird App、Web App,但是網上資料較少,社區活躍度也不大。
7、Robotium也是基於Instrumentation的測試框架,目前國內外用的比較多,資料比較多,社區也比較活躍。缺點是對測試人員來說要有一定的Java基礎,了解Android基本組件,不能跨App。
8、Athrun是淘寶出的一個移動測試框架/平台,同時支持iOS和Android。Android部分也是基於Instrumentation,在Android原有的類基礎上進行了擴展,提供一整套面向對象的API。這里有詳細介紹。
9、Appium是最近比較熱門的框架,社區也很活躍。這個框架應該是是功能最強大的,
它的優點:
它的哲理是:
它的設計理念:
相關限制:
總結:
在iOS部分是封裝了UIAutomation;Android 4.2以上是用UiAutomator,Android 2.3 ~ 4.1用的是 Instrumentation,也就說Appium同時封裝了UiAutomator和Instrumentation。所以Appium擁有了以上幾大框架的所有優點:跨App,支持Native App、Hybird App、Web App,還支持N種語言來編寫你的測試腳本。
如果你在Windows使用Appium,你沒法使用預編譯專用於OS X的.app文件,因為Appium依賴OS X專用的庫來支持iOS測試,所以在Windows平台你不能測試iOS Apps。這意味著你只能通過在Mac上來運行iOS測試。
Client/Server架構,運行的時候Server端會監聽Client端發過來的命令,翻譯這些命令發送給移動設備或模擬器,然後移動設備或模擬器做出響應的反應。正是因為這種架構,所以Client可以使用Appium client libraries多種語言的測試腳本,而且Server端完全可以部署在伺服器上,甚至雲伺服器
Session,每個Client連接到Server以後都會有一個Session ID,而且Client發送命令到Server端都需要這個Session ID,因為這個seesion id代表了你所打開的瀏覽器或者是移動設備的模擬器。所以你甚至可以打開N個Session,同時測試不同的設備或模擬器。
Desired Capabilities,其實就是一個鍵值對,設置一些測試的相關信息來告訴Server端,我們需要測試iOS、還是Android,或者換是WebApp等信息。
Appium Server是Node.js寫的,所以可以直接用NPM來進行安裝。
Appium Clients,Mac OS和Win下提供GUI,不需要裝Node.js,方便測試人員操作。
用Appium自動化測試不需要重新編譯App;
支持很多語言來編寫測試腳本,Java、Javascript、PHP、Python、C#、Ruby等主流語言;
不需要為了自動化測試來重造輪子,因為擴展了WebDriver。(WebDriver是測試WebApps的一種簡單、快速的自動化測試框架,所以有Web自動化測試經驗的測試人員可以直接上手);
移動端自動化測試應該是開源的;
開源;
支持Native App、Hybird App、Web App;
支持Android、iOS、Firefox OS;
Server也是跨平台的,你可以使用Mac OS X、Windows或者Linux;
顯示全部

編輯於 2015-03-20 1 條評論 • 作者保留權利

贊同4反對,不會顯示你的姓名
知乎用戶,hello rabbit
郝思遠、man Nor、徐佳琦 等人贊同
當前有很大的趨勢是轉向移動應用平台,Android 是最廣泛使用的移動操作系統,2014 年大約占 80% 以上的市場。在開發 Android 應用的時候要進行測試,現在市場上有大量的測試工具。

本文提到的開源 Android 軟體測試工具包括:Android Test Kit, AndroidJUnit4, Appium, calabash-android, Monkey, MonkeyTalk, NativeDriver, Robolectric, RoboSpock, Robotium, UIAutomator, Selendroid。

Android Test Kit

Android Test Kit 是一組 Google 開源測試工具,用於 Android 平台,包含 Espresso API 可用於編寫簡潔可靠的 Android UI 測試。

OSChina URL: Android Test Kit首頁、文檔和下載

相關資源

* Android application testing with the Android test framework – Tutorial
* Espresso for Android is here!

AndroidJUnit4

AndroidJUnit4 是一個讓 JUnit 4 可以直接運行在 Android 設備上的開源命令行工具。

OSChina URL: AndroidJUnit4首頁、文檔和下載

Appium

Appium 是一個開源、跨平台的自動化測試工具,用於測試原生和輕量移動應用,支持 iOS, Android 和 FirefoxOS 平台。Appium 驅動蘋果的 UIAutomation 庫和 Android 的 UiAutomator 框架,使用 Selenium 的 WebDriver JSON 協議。

Appinm 的 iOS 支持是基於 Dan Cuellar's 的 iOS Auto. Appium 同時綁定了 Selendroid 用於老的 Android 平台測試。

OSChina URL: Appium首頁、文檔和下載

相關資源

* Appium Tutorial
* Android UI testing with Appium

Calabash-android

calabash-android 是一個基於 Cucumber 的 Android 的功能自動化測試框架。Calabash 允許你寫和執行,是開源的自動化移動應用測試工具,支持 Android 和 iOS 原生應用。Calabash 的庫允許原生和混合應用的交互測試,交互包括大量的終端用戶活動。Calabash 可以媲美 Selenium WebDriver。但是, 需要注意的是 web 應用和桌面環境的交互跟觸摸屏應用的交互是不同的。Calabash 專為觸摸屏設備的原生應用提供 APIs。

OSChina URL: calabash-android首頁、文檔和下載

相關資源

* A better way to test Android applications using Calabash
* Calabash Android: query language basics

Monkey

Monkey 是 Google 開發的 UI/應用測試工具,也是命令行工具,主要針對壓力測試。你可以在任意的模擬器示例或者設備上運行。Monkey 發送一個用戶事件的 pseudo-random 流給系統,作為你開發應用的壓力測試。

OSChina URL: UI/Application Exerciser Monkey

MonkeyTalk

MonkeyTalk 是世界上最強大的移動應用測試工具。MonkeyTalk 自動為 iOS 和 Android 應用進行真實的,功能性交互測試。MonkeyTalk 提供簡單的 "smoke tests",復雜數據驅動的測試套件。

MonkeyTalk 支持原生,移動和混合應用,真實設備或者模擬器。MonkeyTalk 使得場景捕獲非常容易,可以記錄高級別,可讀的測試腳本。同樣的命令可以用在 iOS 和 Android 應用上。你可以記錄一個平台的一個測試,並且可以在另外一個平台回放。MonkeyTalk 支持移動觸摸和基於手勢交互為主的移動體驗。點擊,拖拽,移動,甚至是手指繪制也可以被記錄和回放。

OSChina URL: MonkeyTalk首頁、文檔和下載

相關資源

* Using MonkeyTalk in AndroidStudio

NativeDriver

NativeDriver 是 WebDriver API 的實現,是原生應用 UI 驅動,而不是 web 應用。

OSChina URL: NativeDriver首頁、文檔和下載

Robolectric

Robolectric 是一款Android單元測試框架,使用 Android SDK jar,所以你可以使用測試驅動開發 Android 應用。測試只需幾秒就可以在工作站的 JVM 運行。Robolectric 處理視圖縮放,資源載入和大量 Android 設備原生的 C 代碼實現。

Robolectric 允許你做大部分真實設備上可以做的事情,可以在工作站中運行,也可以在常規的 JVM 持續集成環境運行,不需要通過模擬器。

OSChina URL: Robolectric首頁、文檔和下載

Additional resources

* Better Android Testing with Robolectric 2.0
Using Robolectric for Android testing – Tutorial

RoboSpock

RoboSpock 是一個開源的 Android 測試框架。提供簡單的編寫 BDD 行為驅動開發規范的方法,使用Groovy 語音,支持 Google Guice 庫。RoboSpock 合並了 Robolectric 和 Spock 的功能。

OSChina URL: RoboSpock首頁、文檔和下載

相關資源

* RoboSpock – Behavior Driven Development (BDD) for Android

Robotium

Robotium 是一款國外的Android自動化測試框架,主要針對Android平台的應用進行黑盒自動化測試,它提供了模擬各種手勢操作(點擊、長 按、滑動等)、查找和斷言機制的API,能夠對各種控制項進行操作。

Robotium結合Android官方提供的測試框架達到對應用程序進行自動化的測 試。另外,Robotium 4.0版本已經支持對WebView的操作。Robotium 對Activity,Dialog,Toast,Menu 都是支持的。

OSChina URL: Robotium首頁、文檔和下載

相關資源

* Robotium – Testing Android User Interface
* Android user interface testing with Robotium – Tutorial

UIAutomator

uiautomator 測試框架提高用戶界面(UI)的測試效率,通過自動創建功能 UI 測試示例,可以在一個或者多個設備上運行你的應用。

OSChina URL: uiautomator首頁、文檔和下載

相關資源

* Automatic Android Testing with UiAutomator

Selendroid

Selendroid 是一個 Android 原生應用的 UI 自動化測試框架。測試使用 Selenium 2 客戶端 API 編寫。Selendroid 可以在模擬器和實際設備上使用,也可以集成網格節點作為縮放和並行測試。

OSChina URL: Selendroid首頁、文檔和下載

相關資源

* Mobile Test Automation with Selendroid
* Road to setup Selendroid and create first test script of android application
* Up and running with: Selendroid

一些停止維護的 Android 測試工具

一些幾乎沒有繼續維護的開源 Android 測試工具項目(至少是最近幾個月都沒有更新的項目)。

Emmagee

Emmagee 是監控指定被測應用在使用過程中佔用機器的CPU、內存、流量資源的性能測試小工具。Emmagee 同時還提供非常酷的一些特性,比如定製間隔來收集數據,使用浮動窗口呈現實時進程狀態等。

OSChina URL: Emmagee首頁、文檔和下載

Sirocco

Scirocco(scirocco-webdriver) 是開源的應用自動化測試工具,可以從 Eclipse 訪問必要的測試設備。Scirocco 提供自動化的 Android 應用測試功能,代替手工測試。Scirocco 支持谷歌的 NativeDriver,把 AndroidDriver 作為主要的測試庫。Scirocco 包括三個部分:NativeDriver,AndroidDriver,scirocco 插件(一個 Eclipse 插件;可以自動執行 scenario 測試和製作測試報告截圖)。

OSChina URL: Scirocco首頁、文檔和下載

via softwaretestingmagazine

內容來源:開源中國社區顯示全部

發布於 2015-03-27 添加評論 • 作者保留權利

贊同11反對,不會顯示你的姓名
知乎用戶,擁抱移動互聯網

D. 如何對android多媒體資料庫進行增刪改

Android四種存儲方式: sharedpreference,file,SQlite,contentprovider。

1、SharedPreferences是一種輕型的數據存儲方式,它的本質是基於XML文件存儲key-value鍵值對數據,通常用來存儲一些簡單的配置信息。其存儲位置在/data/data/<包名>/shared_prefs目錄下。SharedPreferences對象本身只能獲取數據而不支持存儲和修改,存儲修改是通過Editor對象實現。實現SharedPreferences存儲的步驟如下:

一、根據Context獲取SharedPreferences對象

二、利用edit()方法獲取Editor對象。

三、通過Editor對象存儲key-value鍵值對數據。

四、通過commit()方法提交數據。

具體實現代碼如下:實現存儲,讀取,清除,刪除

效果圖:

首先創建:// 首先拿到sharedpreference對象

mShared =getSharedPreferences(SHARED_MAIN_XML, MODE_PRIVATE);

存儲:

private void write() {// 存入數據

savename = name.getText().toString().trim();

saveage = Integer.valueOf(age.getText().toString().trim());

Editor editor = mShared.edit();

editor.putString("name", savename);

editor.putInt("age", saveage);

// 保證操作的事務完整性

editor.commit();

}

閱讀:

private String read() {// 從資料庫里讀取數據

namecontent = mShared.getString("name", "資料庫里沒有存儲姓名");

agecontent = mShared.getInt("age", 0);

String reading = "姓名:" + namecontent + "\n年齡:" + agecontent;

return reading;

}

清除內容:

private void clear() {//清除內容

/** 開始清除SharedPreferences中保存的內容 **/

Editor editor = mShared.edit();

editor.remove("name");

editor.remove("age");

editor.commit();

}

刪除文件:

private void delete() {//刪除文件

/** 刪除SharedPreferences文件 **/

Filefile = new File("/data/data/cn.csdn.activity" + "/shared_prefs/"

+ SHARED_MAIN_XML + ".xml");

if (file.exists()) {

file.delete();

Toast.makeText(this, "刪除成功", Toast.LENGTH_LONG).show();

}

}

haredPreferences對象與SQLite資料庫相比,免去了創建資料庫,創建表,寫SQL語句等諸多操作,相對而言更加方便,簡潔。但是SharedPreferences也有其自身缺陷,比如其職能存儲boolean,int,float,long和String五種簡單的數據類型,比如其無法進行條件查詢等。所以不論SharedPreferences的數據存儲操作是如何簡單,它也只能是存儲方式的一種補充,而無法完全替代如SQLite資料庫這樣的其他數據存儲方式。

2、File: 即常說的文件(I/O)存儲方法,常用存儲大數量的數據,但是缺點是更新數據將是一件困難的事情。

下面實現:在本地data文件下使用自己生成的文件處理數據的新建儲存 讀取 刪除

如果說不想把內容存在SharedPreferences中的話,我們可以自己寫一個文件保存須要的數據,在這里我將文件保存在系統中的工程路徑下。

跟上面布局一樣,刪除文件也一樣,清除內容也查不多,下面只是簡單的寫和讀的方法:

寫:

17String
nameage="名字:"+name.getText().toString().trim()+"年齡:"+age.getText().toString();

try {

os = this.openFileOutput(SHARED_MAIN_XML, MODE_PRIVATE);

/* 把字元串轉換成位元組數組,寫入文件中 */

os.write(nameage.getBytes());

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}finally {

try {

/* 關閉文件輸出流 */

os.close();

} catch (IOException e) {

e.printStackTrace();

}

}

讀:

private String read() {

String nameage="";

// 打開文件輸入流,

try {

is = this.openFileInput(SHARED_MAIN_XML);

/* 初始化位元組數組 */

b = new byte[1024];

/* 從文件輸入流中讀取內容到位元組數組中,返回內容長度 */

int length = is.read(b);

/* 把位元組數組轉換成字元串 */

nameage= new String(b);

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return nameage;

}

很簡單吧!!

3、SQLite是一種轉為嵌入式設備設計的輕型資料庫,其只有五種數據類型,分別是:

NULL: 空值

INTEGER: 整數

REAL: 浮點數

TEXT: 字元串

BLOB: 大數據

它是一個輕量級的資料庫、非常小 、 移植性好、效率高、可靠

在Android系統中提供了android.database.sqlite包,用於進行SQLite資料庫的增、刪、改、查工作。

創建與刪除資料庫

封裝一個類去繼承SQLiteOpenHelper
在構造函數中傳入資料庫名稱與資料庫版本號,資料庫被創建的時候會調用onCreate(SQLiteDatabase db)
方法,資料庫版本號發生改變的時候會調用onUpgrade(SQLiteDatabase db, int oldVersion,
intnewVersion)方法,可以方便的對軟體游戲升級後做出相應處理避免覆蓋安裝資料庫發生改變產生的錯誤。調用SQLiteOpenHelper
的getReadableDatabase()方法去創建資料庫,如果資料庫不存在則創建並且返回SQLiteDatabase對象,如果資料庫存在則不創建只返回SQLiteDatabase對象。調用
deleteDatabase(DATABASE_NAME)方法 傳入資料庫名稱則可刪除資料庫。

第一種:詳細請看上一遍博客:android之利用SQLite資料庫實現登陸和注冊,http://blog.csdn.net/rhljiayou/article/details/7085347

下面介紹第二種:另一種添刪改查操作

效果圖:

布局文件很簡單,在此不再給出!!

直接給創建資料庫和表,增刪改查的代碼:

public class UserService {

private DatabaseHelper helper;

public UserService(Context context, String name, int version) {

helper = new DatabaseHelper(context, name, version);

}

public UserService(Context context, String name) {

helper = new DatabaseHelper(context, name);

}

public void insert(UserDao user) {// 插入數據

SQLiteDatabase sdb = helper.getWritableDatabase();

ContentValues values = new ContentValues();

values.put("username", user.getUsername());

values.put("password", user.getPassword());

sdb.insert("user", "name", values);

sdb.close();

}

public void delete(int id) {// 刪除數據

SQLiteDatabase sdb = helper.getWritableDatabase();

sdb.delete("user", "id=?", new String[]{String.valueOf(id)});

sdb.close();

}

public void update(UserDao user, int id) {// 更新數據

SQLiteDatabase sdb = helper.getWritableDatabase();

ContentValues values=new ContentValues();

values.put("username", user.getUsername());

values.put("password", user.getPassword());

sdb.update("user", values, "id=?", new String[]{String.valueOf(id)});

sdb.close();

}

public Cursor select() {// 查詢所有數據

SQLiteDatabase sdb = helper.getWritableDatabase();

return sdb.query("user", new String[]{"id as _id","username","password"},
null, null, null, null, null);

}

public UserDao find(int id){//按id查詢數據

UserDao user=null;

SQLiteDatabase sdb=helper.getWritableDatabase();

Cursor cursor=sdb.query("user", new String[]{"id","username","password"},
"id=?", new String[]{String.valueOf(id)}, null, null, null);

if(cursor.moveToFirst()){

user=new UserDao();

user.setId(cursor.getInt(0));

user.setUsername(cursor.getString(1));

user.setPassword(cursor.getString(2));

}

cursor.close();

sdb.close();

return user;

}

}

插入數據:通過insert(String table, StringnullColumnHack, ContentValues
values)方法插入數據,其中參數含義分別為:

table: 目標表名

nullColumnHack:
指定表中的某列列名。因為在SQLite中,不允許不允許插入所有列均為null的記錄,因此初始值有值為空時,此列需顯式賦予null

values:ContentValues對象,類似於java中的Map。以鍵值對的方式保存數據。

E. Arcgis for Android identify 和query查詢遇到的問題,求教

事件如果只是+=了,只是注冊,至於怎麼觸發要看你自己何時觸發了.
不用for循環的話querytask.execute(query);完了舉含的話,就會執行onComplete事件,用上for循環就出現我上面兆陵說的問題了,下面是問題正猜笑代碼
for(){
querytask.execute(query);
}
dojo.connect(querytask,"onComplete",function(){
});

F. android安卓資料庫的增刪改查和發送通知

{
privatestaticfinalStringname="zhouke.db";
privatestaticfinalintversion=1;
publicMyDbOpenHeler(Contextcontext){
super(context,name,null,version);
}

@Override
publicvoidonCreate(SQLiteDatabasedb){
db.execSQL("createtableifnotexistsword(_,namevarchar(20),ageint)");
}

@Override
publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){

}
}


------------------------------------------------


{
ListViewlv;
MyDbOpenHelerheler;
SQLiteDatabasedb;
SimpleCursorAdapteradapter;

EditTextet1;

//通知
NotificationManagermanage;
//---
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
lv=(ListView)findViewById(R.id.lv);
//實例化資料庫幫助類
heler=newMyDbOpenHeler(this);
//獲取一個可讀寫的資料庫操作對象
db=heler.getWritableDatabase();
Cursorword=db.query("word",null,null,null,null,null,"_iddesc");
adapter=newSimpleCursorAdapter(this,R.layout.list_ltem,word,
newString[]{"_id","name","age"},newint[]{R.id.tv1,R.id.tv2,R.id.tv3},
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
lv.setAdapter(adapter);
//if(word.isClosed()){
//word.close();
//}
registerForContextMenu(lv);
//通知的實例化
manage=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
//---
et1=(EditText)findViewById(R.id.et1);


}
//創建選項菜單
@Override
(Menumenu){
menu.add(1,1,0,"增");
returnsuper.onCreateOptionsMenu(menu);
}
//選項菜單監聽事件
@Override
(MenuItemitem){
Viewinflate=View.inflate(this,R.layout.dialog,null);
finalEditTextet1=(EditText)inflate.findViewById(R.id.et1);
finalEditTextet2=(EditText)inflate.findViewById(R.id.et2);
newAlertDialog.Builder(this).setTitle("增加新學生信息").setView(inflate)
.setPositiveButton("確認",newDialogInterface.OnClickListener(){
@Override
publicvoidonClick(DialogInterfacedialog,intwhich){
ContentValuescv=newContentValues();
cv.put("name",et1.getText().toString());
cv.put("age",et2.getText().toString());

longword=db.insert("word",null,cv);
if(word>0){
Toast.makeText(Main2Activity.this,"增加數據成功",Toast.LENGTH_SHORT).show();
Cursorword2=db.query("word",null,null,null,null,null,"_iddesc");
adapter.changeCursor(word2);

//通知---開始
NotificationCompat.Builderbuilder=newNotificationCompat.Builder(Main2Activity.this);
builder.setSmallIcon(R.drawable.aa)
.setContentText("年齡:"+et2.getText().toString())
.setContentTitle(et1.getText().toString())
.setAutoCancel(true);
manage.notify(1,builder.build());
//通知--結束


}
}
}).setNegativeButton("取消",newDialogInterface.OnClickListener(){
@Override
publicvoidonClick(DialogInterfacedialog,intwhich){

}
}).show();
returnsuper.onOptionsItemSelected(item);
}
//創建上下文菜單
@Override
publicvoidonCreateContextMenu(ContextMenumenu,Viewv,ContextMenu.ContextMenuInfomenuInfo){
super.onCreateContextMenu(menu,v,menuInfo);
menu.add(1,2,0,"修改");
menu.add(1,3,0,"刪除");
}
//上下文菜單監聽事件
@Override
(MenuItemitem){
//獲取當前點擊項的索引
AdapterView.AdapterContextMenuInfoinfo=(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
intposition=info.position;
//根據索引獲取這一行數據,把它轉化為Cursor
Cursorcursor=(Cursor)adapter.getItem(position);
//從結果集中取出id
finalint_id=cursor.getInt(0);
switch(item.getItemId()){
case2:
Viewinflate=View.inflate(this,R.layout.dialog,null);
finalEditTextet1=(EditText)inflate.findViewById(R.id.et1);
finalEditTextet2=(EditText)inflate.findViewById(R.id.et2);
//獲取單詞名稱
Stringname=cursor.getString(1);
Stringage=cursor.getString(2);
et1.setText(name);
et2.setText(age);
newAlertDialog.Builder(this).setTitle("修改學生信息").setView(inflate)
.setPositiveButton("確認",newDialogInterface.OnClickListener(){
@Override
publicvoidonClick(DialogInterfacedialog,intwhich){
ContentValuescv=newContentValues();
cv.put("name",et1.getText().toString());
cv.put("age",et2.getText().toString());

intword=db.update("word",cv,"_id=?",newString[]{String.valueOf(_id)});


if(word>0){
Toast.makeText(Main2Activity.this,"修改數據成功",Toast.LENGTH_SHORT).show();
Cursorword2=db.query("word",null,null,null,null,null,"_iddesc");
adapter.changeCursor(word2);
}
}
}).setNegativeButton("取消",newDialogInterface.OnClickListener(){
@Override
publicvoidonClick(DialogInterfacedialog,intwhich){

}
}).show();

break;
case3:
intword=db.delete("word","_id=?",newString[]{String.valueOf(_id)});
if(word>0){
Toast.makeText(Main2Activity.this,"刪除數據成功",Toast.LENGTH_SHORT).show();
Cursorword2=db.query("word",null,null,null,null,null,"_iddesc");
adapter.changeCursor(word2);
}
break;
}
returnsuper.onContextItemSelected(item);
}

publicvoidclick1(Viewview){
//模糊查詢
Stringaa=et1.getText().toString();
Cursorword2=db.query("word",null,"namelike?",newString[]{"%"+aa+"%"},null,null,"_iddesc");
adapter.changeCursor(word2);
//正常查詢
//Cursorword2=db.query("word",null,"name=?",newString[]{aa},null,null,"_iddesc");
}
}

G. 如何進行Android資料庫操作

Android資料庫操作類實例
實體類:UserInfo.java
package my.db;
import java.io.Serializable;
import android.graphics.drawable.Drawable;
public class UserInfo implements Serializable {
public static final String ID = "_id";
public static final String USERID = "userId";
public static final String TOKEN = "token";
public static final String TOKENSECRET = "tokenSecret";
public static final String USERNAME = "userName";
public static final String USERICON = "userIcon";
private String id;
private String userId; // 用戶id
private String token;
private String tokenSecret;
private String userName;
private Drawable userIcon;
//getter and setter省略
}
SqliteHelper類:
package my.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class SqliteHelper extends SQLiteOpenHelper{
//用來保存UserID、Access Token、Access Secret的表名
public static final String TB_NAME= "users";
public SqliteHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
//創建表
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL( "CREATE TABLE IF NOT EXISTS "+
TB_NAME+ "("+
UserInfo. ID+ " integer primary key,"+
UserInfo. USERID+ " varchar,"+
UserInfo. TOKEN+ " varchar,"+
UserInfo. TOKENSECRET+ " varchar,"+
UserInfo. USERNAME+ " varchar,"+
UserInfo. USERICON+ " blob"+
")"
);
Log. e("Database" ,"onCreate" );
}
//更新表
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL( "DROP TABLE IF EXISTS " + TB_NAME );
onCreate(db);
Log. e("Database" ,"onUpgrade" );
}
//更新列
public void updateColumn(SQLiteDatabase db, String oldColumn, String newColumn, String typeColumn){
try{
db.execSQL( "ALTER TABLE " +
TB_NAME + " CHANGE " +
oldColumn + " "+ newColumn +
" " + typeColumn
);
} catch(Exception e){
e.printStackTrace();
}
}
}
CRUD類DataHelper:
package my.db;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.Log;
public class DataHelper {
// 資料庫名稱
private static String DB_NAME = "weibo.db";
// 資料庫版本
private static int DB_VERSION = 2;
private SQLiteDatabase db;
private SqliteHelper dbHelper;
public DataHelper(Context context) {
dbHelper = new SqliteHelper(context, DB_NAME, null, DB_VERSION );
db = dbHelper.getWritableDatabase();
}
public void Close() {
db.close();
dbHelper.close();
}
// 獲取users表中的UserID、Access Token、Access Secret的記錄
public List<UserInfo> GetUserList(Boolean isSimple) {
List<UserInfo> userList = new ArrayList<UserInfo>();
Cursor cursor = db.query(SqliteHelper. TB_NAME, null, null , null, null,
null, UserInfo. ID + " DESC");
cursor.moveToFirst();
while (!cursor.isAfterLast() && (cursor.getString(1) != null )) {
UserInfo user = new UserInfo();
user.setId(cursor.getString(0));
user.setUserId(cursor.getString(1));
user.setToken(cursor.getString(2));
user.setTokenSecret(cursor.getString(3));
if (!isSimple) {
user.setUserName(cursor.getString(4));
ByteArrayInputStream stream = new ByteArrayInputStream(cursor.getBlob(5));
Drawable icon = Drawable.createFromStream(stream, "image");
user.setUserIcon(icon);
}
userList.add(user);
cursor.moveToNext();
}
cursor.close();
return userList;
}
// 判斷users表中的是否包含某個UserID的記錄
public Boolean HaveUserInfo(String UserId) {
Boolean b = false;
Cursor cursor = db.query(SqliteHelper. TB_NAME, null, UserInfo.USERID
+ "=?", new String[]{UserId}, null, null, null );
b = cursor.moveToFirst();
Log. e("HaveUserInfo", b.toString());
cursor.close();
return b;
}
// 更新users表的記錄,根據UserId更新用戶昵稱和用戶圖標
public int UpdateUserInfo(String userName, Bitmap userIcon, String UserId) {
ContentValues values = new ContentValues();
values.put(UserInfo. USERNAME, userName);
// BLOB類型
final ByteArrayOutputStream os = new ByteArrayOutputStream();
// 將Bitmap壓縮成PNG編碼,質量為100%存儲
userIcon.compress(Bitmap.CompressFormat. PNG, 100, os);
// 構造SQLite的Content對象,這里也可以使用raw
values.put(UserInfo. USERICON, os.toByteArray());
int id = db.update(SqliteHelper. TB_NAME, values, UserInfo.USERID + "=?" , new String[]{UserId});
Log. e("UpdateUserInfo2", id + "");
return id;
}
// 更新users表的記錄
public int UpdateUserInfo(UserInfo user) {
ContentValues values = new ContentValues();
values.put(UserInfo. USERID, user.getUserId());
values.put(UserInfo. TOKEN, user.getToken());
values.put(UserInfo. TOKENSECRET, user.getTokenSecret());
int id = db.update(SqliteHelper. TB_NAME, values, UserInfo.USERID + "="
+ user.getUserId(), null);
Log. e("UpdateUserInfo", id + "");
return id;
}
// 添加users表的記錄
public Long SaveUserInfo(UserInfo user) {
ContentValues values = new ContentValues();
values.put(UserInfo. USERID, user.getUserId());
values.put(UserInfo. TOKEN, user.getToken());
values.put(UserInfo. TOKENSECRET, user.getTokenSecret());
Long uid = db.insert(SqliteHelper. TB_NAME, UserInfo.ID, values);
Log. e("SaveUserInfo", uid + "");
return uid;
}
// 添加users表的記錄
public Long SaveUserInfo(UserInfo user, byte[] icon) {
ContentValues values = new ContentValues();
values.put(UserInfo. USERID, user.getUserId());
values.put(UserInfo. USERNAME, user.getUserName());
values.put(UserInfo. TOKEN, user.getToken());
values.put(UserInfo. TOKENSECRET, user.getTokenSecret());
if(icon!= null){
values.put(UserInfo. USERICON, icon);
}
Long uid = db.insert(SqliteHelper. TB_NAME, UserInfo.ID, values);
Log. e("SaveUserInfo", uid + "");
return uid;
}
// 刪除users表的記錄
public int DelUserInfo(String UserId) {
int id = db.delete(SqliteHelper. TB_NAME,
UserInfo. USERID + "=?", new String[]{UserId});
Log. e("DelUserInfo", id + "");
return id;
}
public static UserInfo getUserByName(String userName,List<UserInfo> userList){
UserInfo userInfo = null;
int size = userList.size();
for( int i=0;i<size;i++){
if(userName.equals(userList.get(i).getUserName())){
userInfo = userList.get(i);
break;
}
}
return userInfo;
}
}

H. android query 模糊查詢怎麼使用

關於Android中 Cursor 的query加入明御模糊查詢的條件,有如下方式:
1.使用這種query方法%號前不能加',以下為示例代碼:
Cursor c_test = mDatabase.query(tab_name, new String[]{tab_field02}, tab_field02+" LIKE ? ",
new String[] { "%" + str[0] + "%" }, null, null, null);

2.使用這則槐氏種query方法%號前必須加',以下為示例代碼 :
Cursor c_test=mDatabase.query(tab_name, new String[]{tab_field02},tab_field02+" like '%" + str[0] + "%'孫散", null, null, null, null);

3.使用這種方式必須在%號前加' ,以下為示例代碼 :
String current_sql_sel = "SELECT * FROM "+tab_name +" where "+tab_field02+" like '%"+str[0]+"%'";
Cursor c_test = mDatabase.rawQuery(current_sql_sel, null);

I. Arcgis for Android identify 和query查詢遇到的問題,求教

1、QueryTask:是一個進行空間和屬性查詢的功能類,它可以在某個地圖服務的某個子圖層內進行查詢,順便提一下的是,QueryTask進行查詢的地圖服務並不必須載入到Map中進行顯示。QueryTask的執行需要兩個先決條件:悶臘戚一個是需要查詢的圖層URL、一個是進行查詢的過濾條件。
下面是QueryTask的基本過程:

//新建一個QueryTask
QueryTask queryTask = new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5");

// Query對象
Query query = new Query();

//傳入空間幾何范圍,可以不設置
//合法的geometry類型是Extent, Point, Multipoint, Polyline, Polygon
query.Geometry = geometry;

//是否返回查詢結果的空間幾何信息
query.ReturnGeometry = true;

//查詢結果返回的欄位,欄位必須在圖層中,欄位的大小寫可忽略
query.OutFields.AddRange(new string[] { "AREANAME", "POP2000" });
//quer.OutField.Add("*"局彎); //返回所有欄位

//查詢的where條件,可以是任何合法的SQL語句,可以不設置
query.Where = "POP2000 > 350000";

//非同步查詢,需要綁定queryTask的兩個事件,通過ExecuteCompleted得到查詢結果
queryTask.ExecuteCompleted += QueryTask_ExecuteCompleted;
queryTask.Failed += QueryTask_Failed;
queryTask.ExecuteAsync(query);

//同步查詢,不需要綁定事件,直接返回查詢結果
//FeatureSet featureSet = queryTask.Execute(query);

2、螞陵FindTask:允許對地圖中一個或多個圖層的要素進行基於屬性欄位值的查詢(search one or more layers in a map for features with attribute values that match or contain an input value)。FindTask不能進行「空間查詢」,因為FindTask可以對多個圖層進行查詢,所有它的url屬性需要指向所查詢的地圖服務的REST URL,而不像QueryTask需要指定某個圖層的URL。
下面是FindTask的基本過程:

//新建一個Find task
FindTask findTask = new FindTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/");

//非同步執行,綁定事件
findTask.ExecuteCompleted += FindTask_ExecuteCompleted;
findTask.Failed += FindTask_Failed;

//初始化FindParameters參數
FindParameters findParameters = new FindParameters();
findParameters.LayerIds.AddRange(new int[] { 3 }); //查找的圖層
findParameters.SearchFields.AddRange(new string[] { "NAME" }); //查找的欄位范圍
findParameters.ReturnGeometry = true;
findParameters.SearchText = FindTextBox.Text; //查找的「屬性值」

//設置查詢的LayerDefinitions
ESRI.ArcGIS.Client.LayerDefinition myDefinition = new ESRI.ArcGIS.Client.LayerDefinition();
myDefinition.LayerID = 3;
//設置LayerDefinition,屬性欄位「Name」屬於ID為0的圖層
//LayerDefinition的設置語句和Query中的Where語句一樣
myDefinition.Definition = "NAME = 'XXX'";

//創建一個ObservableCollection,add設置的LayerDefinition
System.Collections.ObjectModel.ObservableCollection<LayerDefinition> myObservableCollection =
new System.Collections.ObjectModel.ObservableCollection<LayerDefinition>();
myObservableCollection.Add(myDefinition);
findParameters.LayerDefinitions = myObservableCollection; //設置查詢的LayerDefinitions

//非同步執行
findTask.ExecuteAsync(findParameters);

3、IdentifyTask:是一個在地圖服務中識別要素(Feature)的功能類。通過IdentifyTask可以搜索地圖層中與輸入幾何形相交的要素(search the layers in a map for features that intersect an input geometry)。因為也是在多個圖層中查詢,所以Task的URL是動態圖層服務的地址。同樣,返回的要素都可以作為Graphic被添加到地圖的GraphicsLayer上。
基本過程如下:

//新建一個Identify task
IdentifyTask identifyTask = new IdentifyTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer");

//非同步執行,綁定事件
identifyTask.ExecuteCompleted += IdentifyTask_ExecuteCompleted;
identifyTask.Failed += IdentifyTask_Failed;

//初始化 Identify parameters
IdentifyParameters identifyParameters = new IdentifyParameters();
identifyParameters.LayerOption = LayerOption.all;

//傳遞地圖屬性給 identify parameters
identifyParameters.MapExtent = MyMap.Extent;
identifyParameters.Width = (int)MyMap.ActualWidth;
identifyParameters.Height = (int)MyMap.ActualHeight;

//輸入的幾何參數為一個點,args來自點擊事件
identifyParameters.Geometry = args.MapPoint; //Point Envelop Extent polyline polygon

//設置查詢的LayerDefinitions
ESRI.ArcGIS.Client.LayerDefinition myDefinition = new ESRI.ArcGIS.Client.LayerDefinition();
myDefinition.LayerID = 3;
//設置LayerDefinition,屬性欄位「Name」屬於ID為0的圖層
//LayerDefinition的設置語句和Query中的Where語句一樣
myDefinition.Definition = "NAME = 'XXX'";
//創建一個ObservableCollection,add設置的LayerDefinition
System.Collections.ObjectModel.ObservableCollection<LayerDefinition> myObservableCollection =
new System.Collections.ObjectModel.ObservableCollection<LayerDefinition>();
myObservableCollection.Add(myDefinition);
identifyParameters.LayerDefinitions = myObservableCollection; //設置查詢的LayerDefinitions

//非同步執行
identifyTask.ExecuteAsync(identifyParameters);

三種查詢的返回結果:
QueryTask:返回的是一個FeatureSet。Featureset.features[i]可以加入到GraphicsLayer上顯示,也可以通過Attributes屬性欄位得到屬性信息。
FindTask:返回的是一個FindResults數組, FindResults[i].feature可以加入到GraphicsLayer上顯示,也可以通過Attributes屬性欄位得到屬性信息。
IdentifyTask:返回的是一個IdentifyResults數組,IdentifyResults[i].feature可以加入到GraphicsLayer上顯示,也可以通過Attributes屬性欄位得到屬性信息。

J. Arcgis runtime for Android 100.5 (九) 空間查詢

(八) 業務圖層管理

查詢方法

跟上邊用法差不多,只不過查詢結果中獲取到的是graphic

查詢參數
QueryParameters(com.esri.arcgisruntime.data.QueryParameters)是頃頌queryFeaturesAsync、selectFeaturesAsync的查詢參數

FeatureLayer的selectFeaturesAsync方法實際上是 要素選擇 ,族乎胡但從實現結果上來說相當於空間查詢。同時,查詢的結果會兆攔被高亮顯示。高亮顯示可以通過FeatureLayer設置顏色和寬度(厚度)

(十) Callout

熱點內容
誤刪除文件夾恢復工具 發布:2024-04-24 20:31:57 瀏覽:382
php介面編寫 發布:2024-04-24 20:31:06 瀏覽:67
怎麼架設雙線伺服器 發布:2024-04-24 20:25:55 瀏覽:638
通易雲源碼 發布:2024-04-24 20:14:55 瀏覽:962
安卓手機卸載更新什麼意思 發布:2024-04-24 19:29:35 瀏覽:227
文件des加密 發布:2024-04-24 19:24:20 瀏覽:705
魔獸世界data文件夾 發布:2024-04-24 19:24:13 瀏覽:214
蘋果手機怎麼清空緩存 發布:2024-04-24 19:23:38 瀏覽:893
微信密碼沒有手機號如何找回 發布:2024-04-24 19:18:20 瀏覽:875
微雲解析源碼 發布:2024-04-24 19:13:58 瀏覽:792