Android System Version - java

On my Moto Maxx & Moto Razr HD (probably all Moto devices), there is an entry in the About Phone settings that states System version. I am writing an app that pulls this info from the phone but I cannot find where Motorola is pulling that info from. All the Build.VERSION, Build.DISPLAY, etc do not contain it. I have even read in the "/proc/version" from the Linux system, which doesn't contain it as well. Thoughts?
UPDATE: With everyone's help it pushed me in the right direction. My solution was:
private String getDeviceBuildVersion() {
//Get Moto Info
String line = "Note sure...";
try {
Process ifc = Runtime.getRuntime().exec("getprop " + "ro.build.version.full");
BufferedReader bis = new BufferedReader(new InputStreamReader(ifc.getInputStream()));
line = bis.readLine();
ifc.destroy();
} catch (java.io.IOException e) {
e.printStackTrace();
}
return line;
}

It's most likely stored as an Android system property.
Assuming you're connected to the phone through adb, run this command:
adb shell getprop
This will list all of the system properties set in the system. Look for that system version string and you'll see which property it's stored as. Then when you know the name of the property it's stored as, you can use System.getProperty() to grab it programmatically.
If it's not there, Motorola is probably hiding the string somewhere in their modified source and unfortunately you won't be able to get to it.

Have a look at android.os.Build.VERSION.
CODENAME : The current development codename, or the string "REL" if this is a release build.
INCREMENTAL : The internal value used by the underlying source control to represent this build.
RELEASE : The user-visible version string.

Related

Recreating Linux traceroute for an Android app

I am extremely new the Android app development and Stack Overflow. I am trying to recreate traceroute in an Android app since Android devices do not come with traceroute by default. I've encountered a couple stack overflow posts talking about solutions to this, but I have still run into challenges.
Traceroute on android - the top post on this thread links an Android Studio project that implements traceroute using ping. If I understand the algorithm correctly, it continually pings the destination IP, incrementing the time-to-live field to obtain information about intermediary routers. I've tried to recreate this behavior, but for certain values of TTL, the ping stalls and doesn't retrieve any router information. I'm not really sure why this happens. Here's a quick demo function I spun up... at some point in the loop the pings stall.
public static void smallTracerouteDemoShowingThatTheProgramStallsAtCertainTTLs() {
try {
String host = "google.com";
int maxTTL = 20;
for (int i = 1; i < maxTTL; i++) {
// Create a process that executes the ping command
Process p = Runtime.getRuntime().exec("ping -c 1 -t " + i + " " + host);
// Get a buffered reader with the information returned by the ping
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
// Convert the BufferedReader to a string
String dataReturnedByPing = "";
for (String line; (line = br.readLine()) != null; dataReturnedByPing += "\n"+line);
// Print out information about each TTL
System.out.println("TTL = " + i + " out of " + maxTTL);
System.out.println(dataReturnedByPing);
System.out.println("========================================");
}
} catch (Exception e) {
e.printStackTrace();
}
}
how to run traceroute command through your application? - The solution on this thread suggests using BusyBox. I've not used BusyBox as yet, but it seems like I would have to embed BusyBox into my app to get things to work. After doing some research it looks like BusyBox provides numerous Linux commands through one executable. I'm a bit hesitant to explore this option because I really only need the traceroute command. In addition, I know that Android targets a few different CPU architectures, and I'm not sure if one executable will support them all.
I've also run into a github repository that takes another approach to running traceroute:
https://github.com/wangjing53406/traceroute-for-android - In this repository the author embeds the traceroute source code into the project and uses the NDK to build the source code along with the rest of his app. I really like this approach because it feels the most "correct." It uses a built traceroute instead of a Java-based implementation, so you can't find yourself in a situation where the Java implementation gives you one thing and the actual traceroute gives you another. When I open this project to experiment with it, my build fails. The top line says:
org.gradle.initialization.ReportedException: org.gradle.internal.exceptions.LocationAwareException: A problem occurred configuring root project 'traceroute-for-android-master'.
Any help on why this happens or ways to troubleshoot it would be fantastic.
For reference, the minimum SDK I am targeting is API 21 and I am running on Android Studio 3.3.0.
So, at this point I'm stumped. If you were trying to make an app that would let you execute traceroute commands, how would you do it? I really like the NDK approach because it guarantees you're getting true traceroute behavior. If you have any guides to getting that set up for my Android version/SDK, I would appreciate if you would post them. If you'd take another approach I'd to hear about it as well.
Thank you in advance.

