android device ID (not IMEI) - android

I use the command: adb devices to list the attached devices.
On my computer I get :
List of devices attached
HT9CTP820988 device
My question is: how can I get this id (HT9CTP820988) programmatically ?

What you're seeing with the adb devices command is the serial number:
Serial number — A string created by
adb to uniquely identify an
emulator/device instance by its
console port number. The format of the
serial number is -.
Here's an example serial number:
emulator-5554
(refererence: http://developer.android.com/guide/developing/tools/adb.html)
When you ask "how can I get this id programmatically" what exactly do you mean? From an Android app or from a desktop app?

How about this one?
http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID
edit: Hmm I recall this, it can't be right; the ANDROID_ID is supposed to be 64-bit. Maybe the string you see is given by the USB driver?

Look at Settings.ACTION_DEVICE_INFO_SETTINGS and answers that have already been given in the past How to find serial number of Android device?

I think the emulator id's purpose is to identify the emulator and devices in the development environment. And it may not be accessible from the phone.

It's possible by changing *strings_dev* struct from drivers/usb/gadget/android.c

I'm Using the following code...
String aid = Settings.Secure.getString(getContext().getContentResolver(), "android_id");
Object obj = null;
try {
((MessageDigest) (obj = MessageDigest.getInstance("MD5"))).update( aid.getBytes(), 0, aid.length());
obj = String.format("%032X", new Object[] { new BigInteger(1, ((MessageDigest) obj).digest()) });
} catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
obj = aid.substring(0, 32);
}

Related

Java Android Appium - how to take screenshot when telephone is connected via USB cable?

Java Android Appium - how to take screenshot when telephone is connected via USB cable ?
The following line returns "Illegal base64 character a" - is there any different solution to take a screenshot ?
File source = driver.getScreenshotAs(OutputType.FILE);
I want to invoke screenshot when test fails in Test ng listeners Class:
#Override public void onTestFailure(ITestResult result) {}
That's because there is an annoying thing Appium does when using it's driver to take a screenshot, but I'm not sure if this applies in your situation.
Can you output the Base64 in the console to check it's specific output? If the output is something like this:
"Z3Rlc2dyZXNncmdyZWFncmVzZ3Jlc2dyZWFncmVzZ3Jlc2dlaW93YWpm\n"
"ZW9ndGVzZ3Jlc2dyZ3JlYWdyZXNncmVzZ3JlYWdyZXNncmVzZ2Vpb3dh\n"
"amZlb2d0ZXNncmVzZ3JncmVhZ3Jlc2dyZXNncmVhZ3Jlc2dyZXNnZWlv\n"
"d2FqZmVvZ3Rlc2dyZXNncmdyZWFncmVzZ3Jlc2dyZWFncmVzZ3Jlc2dl\n"
"aW93YWpmZW9ndGVzZ3Jlc2dyZ3JlYWdyZXNncmVzZ3JlYWdyZXNncmVz\n"
"Z2Vpb3dhamZlb2d0ZXNncmVzZ3JncmVhZ3Jlc2dyZXNncmVhZ3Jlc2dy\n"
Then you should replace the "\n" to a blank "":
String screenshotBase64 = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BASE64);
String replaceBase64 = screenshotBase64.replaceAll("\n","");
doSomethingWith(replaceBase64);

inf file without PID for multiple products under same VID

