導航:首頁 > 操作系統 > androidslog

androidslog

發布時間:2025-06-14 01:51:16

A. 用android uiautomator做自動化測試,怎麼連接真機進行

Google在sdk4.0以後提供了一個自動化解決方案uiautomator:

優點:可以跨應用了;這可是親生的;

缺點:必須sdk4.0以上版本;要想實現的好,最好有開發配合;java項目編譯為jar後需要push到手機才能運行,也就是說必須列印日誌暴力調試。

Appium基於Android InstrumentationFramework和UIAutomator,也就是說這個工具是可以跨應用的。說遠了,好吧,為了幫大家更容易理解appium的使用,我這里就講一下uiautomator的使用方法。

你應該有android-sdk吧,升級到4.0以上,進入目錄android-sdk ools,你會看到兩個文件:

traceview.bat 和 uiautomatorviewer.bat,這倆文件讓你想起了monkeyrunner了吧,是的,traceview.bat就對應於hierarchyviewer.bat,用來查看程序的ui界面的,通常也是使用管理員許可權啟動的。

好了,現在用eclipse創建一個java project,是的,你沒看錯,是java project不是android project,添加引用:

在project.properties中內容為:

# Project target.

target=android-16

這里的android-16需要和之前的android.jar和uiautomator.jar位置相一致。

然後呢?寫代碼吧,建立一個類,得,發個給大家參考:

packagecom.uia.example.my;

importorg.apache.http.util.EncodingUtils;

importandroid.graphics.Bitmap;

importandroid.graphics.BitmapFactory;

importandroid.graphics.Rect;

importandroid.os.Environment;

importcom.android.uiautomator.core.UiObject;

importcom.android.uiautomator.core.UiObjectNotFoundException;

importcom.android.uiautomator.core.UiScrollable;

importcom.android.uiautomator.core.UiSelector;

importcom.android.uiautomator.testrunner.UiAutomatorTestCase;

importjava.io.File;

importjava.io.FileOutputStream;

importjava.io.IOException;

{

publicStringsLog;

publicFilefout=null;

=null;

publicvoidwrite2file(String filename,String sData)

{

String sLog="";

//初始化日誌文件

if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){

sLog = Environment.getExternalStorageDirectory().getAbsolutePath();

try{

fout=newFile(sLog,filename);

outStream=newFileOutputStream(fout,true);//此處的true是append

sData=sData +" ";

outStream.write(sData.getBytes());

outStream.flush();

outStream.close();

fout=null;

}

catch(Exception e){

e.printStackTrace();

}

}else{

System.out.println("該手機沒有SD卡");

}

}

publicvoidtestDemo() {

//1.啟動app

getUiDevice().pressHome();

UiObject allAppsButton =newUiObject(newUiSelector().description("Apps"));

allAppsButton.clickAndWaitForNewWindow();

UiObject appsTab =newUiObject(newUiSelector().text("Apps"));

appsTab.click();

UiScrollable appViews =newUiScrollable(newUiSelector().scrollable(true));

UiObject settingsApp = appViews.getChildByText(newUiSelector().className(android.widget.TextView.class.getName()),"Efilm");

settingsApp.clickAndWaitForNewWindow();

//2.進入主界面

System.out.println("into main view");

System.out.println(getUiDevice().waitForWindowUpdate("com.eshore.efilm", 60000));

System.out.println("intoed main view");

UiObject tv1 =newUiObject(newUiSelector().text("影院"));

tv1.click();

//3.點擊影院

UiObject oyy=newUiObject(newUiSelector().description("cinema_row"));

System.out.println("wait yingyuan come out");

oyy.waitForExists(60000);

System.out.println("yingyuan come out");

oyy.clickAndWaitForNewWindow();

System.out.println("click yingyuan");

//4.場次

UiObject occ=newUiObject(newUiSelector().description("LinearLayout10"));

System.out.println("wait changci come out");

oyy.waitForExists(60000);

System.out.println("changci come out");

occ.clickAndWaitForNewWindow();

System.out.println("click changci");

//5.座位

UiObject oseat=newUiObject(newUiSelector().description("cinema_shows_list_item").index(0).childSelector(newUiSelector().description("LinearLayout10")));

System.out.println("wait seat come out");

oseat.waitForExists(5000);

inth=getUiDevice().getDisplayHeight();

intw=getUiDevice().getDisplayWidth();

System.out.println("(h/2,w/2)="+h/2+","+w/2);

getUiDevice().click(h/2,w/2);

//System.out.println("seat count:"+String.valueOf(oseat.getChildCount()));

//System.out.println("seat getText:"+ oseat.getText());

//截座點陣圖

Process process;

try{

process = Runtime.getRuntime().exec("screencap /mnt/sdcard/EfilmFailSnapShot01.png");

try{

process.waitFor();

}catch(InterruptedException e) {//TODOAuto-generated catch block

e.printStackTrace();

}

}catch(IOException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

//takeScreenShots("EfilmSeatSnapShot");

}

}