how windows will do auto java update checks?

First of all sorry for my poor English.
I want to know how the windows will do auto java update check behind the User Interface ?
The UI will just react based on our input which is in the link , http://java.com/en/download/help/java_update.xml#howto .
But , how windows checks the updates programmatically.
I wrote a small program in java ,
public class JavaLatestVersion {
public static void main(String[] args){
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new URL(
"http://java.com/applet/JreCurrentVersion2.txt").openStream())) ;
String fullVersion = br.readLine();
System.out.println("fullVersion : "+fullVersion);
String version = fullVersion.split("_")[0];
String revision = fullVersion.split("_")[1];
System.out.println("Version " + version + " revision " + revision);
} catch (IOException e) {
e.printStackTrace();
}
}
}
My questions :
1. Is the above program is the reliable way to get the latest java version ? Or any other standard way to get the latest java version (Not in the computer) ?
2. Is windows use the same way to determine the latest java version ?
3. Is windows use this link for updates http://java.com/applet/JreCurrentVersion2.txt ?
Any one know the secret code behind how windows will check for latest java updates?
Thanks in advance.
Checking for Java updates is done by Java Auto Updater. It is ordinary application (which is ran when Windows starts up).
Yes, it is reliable way to get the latest version of Java (as updater can not only update Java, it can also update itself). But pay attention to firewall/group policy settings which can prohibit updater to access the Web.
Windows doesn't update Java.
Only debugging Java Auto Updater can help to determine what URL it uses.
Unfortunately, Java Auto Updater has only graphical interface and hides all work behind the scenes. So finding a "secret code" is not easy to do. All the more in many cases reverse-engineering non-open source software is illegal from a license point of view.
URL that you provided above doesn't works. Because it says 8.0_51. But latest version of Java on Downloads page is 8u65 / 8u66.
Seems that latest available version (as plain text) can be determined only by fetching http://www.oracle.com/technetwork/java/javase/downloads/index.html web page, then parsing it, handling cases when page is moved to another location, etc.

Lotus Notes Java app can’t find notes.ini