I'm trying to create a "generic" Windows USB driver (really just an .inf-file) that could be used for several products under the same manufacturers. What I would like to do is to only list the Vendor IDs (VID) for the different manufactures so that I can use the same driver for different models from the same manufacturers, something like this:
[Version]
Signature=$WINDOWS NT$
Class=visaUsbDevice
ClassGUID={A3330EDF-239D-4206-833B-1D58952613D5}
Provider=%Vendor%
DriverVer=05/03/2017,1.0
CatalogFile=test.cat
;===========================================================================
; Default Installer
;===========================================================================
[DefaultInstall]
CopyINF=test.inf
[DestinationDirs]
[SourceDisksNames]
[SourceDisksFiles]
;===========================================================================
; Class Installer
;===========================================================================
[ClassInstall32]
AddReg=AddClass_AddReg
[AddClass_AddReg]
HKR,,,0,%DeviceClassString%
HKR,,Icon,,"-20"
;===========================================================================
[Manufacturer]
%Vendor%=USBList,NTamd64
[USBList]
%USB\VID_12D1.DeviceDesc%=WinUsb_Inst, USB\VID_12D1
%USB\VID_1004.DeviceDesc%=WinUsb_Inst, USB\VID_1004
%USB\VID_18D1.DeviceDesc%=WinUsb_Inst, USB\VID_18D1
%USB\VID_0BB4.DeviceDesc%=WinUsb_Inst, USB\VID_0BB4
%USB\VID_04E8.DeviceDesc%=WinUsb_Inst, USB\VID_04E8
%USB\VID_22B8.DeviceDesc%=WinUsb_Inst, USB\VID_22B8
%USB\VID_054C.DeviceDesc%=WinUsb_Inst, USB\VID_054C
%USB\VID_2A70.DeviceDesc%=WinUsb_Inst, USB\VID_2A70
[USBList.NTamd64]
%USB\VID_12D1.DeviceDesc%=WinUsb_Inst, USB\VID_12D1
%USB\VID_1004.DeviceDesc%=WinUsb_Inst, USB\VID_1004
%USB\VID_18D1.DeviceDesc%=WinUsb_Inst, USB\VID_18D1
%USB\VID_0BB4.DeviceDesc%=WinUsb_Inst, USB\VID_0BB4
%USB\VID_04E8.DeviceDesc%=WinUsb_Inst, USB\VID_04E8
%USB\VID_22B8.DeviceDesc%=WinUsb_Inst, USB\VID_22B8
%USB\VID_054C.DeviceDesc%=WinUsb_Inst, USB\VID_054C
%USB\VID_2A70.DeviceDesc%=WinUsb_Inst, USB\VID_2A70
[PreCopySection]
HKR,,NoSetupUI,,1
[WinUsb_Inst]
Include = winusb.inf
Needs = WINUSB.NT
[WinUsb_Inst.hw]
AddReg=WinUsb_Inst_HW_AddReg
[WinUsb_Inst.Services]
Addservice = WinUsb, 0x00000002, WinUsb_AddService
[WinUsb_AddService]
DisplayName = %WinUsb_Service_DisplayName%
ServiceType = %SERVICE_KERNEL_DRIVER%
StartType = %SERVICE_DEMAND_START%
ErrorControl = %SERVICE_ERROR_NORMAL%
ServiceBinary = %12%\WinUSB.sys
[WinUsb_Inst_HW_AddReg]
HKR,,DeviceInterfaceGUIDs, 0x10000,"{761ED34A-CCFA-416b-94BB-33486DB1F5D5}"
[Strings]
Vendor="TEST"
USB\VID_12D1.DeviceDesc="HUAWEI"
USB\VID_1004.DeviceDesc="LGE"
USB\VID_18D1.DeviceDesc="GOOGLE"
USB\VID_0BB4.DeviceDesc="HTC"
USB\VID_04E8.DeviceDesc="SAMSUNG"
USB\VID_22B8.DeviceDesc="MOTOROLA"
USB\VID_054C.DeviceDesc="SONY"
USB\VID_2A70.DeviceDesc="ONEPLUS"
DeviceClassString="NI-VISA USB Devices"
WinUsb_Service_DisplayName="WinUSB Driver"
SERVICE_BOOT_START = 0x0
SERVICE_SYSTEM_START = 0x1
SERVICE_AUTO_START = 0x2
SERVICE_DEMAND_START = 0x3
SERVICE_DISABLED = 0x4
SERVICE_KERNEL_DRIVER = 0x1
SERVICE_ERROR_IGNORE = 0x0
SERVICE_ERROR_NORMAL = 0x1
SERVICE_ERROR_SEVERE = 0x2
SERVICE_ERROR_CRITICAL = 0x3
But I can't seem to get it to work without having a product ID (PID) connected to the listed VIDs, e.g:
%USB\VID_1004&PID_631C.DeviceDesc%=WinUsb_Inst, USB\VID_1004&PID_631C
When I try to manually select the inf file I created for my devices in Device Manager, it gives me the following error:
The folder you specified doesn't contain a compatible software driver for your device. If the folder contains a driver, make sure it is designed to work with Windows for x64-based systems.
But if I use the .inf file where i have specified some of my devices PIDs, it works. The problem is that I can't list all the different PIDs because the driver needs to be compatible with a random device from the listed manufacturers. Anyone who knows how I can get around this?
That's a very bad idea because those manufacturers might choose to make different types of devices in the future and your driver could make it difficult for people to use those devices if it takes precedence over the official drivers.
Also, it won't work because the "PID" is part of the string that Windows uses to find drivers, as you have seen in your experiments.
You might try looking at the devices in the Device Manager to see if they have a "Compatible Id" you can use for matching instead of the VID/PID numbers.
Another thing you could do is instruct your users how to install your driver manually for a specific connected USB device. To do this, they can open the Device Manager, right-click on the USB device in question, select "Update Driver Software...", select "Browse my computer for driver software", select "Let me pick from a list of device drivers on my computer", and then from there they should be able to find the INF file you supplied.
Alternatively, you can use a utility like Zadig to install WinUSB for those devices.