這個例子是隨便寫的,可能不夠嚴謹。大體就這么個情況吧。下一步就是編譯執行了,先插上手機usb介面,然後打開cmd,執行:

找到SDKID,也就是android create中的-t參數:

cd C: PROGRAMandroid-sdk ools

android list

找到t參數的值以後:

cd C: PROGRAMandroid-sdk ools

android create uitest-project -n TAppWorkAssistV1 -t 25 -p C:android自動化Tv2.0TestSetting

cd C:android自動化Tv2.0TestSetting

ant build

cd C:android自動化Tv2.0TestSettingin

adb push TAppWorkAssistV1.jar /data/local/tmp/

adb shell uiautomator runtest TAppWorkAssistV1.jar -c com.uia.example.my. TAppWorkAssistV1

看了看,好像沒有什麼特別值得解釋的

-n TAppWorkAssistV1:類名

-p: 項目所在目錄

Ant build 把這個類編譯成一個jar包:TAppWorkAssistV1.jar

然後把jar包push到手機上,調用執行這個類就可以了

大致是這么個步驟,不過有一個非常重要的細節,就是如果你需要更省心,就最好把界面元素,無論動態的還是布局文件中的,都加上content-description屬性,並保證唯一性,根據:

UiSelector:description(String desc)

Set the search criteria to match thecontent-description property for a widget.

那就可以統一隻使用這一個引用界面元素的方法就行了,就不用去想方設法利用其它的屬性來引用了。

B. 如何通過反射使用BluetoothHeadset類

Usb
setting 中tethering 設置流程

一 資源位置及入口文件

USB
tethering, usb_tethering_button_text

Xml/tether_prefs.xml------usb_tether_settings,布局文件

packages/apps/Settings/AndroidManifest.xml

<!-- Keep compatibility with old
shortcuts. -->

<activity-alias
android:name=".TetherSettings"

android:label="@string/tether_settings_title_all"

android:clearTaskOnLaunch="true"

android:exported="true"

android:targetActivity="Settings$TetherSettingsActivity">

<meta-data
android:name="com.android.settings.FRAGMENT_CLASS"

android:value="com.android.settings.TetherSettings"
/>

<meta-data
android:name="com.android.settings.TOP_LEVEL_HEADER_ID"

android:resource="@id/wireless_settings"
/>

<meta-data
android:name="com.android.settings.PARENT_FRAGMENT_TITLE"

android:resource="@string/wireless_networks_settings_title"
/>

<meta-data
android:name="com.android.settings.PARENT_FRAGMENT_CLASS"

android:value="com.android.settings.Settings$WirelessSettingsActivity"
/>

</activity-alias>

TetherSettings.java

二 觸發流程

2.1
TetherSettings.java

packages/apps/Settings/src/com/android/settings/TetherSettings.java

onPreferenceTreeClick