Both the systems described are Windows XP with Lotus Notes 8.5.
I have a Java app (sample code below) that uses notes.jar to interact with Lotus Notes. The app works fine on a system that has notes.ini in the Lotus install dir of c:\Program Files\Lotus\Notes and the user ID file is in c:\Program Files\Lotus\Notes\Data. The user has to type a password to login to Lotus. This system has HKLM\Software\Lotus\Notes\MultiUser set to 0 (single user system). On this machine, the below code displays good values on the four println’s.
On a problem system, this app prints the four headings but blanks for the four values (the user name, key filename, mailfile, and mailserver are all blank). This problem system has notes.ini and the user ID file in D:\Data\johnsmith\NotesData. Lotus is installed in C:\Program Files\Lotus\Notes. This problem system also has HKLM\Software\Lotus\Notes\MultiUser set to 1 (implying it is multiuser instead of single user). Finally, under Lotus’s File -> Security -> User Security dialog the "Log in to Notes using your operating system login" box is checked (so the user doesn’t type in a password to login to Lotus).
So, it appears that on the problem system, the notes.ini file can’t be found (since notes.ini is where the four output values are supposed to be read from). I’ve looked through the Notes.jar API and can’t see any way to specify the location of notes.ini. The dir where notes.ini resides is in the Windows PATH, but that doesn’t help.
Any help would be appreciated.
import java.io.*;
import lotus.domino.*;
public static void main(String[] args) throws IOException {
try {
NotesThread.sinitThread();
Session session = NotesFactory.createSession();
System.out.println("Common user name: " + session.getCommonUserName());
System.out.println("KeyFilename: " + session.getEnvironmentString("KeyFilename", true));
System.out.println("MailFile: " + session.getEnvironmentString("MailFile", true));
System.out.println("MailServer: " + session.getEnvironmentString("MailServer", true));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
NotesThread.stermThread();
}
}
As mentioned in the original question, if HKEY_LOCAL_MACHINE\Software\Lotus\Notes\MultiUser has a value of 1, then you have a multi-user installation (even if you are the only user of Lotus).
Here is a solution that worked. Find the location of Notes.ini, probably somewhere like C:\Documents and Settings\(username)\Lotus. Edit or create the string value below and set it to your Notes.ini directory. HKEY_CURRENT_USER\Software\Lotus\Notes\(optional-version)\NotesIniPath.
In a multi-user environment, Lotus Notes gets the ini filename from the NotesIniPath registry value.
Add a new command-line parameter, "=c:\data\johnsmith\NotesData\notes.ini" . To make this happen, you need to use NotesFactory.CreateSession(String host, String args[], String user, String passwd); method, after setting up a new String array containing that parameter and whatever other arguments were passed, since itis basically supposed to be the String args[] as passed to static Main. (The =fullpath\notes.ini parameter just needs to be in the array, it doesn't need to be in any specific location.)
This permits the session to be initialized with the absolute path to the notes.ini file used, and appears to be supported since (though I could be wrong) Notes 5.0.5.
Notably, the Directory= line is going to be taken from that notes.ini and used for all error reporting and logging, as the user's private data directory.
There is a number of things you can try:
Notes actually comes with its own JVM and I found using this JVM makes Java applications run more reliably with Notes classes since any eventually needed support library would be properly configured.
What happens if notes is already running before you start your program. There are 2 variations here: Checkbox "Don't prompt for a password from other Notes-based programs" is checked or unchecked.
Make sure to switch to the directory where the Notes.ini is at home before you run the app. (And verify that the user can't see any other notes.ini variables)

How to get a unique computer identifier in Java (like disk ID or motherboard ID)?

I'd like to get an id unique to a computer with Java, on Windows, MacOS and, if possible, Linux. It could be a disk UUID, motherboard S/N...
Runtime.getRuntime().exec can be used (it is not an applet).
Ideas?
The problem with MAC address is that there can be many network adapters connected to the computer. Most of the newest ones have two by default (wi-fi + cable). In such situation one would have to know which adapter's MAC address should be used. I tested MAC solution on my system, but I have 4 adapters (cable, WiFi, TAP adapter for Virtual Box and one for Bluetooth) and I was not able to decide which MAC I should take... If one would decide to use adapter which is currently in use (has addresses assigned) then new problem appears since someone can take his/her laptop and switch from cable adapter to wi-fi. With such condition MAC stored when laptop was connected through cable will now be invalid.
For example those are adapters I found in my system:
lo MS TCP Loopback interface
eth0 Intel(R) Centrino(R) Advanced-N 6205
eth1 Intel(R) 82579LM Gigabit Network Connection
eth2 VirtualBox Host-Only Ethernet Adapter
eth3 Sterownik serwera dostepu do sieci LAN Bluetooth
Code I've used to list them:
Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
while (nis.hasMoreElements()) {
NetworkInterface ni = nis.nextElement();
System.out.println(ni.getName() + " " + ni.getDisplayName());
}
From the options listen on this page, the most acceptable for me, and the one I've used in my solution is the one by #Ozhan Duz, the other one, similar to #finnw answer where he used JACOB, and worth mentioning is com4j - sample which makes use of WMI is available here:
ISWbemLocator wbemLocator = ClassFactory.createSWbemLocator();
ISWbemServices wbemServices = wbemLocator.connectServer("localhost","Root\\CIMv2","","","","",0,null);
ISWbemObjectSet result = wbemServices.execQuery("Select * from Win32_SystemEnclosure","WQL",16,null);
for(Com4jObject obj : result) {
ISWbemObject wo = obj.queryInterface(ISWbemObject.class);
System.out.println(wo.getObjectText_(0));
}
This will print some computer information together with computer Serial Number. Please note that all classes required by this example has to be generated by maven-com4j-plugin. Example configuration for maven-com4j-plugin:
<plugin>
<groupId>org.jvnet.com4j</groupId>
<artifactId>maven-com4j-plugin</artifactId>
<version>1.0</version>
<configuration>
<libId>565783C6-CB41-11D1-8B02-00600806D9B6</libId>
<package>win.wmi</package>
<outputDirectory>${project.build.directory}/generated-sources/com4j</outputDirectory>
</configuration>
<executions>
<execution>
<id>generate-wmi-bridge</id>
<goals>
<goal>gen</goal>
</goals>
</execution>
</executions>
</plugin>
Above's configuration will tell plugin to generate classes in target/generated-sources/com4j directory in the project folder.
For those who would like to see ready-to-use solution, I'm including links to the three classes I wrote to get machine SN on Windows, Linux and Mac OS:
Java code to get computer SN on Windows
Java code to get computer SN on Linux
Java code to get computer SN on Mac OS
The OSHI project provides platform-independent hardware utilities.
Maven dependency:
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>LATEST</version>
</dependency>
For instance, you could use something like the following code to identify a machine uniquely:
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.ComputerSystem;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;
class ComputerIdentifier
{
static String generateLicenseKey()
{
SystemInfo systemInfo = new SystemInfo();
OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();
ComputerSystem computerSystem = hardwareAbstractionLayer.getComputerSystem();
String vendor = operatingSystem.getManufacturer();
String processorSerialNumber = computerSystem.getSerialNumber();
String processorIdentifier = centralProcessor.getIdentifier();
int processors = centralProcessor.getLogicalProcessorCount();
String delimiter = "#";
return vendor +
delimiter +
processorSerialNumber +
delimiter +
processorIdentifier +
delimiter +
processors;
}
public static void main(String[] arguments)
{
String identifier = generateLicenseKey();
System.out.println(identifier);
}
}
Output for my machine:
Microsoft#57YRD12#Intel64 Family 6 Model 60 Stepping 3#8
Your output will be different since at least the processor serial number will differ.
It is common to use the MAC address is associated with the network card.
The address is available in Java 6 through through the following API:
Java 6 Docs for Hardware Address
I haven't used it in Java, but for other network identification applications it has been helpful.
What do you want to do with this unique ID? Maybe you can do what you want without this ID.
The MAC address maybe is one option but this is not an trusted unique ID because the user can change the MAC address of a computer.
To get the motherboard or processor ID check on this link.
On Windows only, you can get the motherboard ID using WMI, through a COM bridge such as JACOB.
Example:
import java.util.Enumeration;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;
public class Test {
public static void main(String[] args) {
ComThread.InitMTA();
try {
ActiveXComponent wmi = new ActiveXComponent("winmgmts:\\\\.");
Variant instances = wmi.invoke("InstancesOf", "Win32_BaseBoard");
Enumeration<Variant> en = new EnumVariant(instances.getDispatch());
while (en.hasMoreElements())
{
ActiveXComponent bb = new ActiveXComponent(en.nextElement().getDispatch());
System.out.println(bb.getPropertyAsString("SerialNumber"));
break;
}
} finally {
ComThread.Release();
}
}
}
And if you choose to use the MAC address to identify the machine, you can use WMI to determine whether an interface is connected via USB (if you want to exclude USB adapters.)
It's also possible to get a hard drive ID via WMI but this is unreliable.
Not Knowing all of your requirements. For example, are you trying to uniquely identify a computer from all of the computers in the world, or are you just trying to uniquely identify a computer from a set of users of your application. Also, can you create files on the system?
If you are able to create a file. You could create a file and use the creation time of the file as your unique id. If you create it in user space then it would uniquely identify a user of your application on a particular machine. If you created it somewhere global then it could uniquely identify the machine.
Again, as most things, How fast is fast enough.. or in this case, how unique is unique enough.
Be careful when using the MAC address as an identifier. I've experienced several gotchas:
On OS X, ethernet ports that are not active/up do not show up in the NetworkInterface.getNetworkInterfaces() Enumeration.
It's insanely easy to change a MAC address on cards if you've got appropriate OS privileges.
Java has a habit of not correctly identifying "virtual" interfaces. Even using the NetworkInterface.isVirtual() won't always tell you the truth.
Even with the above issues, I still think it's the best pure Java approach to hardware locking a license.
I think you should look at this link ... you can make a mixed key using several
identifiers such as mac+os+hostname+cpu id+motherboard serial number.
The usage of MAC id is most easier way if the task is about logging the unique id a system.
the change of mac id is though possible, even the change of other ids of a system are also possible is that respective device is replaced.
so, unless what for a unique id is required is not known, we may not be able to find an appropriate solution.
However, the below link is helpful extracting mac addresses.
http://www.stratos.me/2008/07/find-mac-address-using-java/
For identifying a windows machine uniquely.
Make sure when you use wmic to have a strategy of alternative methods. Since "wmic bios get serialnumber" might not work on all machines, you might need to have additional methods:
# Get serial number from bios
wmic bios get serialnumber
# If previous fails, get UUID
wmic csproduct get UUID
# If previous fails, get diskdrive serialnumber
wmic DISKDRIVE get SerialNumber
Resources:
The Best Way To Uniquely Identify A Windows Machine
http://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine/
In the java programs I have written for release I used the motherboard serial number (which is what I beleive windows use); however, this only works on windows as my function creates a temporary VB script which uses the WMI to retrieve the value.
public static String getMotherboardSerial() {
String result = "";
try {
File file = File.createTempFile("GetMBSerial",".vbs");
file.deleteOnExit();
FileWriter fw = new FileWriter(file);
String vbs =
"Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
+ "Set colItems = objWMIService.ExecQuery _ \n"
+ " (\"Select * from Win32_ComputerSystemProduct\") \n"
+ "For Each objItem in colItems \n"
+ " Wscript.Echo objItem.IdentifyingNumber \n"
+ "Next \n";
fw.write(vbs);
fw.close();
Process gWMI = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input = new BufferedReader(new InputStreamReader(gWMI.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result += line;
System.out.println(line);
}
input.close();
}
catch(Exception e){
e.printStackTrace();
}
result = result.trim();
return result;
}

Data in J2ME RecordStore does not persist across sessions

I'm building a mobile app with J2ME, and I've found that the data I write into a RecordStore can be accessed while the program is still running but it is lost after quitting and restarting it. No exception is thrown, the data is simply lost.
UPDATE: Thanks everyone for your suggestions. I'm using NetBeans on Windows 7. I'm not sure if it is using the WTK version I have previously installed or another one it has installed somewhere else. I've checked my WTK folder for the files Pavel wrote about, but couldn't find them. Now I'm testing the features requiring persistence on my phone and everything else in the emulator, but it would of course be much better to be able to test everything in the emulator.
private RecordStore recordStore = null;
public MyMIDlet() {
readStuff(); // output: nothing found in recordStore :(
saveStuff();
readStuff(); // output: stuff
}
private void readStuff() {
try {
recordStore = RecordStore.openRecordStore(REC_STORE, true);
int n = recordStore.getNumRecords();
String stuff;
if (n == 0) {
stuff = "nothing found in recordStore :(";
}
else {
stuff = new String(recordStore.getRecord(1));
}
System.out.println(stuff);
}
catch (Exception e) {
System.out.println("Exception occured in readStuff: " + e.getMessage());
}
finally {
if (recordStore != null) {
try {
recordStore.closeRecordStore();
}
catch (Exception e) {
// ignore
}
}
}
}
private void saveStuff() {
try {
recordStore = RecordStore.openRecordStore(REC_STORE, true);
int n = recordStore.getNumRecords();
byte[] stuff = "stuff".getBytes();
recordStore.addRecord(stuff, 0, stuff.length);
} catch (Exception e) {
System.out.println("Exception occured in saveStuff: " + e.getMessage());
} finally {
if (recordStore != null) {
try {
recordStore.closeRecordStore();
} catch (Exception e) {
// ignore
}
}
}
}
If you use Sun WTK, it creates a file named "in.use" in its "appdb" folder:
C:\WTK25\appdb\DefaultColorPhone\in.use
If you close your emulator in unusual way (kill a process, for example), it would not delete it, and next time you run emulator, it would create temporary folder for storing data:
C:\WTK25\appdb\temp.DefaultColorPhone1
when starting this way, it should print in console: "Running with storage root temp.DefaultColorPhone1".
I fix it, including into my ".bat" file a line for deleting "in.use" file each time, emulator runs. But you should be careful when running several emulators at once.
I experienced the same problem myself, I did however discover that NetBeans, or whatever, deletes the deployed program files after execution. These files are located in the C:\Documents and Settings\MyUser\javame-sdk\3.0\work\0\appdb folder, might be different on Vista/Win7 and I guess the number in the path refers to the emulator you are currently using. Anyways, in this folder look for something that is named like your RecordStore. E.g. "00000002_PSC_onfig.db", which is my suite configuration recordstore named PSConfig. By copying this to e.g. "Copy of 00000002_PSC_onfig.db" it will not be deleted. After NetBeans have cleaned up, just copy it back to its original name.
The next time you hit run in NetBeans your recordstore will be there. It's pain, but at least it gives you the possibility to use the emulator to debug your RMS handling.
This question has been around for a while but I stumbled upon it whilst looking for an answer to the same problem with the emulator but in my case it was when using the Java ME 3 SDK. It is possible that the solution I found might also fix this problem.
Using:
emulator -Xdescriptor:/path/to/app.jad
will according to the docs: "Install a MIDlet, run it, and uninstall it after it finishes."
To persist an installation (and it's data) you should use:
emulator -Xjam:install=<JAD-file-URL>
The JAD file URL can either be a web address or 'file:///path/to/app.jad' if you want to install from your local file system. This installation command will display an application storage number which you can then use to launch the emulator and run the previously installed app by calling:
emulator -Xjam:run=<application-storage-number>
See the docs for further command line options.
I could finally get it to work on a real handset. It seems that, as Martin Clayton suggested, the emulator reset erased the data. I'm still looking for a way to enable persistence in the emulator though.
If you are using windows Vista there can and almost are permission issues. I am not sure how to resolve this but you might want to check that the user that is running the emulator has access to write to the emulator store.
In appdb/$phone/*.db
to fix the storage problem you need to check the option "Storage size" in the netbeans platform manager.
Go in project properties;
go in platform;
manage emulators;
select the sun java wireless toolkit;
go in Tools and Extensions;
open preferences;
storage;
storage size option... set a size.
this works for me
I experienced the same issue on Ubuntu Linux and working with WTK 2.5.2 and Netbeans 8.0.2. I later figured it was caused by shutting down my laptop without closing the emulator. It also happens if you run a second emulator without shutting down the first.
My solution is based on the Best Answer here, just shut down all emulators and delete the file located at
~/j2mewtk/2.5.2/appdb/DefaultColorPhone

Categories