Appium: "An element could not be located on the page using the given search parameters" error

I am new to Appium and have been trying to automate the Conversion Calculator app for Android. Am getting the error "org.openqa.selenium.NoSuchElementException: An element could not be located on the page using the given search parameters", when trying to find a EditText element. Using Appium ver 1.0.0 and Android 4.3
The following is my code:
List<WebElement> textViews = driver.findElements(By.className("android.widget.TextView"));
for (i=0; i<textViews.size(); i++) {
if(textViews.get(i).getText().toLowerCase().contains("memory")) {
textViews.get(i).click();
}
}
Thread.sleep(5000);
WebElement editText = driver.findElement(By.className("android.widget.EditText"));
editText.sendKeys("123");
Even findElement by ID is not working. Please let me know what I am doing wrong here or if I need to provide more details.
I would use
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); instead of Thread.sleep(5000).
Try to use a newer version of Appium, I's been improved a lot. You can download the latest version of Appium and Appium clients here:http://appium.io/downloads.html
But be careful because in the newer version the findElement throws an Exception if there are more then one result of the search.
I would write this in a comment but I've not enough reputation :/
Possible Cause:
Multiple EditText in the current screen.
Please try with the following:
Solution1:
List<WebElement> editText = driver.findElements(By.className("android.widget.EditText"));
editText.get(0).sendKeys("123");
0 - Index of EditText
Solution2:
Use any other locating strategy like Xpath.
Maybe you could try waiting until the element is visible or enabled using a WebDriverWait object?
Avoid using sleep as much as possible, try using the WAIT command.
Sleep without waiting for the time that has been determined, even if the element is already on the screen.
In the case of the wait command, as soon as the element appears, the action will already be performed, this along the code will reduce the execution time considerably.
The issue for me was the app path I was using. If you are using a config file make sure to declare the application separately from the device.
If not, make sure the "app" capability has the right path. Here is the code in my config file for example:
devices_by_ids = {
"platformName": "Android",
"appium:DEVICE ADB ID": {
"android_version": "13",
"device_name": "google_Pixel_5a",
"DEVICE ADB ID": "DEVICE ADB ID",
"port":"4723",
"autoGrantPermissions": "true",
},
"appium:app": "YOUR APP PATH",
"appium:appWaitActivity": "*"
}
In Appium v2 use
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

Jelly Bean Issue - wifiManager.getConnectionInfo().getSSID() - extra ""

