How to enumerate connected USB storage devices Ubuntu Java - java

I have an application, mostly in Java' that controls an airborne infrared camera via a webpage GUI (served by the Ubuntu machine) which starts running automatically when the computer is powered up and towards the end of the boot. The application runs as a user, not root, even though the user is not logged in.
After a great many images are collected the data need to be archived by using rsync to a folder on the operator's USB drive. I need to have the USB drive mounted and know its name tag. The computer is headless and the operator, who is on the aircraft, cannot be expected to know Linux in any case.
On an Ubuntu I see that logged in and running the xfce4 GUI, and only then, the drives are listed in /media/user-name/drive-tag (I note that /media/username is owned by root but the folder named for the drive is owned by the user.) and are shown in /etc/mtab :
/dev/sdd1 /media/programmer/DATA-02-2TB vfat rw,nosuid,nodev,uid=1001,gid=1001,shortname=mixed,dmask=0077,utf8=1,showexec,flush,uhelper=udisks2 0 0
How can I, through Java or through a combination of Java and bash, detect and mount a USB storage device?
If that's not possible do I need to ask the user, through the GUI, to enter the device tag or name, e.g., 'DATA-02-2TB' and then create the mount point and mount the USB drive via a script using the information above?

First install usbmount, a Ubuntu tool.
sudo apt-get update
sudo apt-get install usbmount
Then edit the /etc/usbmount/usbmount.conf file:
sudo sed -i 's/MOUNTOPTIONS="/MOUNTOPTIONS="user,umask=000,/' /etc/usbmount/usbmount.conf
These steps are described at Serverfault. Note that only a subset of drive formats is supported including the ubiquitous VFAT.
With this in place USB external drives and thumb drives will mount in /media as /media/usb0 through /media/usb7 and will be listed in /etc/mtab.
/dev/sdc1 /media/usb0 vfat rw,noexec,nosuid,nodev,sync,noatime,nodiratime,umask=000 0 0
I've tested this on my 14.04 machine. Now if I could only get the drive label.
Edit: The sync option does not work well with flash drives. Read the /etc/usbmount/usbmount.conf file for details and remove "sync" from the appropriate line in that file. A full backup made with sync option ran for over an hour before I cancelled it but took only about 5 minutes with sync removed. Note the comment about using pumount to unmount the non-synched drive.
public static ArrayList<String> usbDriveList() throws FileNotFoundException {
final String MTB_ADDRESS = "/etc/mtab";
final String TARGET = "^/media/usb[0-7]$"; // REGEX
final File file = new File(MTB_ADDRESS);
final ArrayList<String> driveList = new ArrayList<String>();
try (Scanner in = new Scanner(file)) {
while (in.hasNext()) {
final String[] splitLine = in.nextLine().split(" ");
if (splitLine[1].matches(TARGET)) {
driveList.add(splitLine[1]); // got it!
}
}
} catch (final FileNotFoundException e) {
throw new FileNotFoundException();
}
return driveList;
}

Related

Changing permissions to read data/anr files programmatically

I want to read the ANR files in the /data/anr/ directory on my device. I have managed to push my apk file to the /system/priv-app/ directory, so I can list the anr files generated by that apk in my program, but I cannot read each file (there are currently 2).
Their current permissions are set to "-rw-------" and when I execute
chmod 644 /data/anr/anr-name using adb shell, the permission changed successfully to "rw-r--r--" and I can read them through my program. However, because it is unpredictable when they generate, I want to change the permission to 644 within my Android Studio java program.
I have tried:
POSIX permissions
Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rw-r--r--"));
This caused my program to hang at that line.
JNA chmod library using the CLibrary interface
private static CLibrary libc = (CLibrary) Native.loadLibrary("c", CLibrary.class);
libc.chmod("/data/anr/anr-name", 0644);
This caused my program to hang as well.
Runtime.getRuntime().exec()
String[] str = new String[3];
str[0] = "chmod";
str[1] = "644";
str[2] = "/data/anr/anr-name";
Process pro = Runtime.getRuntime().exec(str);
pro.waitFor();
pro.waitFor() returns 1 and pro.getErrorStream() returns "Operation not permitted."
java.io.File.setReadable(boolean readable)
file.setReadable()
file.isReadable() returns false and the file permission has not been changed.
For the record, I have a rooted device. My min AND Target SDK Version are API 26.
I also cannot execute "su" in my program because when I tried, it gave me a "Permission denied" error.
I am completely at loss as to what to do. I just want to read the ANR files from my program.

How to open TestComplete from java code

