Goal:
Taking a screenshot during an automated test on a device. Pull the screenshot file using adb once the test is done.
Context:
I'm currently trying to write automated tests to take snapshots of the device screen. Using UiDevice to navigate, I would like to take a screenshot in the middle of a test. UiDevice has a method takeScreenshot that I call when I would like to take a snapshot.
After some investigation, I realised that the class responsible to write the image into file UiAutomatorBridge catches an Exception :
java.io.FileNotFoundException:
/data/local/tmp/screenshots/screen2.png: open failed: EACCES
(Permission denied)
Using adb, I created the file and set all permissions to all users.
adb shell touch /data/local/tmp/screenshots/screen1.png
adb shell chmod 777 /data/local/tmp/screenshots
Once done, I can take a screenshot with :
#Test
public void takeSnapShot() {
String filename = "/data/local/tmp/screenshots/screen1.png";
File file = new File(filename);
assertEquals(true, mDevice.takeScreenshot(file));
}
Problem :
I would like to be able to create a file directly while the test is executing, without the need of using adb.
I tried to create a file directly from Java using createNewFile.
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
But I get an IOException
java.io.IOException: open failed: EACCES (Permission denied)
Has anyone an idea of what is going on ? I'm quite new to Linux, so don't hesitate to suggest something even if it seems obvious to you ;)
Should I post this on superuser instead ?
EDIT
The directory /data has these permissions
drwxrwx--x system system 2016-01-14 14:03 data
I can't list the content of /data, which makes me believe the user "shell" doesn't belong to the group "system". I can't list the content of /data/local neither.
However, the /data/local/tmp is owned by "shell".
drwxrwx--x shell shell 2016-01-14 12:20 . (tmp)
/data/local/tmp gives +x permission to all users.
Finally, the directory "screenshots" belongs to shell with permissions 777.
drwxrwxrwx shell shell 2016-01-14 11:46 screenshots
To my understanding, any user should be able to access /data/local/tmp/screenshots
Instead of saving under /data/local/tmp/, use Environment.getExternalStorageDirectory().
You need a read/write permission to do that. You have to add these two lines into the Manifest of the application ! (I tried to add those lines into the /androidTest/Manifest.xml file, but it has no effects).
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
While it solves the problem of finding a common directory to save/read screenshots, it brings a new one as well.
Having to add these 2 permissions isn't a big deal if you already had them. But if you don't want to ask the user for those permissions, you have to add/remove these lines every time you test/sign your application, which is far from ideal.
EDIT :
In this post, someone proposed to make use of the build differentials (debug, release) to have two different Manifests.
In the end, I have 3 Manifests :
Release Manifest (without external read/write permissions)
Debug Manifest (with external read/write permissions)
AndroidTest Manifest for
tools:overrideLibrary="android.support.test.uiautomator.v18"
Related
I'm attempting to write a simple log file from inside av/services/audioflinger/AudioStreamOut.cpp, for testing a custom ROM.
I need it to work on Nexus 5X (bullhead).
if (logFile1 == NULL)
logFile1 = fopen("/sdcard/log_before.pcm", "ab");
if (logFile1 == NULL)
ALOGE("can't open 1, errno %d", errno);
I'm getting permission denied (ERRNO is 13).
I tried modifying frameworks/base/data/etc/platform.xml by adding the following:
<assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="media" />
<assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="audioserver" />
<assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="audio" />
Still no change.
How can I get this to work? Or is there another place in the filesystem where a system service like audioflinger is supposed to use for writing files?
UPDATE:
I just found a solution that works for emulator - in Android N, write to /data/misc/audioserver.
When I use ADB shell, it shows me that this particular folder has the "audioserver" group, which is why it works.
I found about this folder from this link: https://source.android.com/devices/audio/debugging.html
But this folder seems not accessible on Nexus 5X - can't get to it with shell, even with su root.
I found a way around the permission issue.
First, write the log file to /data/misc/audioserver
Then:
adb shell su root cp /data/misc/audioserver/log_before.pcm sdcard/.
Etc.
And then I can pull the file:
adb pull /sdcard/log_before.pcm .
There is a folder called "D_Permision" SD Card and there is a text file called "permission.txt" in it.
I want to read this text file through command prompt and display its content in the command prompt(Not in a separate file)
When I use
adb pull permission.txt /sdcard/D_Permission
it gives following error
remote object 'permission.txt' does not exist.
but I used
adb push permission.txt /sdcard/D_Permission
(successfully added permission.txt to D_Permission folder)
and the tried to pull.but I get same error.
sdcard/D_permission has both read / write permission
So how to read this text file through command prompt and display its content in the cmd?
You don't need to pull the file.
adb provides shell acces, so you can do a cat:
adb shell cat /sdcard/D_Permission/foo.txt
If the file does not exist though, you'll still get "does not exists" error of course, which is normal.
I directly use the path "/mnt/external_sd/.. Path of File.".
But it was only work with my Device
Maybe you forget these permissions.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I am trying to develop Amazon In-app in android. For this i download the sample code for from this site https://developer.amazon.com/sdk/in-app-purchasing/sample-code/button-clicker.html. This article suggests that we have to put a file amazon.sdktester.json in mnt/sdkcard folder of device. For this i read article from this site https://developer.amazon.com/sdk/fire/connect-adb.html#InstallApp and do the same. But when I tried to push file on sdcard, the eclipse gives me following error:
[2012-11-19 13:39:39 - ddms] transfer error: Permission denied
[2012-11-19 13:39:39] Failed to push selection: Permission denied
Is there any way to change the permissions of root folder of Kindle Fire?
Please try to use chmod command in the ADB shell...
Following are some chmod sample:
Add single permission to a file/directory
Changing permission to a single set. + symbol means adding permission.
For example, do the following to give execute permission for the user
irrespective of anything else:
$ chmod u+x filename
Add multiple permission to a file/directory
Use comma to separate the multiple permission sets as shown below.
$ chmod u+r,g+x filename
Remove permission from a file/directory
Following example removes read and write permission for the user.
$ chmod u-rx filename
Change permission for all roles on a file/directory
Following example assigns execute privilege to user, group and others
(basically anybody can execute this file).
$ chmod a+x filename
Make permission for a file same as another file (using reference)
If you want to change a file permission same as another file, use the
reference option as shown below. In this example, file2′s permission
will be set exactly same as file1′s permission.
$ chmod --reference=file1 file2
Apply the permission to all the files under a directory recursively
Use option -R to change the permission recursively as shown below.
$ chmod -R 755 directory-name/
Change execute permission only on the directories (files are not affected)
On a particular directory if you have multiple sub-directories and
files, the following command will assign execute permission only to
all the sub-directories in the current directory (not the files in the
current directory).
$ chmod u+X *
I am trying to rename the SystemUI.apk in the directory /system/app to something else on my rooted device (Tablet with ICS) just like Root Browser is able to.
It doesn't work the same way as it works in the /sdcard directory. I tried this:
String s = "/system/app";
File from = new File(s, "SystemUI.apk");
File to = new File(s, "_SystemUI.apk");
from.renameTo(to);
(This code works for file in SD-Card)
And I set the permission to write to the external storage:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
However, there is no such permission for the "internal" storage. Do I need to do this via Runtime.getRuntime().exec(some command)?
Thanks for any help.
You need root access, this can not be done with standard java classes.
Run this commands via SU binary
mv /system/app/SystemUI.apk /system/app/_SystemUI.apk
Obviously you can change the cmd as need to do what you need.
I try to change file permission in application. Code is below:
Runtime.getRuntime().exec("chmod 777 /sdcard/test.txt");
This code NOT works in my application, but no error log.
I also checked the shell tools under /system/bin, find chmod is under /system/bin, but some other info shown that chmod > toolbox. I am not clear about this. My application has used android:sharedUserId="android.uid.system".
How to run this code or how to change permission of file? Thanks a lot.
Runtime rt = Runtime.getRuntime();
Process proc;
try {
proc = rt.exec(new String[] { "su", "-c", "chmod 777 " + Constants.filename });
proc.waitFor();
} catch (Exception e){ //DOSTUFFS }
This should do the trick
You've used the path /sdcard/ in your test -- is your SD Card formatted with a filesystem that supports standard Unix permissions? (FAT does not.)
You did not give an explicit path to chmod(1) in your string -- are you certain that chmod(1) is:
available on your device
available with your current PATH environment variable setting?
You can only change the permissions on files you own; are you certain that whatever your application's effective userid is owns the file on the SD card?
Lastly, Android may have additional security restrictions on changing file permissions. I don't know Android well, but perhaps changing file permission bits requires entries in the manifest declaring the operations, perhaps changing file permissions can only be done through provided APIs.