Hi all bug reporting for your information. link
Problem details:
The Code - wifiManager.getConnectionInfo().getSSID()
The above code to returns the current SSID, it is returning the current SSID with extra quotations around it.
For eg. the SSID internet is returned as "internet".
This is only seen on Jelly bean 4.2 using device Nexus 7.
This bug is causing errors in our app as we compare the current SSID with the SSID that we are trying to connect too.
The code wifiManager.getScanResults(); however still returns all SSID's without extra quotation marks.
this is not a bug and behavior is correct as per documentation at http://developer.android.com/reference/android/net/wifi/WifiInfo.html#getSSID()
The so-called bug apparently was in pre 4.2 devices, because they didn't return it with "" enclosure.
Aiden's method looks good to me in the current state of confusion left by Android. However, being theoritically correct would just require
if (ssid.startsWith("\"") && ssid.endsWith("\"")){
ssid = ssid.substring(1, ssid.length()-1);
}
This regular expression is quite neat:
String ssid = wi.getSSID().replaceAll("^\"(.*)\"$", "$1");
Just for the notes
Edit °1 (as per question in the comment):
The issue that OP describes is, that on some devices the SSID returned by getSSID() is enclosed in "" whereas it is not on other devices. E.g. on some devices the SSID is "MY_WIFI" and on others it is MY_WIFI - or spoken in Java code: "\"MY_WIFI\"" and "MY_WIFI".
In order to to unify both results I proposed to remove the " at start and end - only there, because " is a legal character inside the SSID. In the regular expression above
^ means from start
$ means at end
\" means " (escaped)
.* means any number of characters
(...) means a capturing group, that can be referred by $1
So the whole expression means: replace "<something>" by <something> where $1 = <something>.
If there is no " at end/start, the regular expression doesn't match and nothing is replaced.
See Java Pattern class for more details.
For the mean time this is how I am getting around it, although its not great it will fix the issue.
public String removeQuotationsInCurrentSSIDForJellyBean(String ssid){
int deviceVersion= Build.VERSION.SDK_INT;
if (deviceVersion >= 17){
if (ssid.startsWith("\"") && ssid.endsWith("\"")){
ssid = ssid.substring(1, ssid.length()-1);
}
}
return ssid;
}
Two very simple variants:
string = string.replaceAll("^\" | \"$", "");
and
string = string.substring(1, string.length() - 1);
Faced the same problem! Used this technique which is backwards compatible:
if (suppliedSSID.equals(connectionInfo.getSSID()) || ("\"" + suppliedSSID + "\"").equals(connectionInfo.getSSID()) { DO SOMETHING }

Different encoding using "android.util.Base64" and "org.apache.commons.codec.binary.Base64;"

I am programming an authentication service in Android and this one includes a server part written in java.
I do the same operations in both parts executing these two pieces of codes in Android and Server:
ANDROID:
String genChallengeResponse(String challenge, String message) {
String Hmac_ALG = "HmacSHA256";
SecretKey key = new SecretKeySpec(challenge.getBytes(), Hmac_ALG);
Mac m = Mac.getInstance(Hmac_ALG);
m.init(key);
m.update(password.getBytes());
byte[] mac = m.doFinal();
return new String(Base64.encode(mac, Base64.DEFAULT));
}
SERVER:
String genChallengeResponse(String challenge, String message) {
String Hmac_ALG = "HmacSHA256";
SecretKey key = new SecretKeySpec(challenge.getBytes(), Hmac_ALG);
Mac m = Mac.getInstance(Hmac_ALG);
m.init(key);
m.update(password.getBytes());
byte[] mac = m.doFinal();
return new String(Base64.encodeBase64(mac));
}
Starting from the same challenge and message these are the results:
Android: n2EaLpQr0uKgkZKhCQzwuIFeeLjzZKerZcETVNcfla4=
Server: n2EaLpQr0uKgkZKhCQzwuD9eeLjzZKerZcETVNcfla4=
^^
These are different just for TWO CHARACTERS.
The problem is that this strange behaviour does not appear in every pair of String passed to the functions...
I tried to use the UTF-8 in each system, but nothing changes...
Do someone knows what is the problem? If this is a known problem...
(is important to say that the problem is the same using Android 2.2 or also 4.0, then the problem is not the operating system, I think).
Can't comment yet therefore as answer:
I found out a few weeks ago that Android's Base64 uses different settings for the Linefeeds (check here: http://developer.android.com/reference/android/util/Base64.html )
I think in my case it was NO_WRAP missing.Perhaps one of the other options (NO_PADDING or URL-Safe, does the tested password contain + or - ?) could change your results...

Categories

Resources