I would like to open TestComplete from java, but I can't do that, because lack of privilege. When I run my code
public static void StartTC() {
try{
Process p = Runtime.getRuntime().exec(new String[] {"C:\\Program Files (x86)\\SmartBear\\TestComplete 11\\Bin\\TestComplete.exe"});
}
catch (IOException e) {
e.printStackTrace();
}
}
the program exits with CreateProcess error=740, and tells me that I need higher privilege for this action.
I know that I could make a .lnk with admin priv. at open properties of the exe, but there could be a right way to do this.
I think you can use File class for setting permissions.
File file = new File("File.c");
//but file permission are OS specific.
file.setExecutable(true);
In linux it will work.
If you are using windows then you can run "icacls" command to give permission to the file.
C:\>icacls "D:\test" /grant John:(OI)(CI)F /T
This command can be used to to give permission in windows.
According do MS documentation:
F = Full Control
CI = Container Inherit - This flag indicates that subordinate containers will inherit this ACE.
OI = Object Inherit - This flag indicates that subordinate files will inherit the ACE.
/T = Apply recursively to existing files and sub-folders. (OI and CI only apply to new files and sub-folders). Credit: comment by #AlexSpence.
You can run above command using Runtime.getRuntime().exec("icacls something here");
I hope I helped you.
You need to disable the Tools | Options... | Engines | General | Enable support for testing Windows Store applications option in TestComplete.
Information on how this can affect working with TestComplete from an external application like in your case can be found in the Requirements for Testing Windows Store Applications help topic.

Android export SQLite Database to Computer / Mac

I have a SQLite Database on my Android Device (My own App). Now i want to see the SQLite Database on my Computer.
Is there any solution ( easy way ) to get the Database without root rights and without a SD-Card on my Computer?
I tried to google it but i can't find any solution for this problem....
Edit: I'm using not the Emulator ( need the Camera on my Device).
if phone is not rooted you cant access directly your DB, but you can copy it to download folder, then, copy to PC
public static void copyAppDbToDownloadFolder(Activity ctx) throws IOException {
File backupDB = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"databse_name.db"); // for example "my_data_backup.db"
File currentDB = getApplicationContext().getDatabasePath("databasename.db");
if (currentDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
This method worked for my unrooted device.
# check if your device connected
adb devices
adb shell
run-as your.package.name
chmod 777 databases/your.database.name
exit
cp /data/data/your.package.name/your.database.name /mnt/sdcard/
exit
adb pull /mnt/sdcard/your.database.name
If you are saving Sqlite DB in default location , you can find the same in path like following
/data/data/com.dev.myapplication/databases/mydb.db
You can find the same using Android Device Monitor, through which you can navigate to both internal and external memory.
Once you find the database file, extract the same and save in desktop after connecting through USB cable. You can use option "Pull a file from device"
Once you have extracted file to desktop, use any tools similar to Mozilla Firefox SQLite viewer to view database.

How can I check if my application can create a symbolic link?

From my Java application I want to create a symbolic link. However my application can run in different circumstances, not all of those permit the creation of symbolic links. I have the following situations:
Linux - can always make a symlink
Windows - can make a symlink if you are running the application as an administrator.
To create the symlink I use Files.createSymbolicLink(). This throws an IOException under Windows when it doesn't have permission. To be precise the exception is:
java.nio.file.FileSystemException: test\link: A required privilege is not held by the client.
I want to be able to tell if I have this permission from the application (Java 7 or newer) before trying to make the symlink. How can I do this?
This code bellow will work only for Windows and comes with Java.
public static boolean AdminAuth() {
String groups[] = (new com.sun.security.auth.module.NTSystem()).getGroupIDs();
for (String group : groups) {
if (group.equals("S-1-5-32-544"))
return true;
}
return false;
}
The SID S-1-5-32-544 is the id of the Administrator group in the Windows operating system.
You can also take a look at this documentation regarding Application Manifest for Windows.

exec not working with java 1.7.21, but in netbeans works fine

I made a little program and it worked fine, but now. First, it mux the xml chapter file in the mkv file, so we get a muxed mkv file. Some day ago I updated java to 1.7.21 and I think this is the problem why it is not working now. It's a little strange, but when I run in netbeans everything is fine, but when I build and I run the .jar file, it is not working. It create the xml file, but not mux in the mkv file (and because not muxed not delete the xml file). Here is the code: (filename=xml file path; mkv=mkv file path)
public void muxing() {
try {
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("c:\\Program Files\\MKVtoolnix\\mkvpropedit.exe --chapters \""+filename+"\" \""+mkv+"\"");
if (p.waitFor()==0) {
File xmlfile=new File(filename);
xmlfile.delete();
}
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
The program worked with java 1.6 and I think with 1.7.17 too. Win7 32bit. Sorry for my bad English.
Oracle has made breaking changes to Runtime.exec() in Java 7 update 21 (and 6 update 45).
If the program name contains spaces, you need to specify command and arguments in an array:
Process p = Runtime.getRuntime().exec(new String[] {
"C:\\Program Files\\MKVtoolnix\\mkvpropedit.exe",
"--chapters", "\""+filename+"\"", "\""+mkv+"\""});
Another option is to use java.lang.ProcessBuilder:
Process p = new ProcessBuilder("C:\\Program Files\\MKVtoolnix\\mkvpropedit.exe",
"--chapters", "\""+filename+"\"", "\""+mkv+"\"").start();
As stated by Oracle:
Applications that need to launch programs with spaces in the program name should consider using the variants of Runtime.exec that allow the command and arguments to be specified in an array.
Alternatively, the preferred way to create operating systems processes since JDK 5.0 is using java.lang.ProcessBuilder. The ProcessBuilder class has a much more complete API for setting the environment, working directory and redirecting streams for the process.

Categories

Resources