SXlog.d(TAG,
"onPreferenceTreeClick - setusbTethering(" + newState + ")
mUsbTethering: " + mUsbTethering);

setUsbTethering(true);

下面是設置時抓取的log日誌

D/TetherSettings( 543): onPreferenceTreeClick -
setusbTethering(true) mUsbTethering: true

D/Tethering(
271): setUsbTethering(true)

D/UsbDeviceManager( 271):
setCurrentFunction(rndis) default: false

W/UsbDeviceManager( 271): handleMessage:
2

W/UsbDeviceManager( 271): setEnabledFunctions:
functions = rndis

W/UsbDeviceManager( 271): setEnabledFunctions,
mDefaultFunctions: mtp,adb

W/UsbDeviceManager( 271): setEnabledFunctions,
mCurrentFunctions: mtp,adb

D/UsbDeviceManager( 271): setEnabledFunctions,
mSettingFunction: mtp,adb

W/UsbDeviceManager( 271): containsFunction,
functions: rndis

W/UsbDeviceManager( 271): containsFunction,
function: adb

W/UsbDeviceManager( 271): containsFunction
index: -1

W/UsbDeviceManager( 271): addFunction,
functions: rndis

W/UsbDeviceManager( 271): addFunction, function:
adb

W/UsbDeviceManager( 271): containsFunction,
functions: rndis

W/UsbDeviceManager( 271): containsFunction,
function: acm

W/UsbDeviceManager( 271): containsFunction
index: -1

W/UsbDeviceManager( 271): containsFunction,
functions: rndis,adb

W/UsbDeviceManager( 271): containsFunction,
function: acm

W/UsbDeviceManager( 271): containsFunction
index: -1

D/UsbDeviceManager( 271):
setUsbConfig(none)

W/UsbDeviceManager( 271): setUsbConfig, config:
none

public
boolean onPreferenceTreeClick(PreferenceScreen
screen, Preference preference) {

ConnectivityManager cm =

(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

if
(preference == mUsbTether) {

if
(!mUsbTethering) {

boolean
newState = mUsbTether.isChecked();

mUsbTethering = true;

mUsbTetherCheckEnable = false;

mUsbTether.setEnabled(false);

SXlog.d(TAG,
"onPreferenceTreeClick - setusbTethering(" + newState + ")
mUsbTethering: " + mUsbTethering);

if
(newState) {

startProvisioningIfNecessary(USB_TETHERING);

} else
{

setUsbTethering(newState);

}

} else
{

return
true;

}

} else if
(preference == mBluetoothTether) {

private void
setUsbTethering(boolean
enabled) {

ConnectivityManager cm =

(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

if
(cm.setUsbTethering(enabled) !=
ConnectivityManager.TETHER_ERROR_NO_ERROR) {

mUsbTether.setChecked(false);

mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);

return;

}

mUsbTether.setSummary("");

}

2.2
ConnectivityManager.java

frameworks/base/core/java/android/net/ConnectivityManager.java

private
final IConnectivityManager
mService;

public int
setUsbTethering(boolean
enable) {

try
{

return
mService.setUsbTethering(enable);

} catch
(RemoteException e) {

return
TETHER_ERROR_SERVICE_UNAVAIL;

}

}

manager 和service有一個對應關系,固定的規則。 manager是為了sdk誕生的,方便app開發者調用。其實可以直接調用service,如mountservice是沒有mountmanager的。

service是在系統起來是就被android系統啟動的,而manager是後期有需要時實例化起來的。

Service的目錄在:/frameworks/base/services/java/com/android/server/

manager的目錄在:frameworks/base/core/java/android

2.3
ConnectivityService.java

frameworks/base/services/java/com/android/server

private
Tethering mTethering;

public int
setUsbTethering(boolean
enable) {

enforceTetherAccessPermission();

if
(isTetheringSupported()) {

return
mTethering.setUsbTethering(enable);

} else
{

return
ConnectivityManager.TETHER_ERROR_UNSUPPORTED;

}

}

2.4
Tethering.java

frameworks/base/services/java/com/android/server/connectivity/Tethering.java

public int
setUsbTethering(boolean
enable) {

UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);

………………

else
{

mUsbTetherRequested = true;

usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS,
false);

}

通過service,來獲取manager,進行操作。這個tethering.java的構造函數

public
Tethering(Context context,
INetworkManagementService nmService,

INetworkStatsService statsService,
IConnectivityManager connService, Looper looper)
{

Context是獲取全局信息的介面,

2.5 UsbManager.java

/frameworks/base/core/java/android/hardware/usb/UsbManager.java

public void setCurrentFunction(String
function, boolean makeDefault) {

try {

mService.setCurrentFunction(function,
makeDefault);

}
catch (RemoteException e) {

Log.e(TAG, "RemoteException in
setCurrentFunction", e);

}

}

2.6
frameworks/base/services/java/com/android/server/usb$

mengfd1@tablet-C:~/work/A2107/frameworks/base/services/java/com/android/server$
cd usb

mengfd1@tablet-C:~/work/A2107/frameworks/base/services/java/com/android/server/usb$
ls

UsbDeviceManager.java UsbHostManager.java
UsbService.java UsbSettingsManager.java

/frameworks/base/services/java/com/android/server/usb/UsbService.java

public void setCurrentFunction(String function, boolean
makeDefault) {

mContext.(android.Manifest.permission.MANAGE_USB,
null);

if
(mDeviceManager != null) {

mDeviceManager.setCurrentFunction(function,
makeDefault);

}
else {

throw new IllegalStateException("USB device
mode not supported");

}

}

/frameworks/base/services/java/com/android/server/usb/UsbDeviceManager.java

public void setCurrentFunction(String
function, boolean makeDefault) {

if
(DEBUG) Slog.d(TAG, "setCurrentFunction(" + function + ") default:
" + makeDefault);

mHandler.sendMessage(MSG_SET_CURRENT_FUNCTION,
function, makeDefault);

}

public void handleMessage(Message msg)
{

case
MSG_SET_CURRENT_FUNCTION:

String function =
(String)msg.obj;

boolean makeDefault = (msg.arg1 ==
1);

if (function != null
&&
function.equals(UsbManager.USB_FUNCTION_CHARGING_ONLY))
{

mSettingUsbCharging = true;

SXlog.d(TAG, "handleMessage -
MSG_SET_CURRENT_FUNCTION - USB_FUNCTION_CHARGING_ONLY -
makeDefault: " + makeDefault);

} else {

mSettingUsbCharging = false;

}

setEnabledFunctions(function,
makeDefault);

SXlog.d(TAG, "handleMessage -
MSG_SET_CURRENT_FUNCTION - function: " +
function);

break;

private void setEnabledFunctions(String
functions, boolean makeDefault) {

private boolean setUsbConfig(String config) {

SystemProperties.set("sys.usb.config",
config);

C. 如何創建android系統服務

1、 撰寫一個aidl文件,定義服務的介面,將在編譯過程中通過aidl工具生成對應的java介面。一般系統服務的aidl文件都放在framework\base\core\java\android\os目錄中。

以我所寫的IMyTool.aidl為例。在.aidl中定義自己需要加入的方法,編寫規則和java介面差不多,這里不多說。

2、 將aidl文件名添加到frameworks\base\目錄下的Android.mk編譯腳本文件中。

如:

LOCAL_SRC_FILES += \

core/java/android/accessibilityservice/.aidl\

…\

core/java/android/os/IMyTool.aidl\



IMyTool.aidl即我加進去的aidl文件,加入後才能在make過程中編譯到,否則將在後面的SystemServer添加系統服務時會報錯提示找不到對應類。

3、 編寫真正工作的服務類,繼承IMyTool.Stub類(AIDL文件名.Stub,aidl生成的介面中的內部類,是一個Binder)。

服務類一般都放在framework\base\services\java\com\android\server目錄中。

例如:

public class MyToolService extends IMyTool.Stub {

實現IMyTool.aidl中定義的介面。

}

4、 將自定義服務注冊到SystemServer,使得開機過程中被添加。

在framework\base\services\java\com\android\server目錄中的SystemServer中啟動服務代碼處加入:

try {

Slog.i(TAG, "MyToolService");

ServiceManager.addService(Context.MY_TOOL_SERVICE,new MyToolService(context));// MyToolService構造函數自己定義,一般都會用到Context

} catch(Throwable e) {

Slog.e(TAG, "Failure startingMyToolService", e);

}

上面代碼中Context.MY_TOOL_SERVICE是自己在Context類中定義的常量,也就是給服務定義的名字,使用常量方便獲取服務,而不需要記住注冊服務時用的名字,且想換名字時只需改一個常量的值。

閱讀全文

與androidslog相關的資料

熱點內容
5200U編程 瀏覽:615
linuxswap修改 瀏覽:155
單片機原理及介面第五版李朝青 瀏覽:951
g75編程為什麼報警 瀏覽:624
冰櫃壓縮機nh3 瀏覽:49
少數派app是什麼意思 瀏覽:162
常見壓縮方法 瀏覽:46
大型團購網站源碼 瀏覽:263
2019高級會計實務pdf 瀏覽:190
恆智天成怎麼解加密鎖 瀏覽:376
快手小店的app叫什麼名字 瀏覽:769
深夜的程序員 瀏覽:687
ftth成端演算法 瀏覽:361
方舟生存進化手游怎麼做伺服器 瀏覽:436
加班壓力大怎麼解壓 瀏覽:435
通達信中樞主圖指標源碼 瀏覽:141
程序員有女朋友然後忘記了 瀏覽:888
泡棉壓縮應力試驗機 瀏覽:953
pythonimportdb 瀏覽:699
動態鏈接編譯為什麼需要庫文件 瀏覽:461