How to save screenshot to android device by appium+selenium - android

Does anybody know how to save screenshot taken from real android device by appium+selenium to device local storage?
Here I have method which can take screenshot from device and save it to PC storage.
But how to set path to save them on real device folder (e.g. deviceName\tablet\GUI\screenshots\screenshot.jpg ...or other way),
taking into account that code should run on PC.
p.s. My app is hybrid so I make switch context to "NATIVE_APP" and then back to WEBVIEW.
public static void getScreenshot(String screenName) throws IOException {
String contextName = AppiumConfigurationTest.driver.getContext();
AppiumConfigurationTest.driver.context("NATIVE_APP");
String Screenshotpath = "C:\\!automation\\build\\reports\\gui_screen_capture\\";
File screenShot = AppiumConfigurationTest.driver.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenShot, new File(Screenshotpath + screenName+"_ " + "." + "jpg"));
AppiumConfigurationTest.driver.context(contextName);
}

You can execute adb command from your code, in which case this shall help you :
adb shell screencap -p /sdcard/screen.png
Note : Saving the screenshots on laptop with different named tests/build is better than saving them on devices.

File scrFile = ((TakesScreenshot) appiumDriver).getScreenshotAs(OutputType.FILE);
BufferedImage originalImage=null;
try {
originalImage= ImageIO.read(((TakesScreenshot) appiumDriver).getScreenshotAs(OutputType.FILE));
}
catch(Exception e) {
System.out.println("\n\n\n\nbuffered image" + originalImage +"\n\n\n\n\n\n");
Thread.sleep(5000);
e.printStackTrace();
}
System.out.println("buffered image" + originalImage);
BufferedImage.TYPE_INT_ARGB : originalImage.getType();
BufferedImage resizedImage = CommonUtilities.resizeImage(originalImage, IMG_HEIGHT, IMG_WIDTH);
ImageIO.write(resizedImage, "jpg", new File(path + "/"+ testCaseId + "/img/" + index + ".jpg"));

Related

How to stream video on my video view from samba server ? How can I do it

I am stuck at this since very long and not getting any proper solution for it.
I am using jcifs and samba to access shared folder from my windows Pc. Now I want to play the video file which I am getting from the shared folder. I have searched with every keyword but not getting anything what to do and how to do.
Till now I have seen these links:
Using NanoHTTPD in Android
how to stream video from internet via nanoHTTPd to VideoView
Android SDK : Samba server streaming video to Android using VideoView?
None of these were found promising.
Then I searched more for it
and I found this :
https://code.google.com/archive/p/android-smb-streaming/
This is my code to get the files from my windows shared folder
String ip = "192.108.0.00";
String username = "test";
String sharedFolder = "andsyyy/";
String path = "smb://" + ip + "/" + sharedFolder;
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", username, null);
SmbFile sfile = new SmbFile(path, auth);
String[] files = sfile.list();
PATH = sfile.getPath();// returns path of folder
for (String fileName : files) {
Log.e("log_tag", "Fisier: " + fileName);
abc = fileName;
}
} catch (Exception ex) {
// TODO: handle exception
z = ex.getMessage();
}
return z;
}

Why the txt file did not create in Android?

I am developing in Android , I found a sample code and it read and write the data to the txt file like the following code:
The following function is for writing data to text file:
private static final String MESH_DATA_FILE_NAME = "TEST.txt";
public void save(Activity activity) {
try {
int i;
Context context = activity;
FileOutputStream fos = activity.openFileOutput(MESH_DATA_FILE_NAME, context.MODE_PRIVATE);
String str;
for (i = 0; i < 10; i++) {
str += "##" + i;
}
fos.write(str.getBytes());
fos.write('\n');
fos.close();
} catch (Exception e) {
Log.e(TAG, "saveMeshInfo exception: " + e);
}
}
The following code for reading data from text file:
public void read(Activity activity) {
try {
FileInputStream fin = activity.openFileInput(MESH_DATA_FILE_NAME);
BufferedReader br = new BufferedReader(new InputStreamReader(fin));
Log.i(TAG, "From file [" + MESH_DATA_FILE_NAME + "]...");
// Read the information
String text = br.readLine();
String[] strs = text.split("##", 4 + FloodMesh.IV_LEN + FloodMesh.KEY_LEN);
fin.close();
} catch (Exception e) {
}
}
It can see the data from the log when it call read function , so the TEST.txt should be exists.
But I didn't found the TEST.txt via file manager app on my android phone.
Why I didn't found the TEST.txt file on my android phone ?
If the TEST.txt not exists , why the read function can read the data ?
How to find the TEST.txt file ?
You've created file in you app directory (/data/data/your.package) and you don't have access there via file manager. The file exists that is why you can read it via method but you won't see it. Test your code on emulator - than you will be able to see the file
If you want to test it better and you don't want to use emulator you can save file on sdcard, you have access there via file manager and you will be able to see it
your file will be in /data/data/<your package name>/files/ - either you have root and an explorer to see this or you use the run-as command on adb to explore the file
With the right permission you can also write the file to sd-card - then accessing it is easier - depends on your needs
You didn't found the TEST.txt because it's in private mode, you need to write MODE_APPEND,You should check http://developer.android.com/reference/android/content/Context.html.
activity.openFileOutput() This method opens a private file associated with this Context's application package for writing. see doc

Programmatically how to create Video in android

I want to create an application that will enable to record screen behavior as a video that will be save programmatically on the device. Can any one help me for this ?
Fortunately, this is not possible, except perhaps on rooted devices, for obvious privacy and security reasons. An app cannot record what other apps show on the screen.
For a rooted device you can take screenshots and make a video based on those screenshots using FFMPEG or JavaCV.
Actually this topic have been discussed several times.
Here's an example of How to get root access and get your screenshot.
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
// we check if external storage is\ available, otherwise
// display an error message to the user using Toast Message
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File(sdCard.getAbsolutePath() + "/ScreenShots");
directory.mkdirs();
String filename = "screenshot_jpeg_" + i + ".png";
File yourFile = new File(directory, filename);
try {
Process sh = Runtime.getRuntime().exec("su", null, null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + "/sdcard/ScreenShots/" + filename).getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();
i++;
} catch (Exception e) {
e.printStackTrace();
}
}
You can check other solutions on the following topic and here for FFMPEG

Android mkdirs() creates a zero byte file instead of a folder

In my android application, I am trying to create the following folder on the sdcard:
/mnt/sdcard/OSGiComponents/admin/felix-cache/
Here's the code:
File cacheDir =
new File( Environment.getExternalStorageDirectory().getAbsolutePath() +
"/OSGiComponents/admin/felix-cache/" );
// Create the folder
cacheDir.mkdirs();
// Check if it exists
if ( ! cacheDir.exists() ) {
Log.e ( "Debug" , "Cache directory cannot be created" );
}
I have the WRITE_STORAGE_PERMISSION under the manifest tag of the android manifest file. I am able to create other folders and files without problem on the sdcard.
The app works fine on the following phones:
Nexus S (rooted) running Gingerbread (2.3)
Nexus S (unrooted) running Jelly Bean (4.1.2)
HTC Desire (rooted) running Froyo (2.2)
HTC Desire (unrooted) running Froyo (2.2)
However on Samsung Galaxy Nexus phone (unrooted) running Ice Cream Sandwich (4.0.4), the directory is created as a zero size file, which can be seen in Astro. The exists() call returns false.
As you can see from the folder name, I am using Apache Felix. Felix creates the cache directory automatically if it does not exist. On Galaxy Nexus, it always complained that it is unable to create the cache directory. Astro shows a 0 byte file instead of a folder. This is why I decided to try creating the cache folder myself before initializing Felix.
So, I create the cache folder myself. The app works fine the first time, and I can see the folder fine in Astro. If I close the app, then delete the folder in Astro, and then re-launch the app, even my code mysteriously cannot create the cache directory, and Astro shows a 0 byte file.
The 0 byte file cannot be deleted in Astro. However, when I reboot the phone, the folder is magically there and ok.
I use FileInstall to watch the OSGiComponents/install folder. When I drop bundle jars into that folder, it is detected and installed ok on all phones except Galaxy Nexus (when the app works the first time). There are no logs/errors from FileInstall about not being able to watch the directory.
I have tested this on 2 Galaxy Nexus phones, same problem.
I suspect it is a permissions problem, but I not sure what it is, and why a 0 byte file is created while exists() returns false. Nowhere else in the code am I creating this file.
Any suggestions on what could be the problem?
Thanks :)
UPDATE: I think I have identified the issue, please see the answer I posted.
please use instead of
File cacheDir = new File( Environment.getExternalStorageDirectory().getAbsolutePath() +
"/OSGiComponents/admin/felix-cache/" );
cacheDir.mkdirs();
to
File cacheDir =
new File( Environment.getExternalStorageDirectory().getAbsolutePath() +
"/OSGiComponents/admin/felix-cache" );
cacheDir.mkdir();
I found a workaround which solves this problem. Whenever I am deleting a file/directory, instead of using delete() directly, I rename the file/folder, and then delete() it. This weird workaround seems to remove the problem.
I got this idea by seeing this question's answers - Open failed EBUSY device or Resource busy
However, I'm not sure why this works, or what caused the problem in the first place.
In case anyone else is using Felix on Galaxy Nexus and encounters the same problem, just change the Felix source code as shown below:
org.apache.felix.framework.util.SecureAction.java:
public boolean deleteFile(File target)
{
if (System.getSecurityManager() != null)
{
try
{
Actions actions = (Actions) m_actions.get();
actions.set(Actions.DELETE_FILE_ACTION, target);
return ((Boolean) AccessController.doPrivileged(actions, m_acc))
.booleanValue();
}
catch (PrivilegedActionException ex)
{
throw (RuntimeException) ex.getException();
}
}
else
{
// Solution: Rename before deleting
// https://stackoverflow.com/questions/11539657/open-failed-ebusy-device-or-resource-busy
File to = new File(target.getAbsolutePath() + System.currentTimeMillis());
boolean renameStatus = target.renameTo(to);
boolean deleteStatus = to.delete();
boolean returnStatus = ( renameStatus && deleteStatus );
// Debug SecureAction
//boolean returnStatus = target.delete();
Log.e ( "SecureAction" , "Deleting " + target + " delete(): " + returnStatus );
return returnStatus;
}
}
I suggest that you connect to the device using adb and use the command ls -l in the directory, to check what is operating system reporting about this 0 size file (permissions, etc.). This can eventually bring some light to the issue.
If you can't figure out a working solution, maybe you can make a workarround using the exec() to execute a mkdir directly.
You can use the cobe bellow to do it:
public static boolean execCmd(String command, ArrayList<String> results){
Process process;
try {
process = Runtime.getRuntime().exec(new String [] {"sh", "-c", command});
} catch (IOException e) {
e.printStackTrace();
return false;
}
int result;
try {
result = process.waitFor();
} catch (InterruptedException e1) {
e1.printStackTrace();
return false;
}
if(result != 0){ //error executing command
Log.d("execCmd", "result code : " + result);
String line;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
try {
while ((line = bufferedReader.readLine()) != null){
if(results != null) results.add(line);
Log.d("execCmd", "Error: " + line);
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return false;
}
//Command execution is OK
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
try {
while ((line = bufferedReader.readLine()) != null){
if(results != null) results.add(line);
Log.d("execCmd", line);
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
To use it:
boolean res= execCmd("mkdir "+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/OSGiComponents", results);
if(!res) return error;
res= execCmd("mkdir "+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/OSGiComponents/admin", results);
if(!res) return error;
res= execCmd("mkdir "+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/OSGiComponents/admin/felix-cache", results);
if(!res) return error;
Regards.
String root = Environment.getExternalStorageDirectory()
.getAbsolutePath()+"/OSGiComponents/admin/felix-cache";
File myDir = new File(root);
String fname = "Image Name as you want";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Although not a direct answer to your question,the information mentioned below may help you:
In certain devices, the Environment.getExternalStorageDirectory().getAbsolutePath() does not necessary reflect the actual external sd card path. Sometimes it represents the internal storage.
for example in Galaxy Note 2:
Log.i(TAG,Environment.getExternalStorageDirectory().getAbsolutePath());
will print
12-19 17:35:11.366:
E/sample.Examples(10420): /storage/sdcard0
meanwhile the actual external sd card should be:
/storage/extSdCard
The following are several posts regarding to this issues which may help you:
Building a Utility to get the path to External Removable storage every time
Check if the SDCard is present, boolean is always true
How could i get the correct external storage on Samsung and all other devices?
Android how to use Environment.getExternalStorageDirectory()

Android FileWriter not working on Sony Ericsson Arc but works on another phone

The issue I am having could be a hardware-related. In any case I'm stumped.
I have written some code (that I took and modified from: Writing Text File to SD Card fails) I've put the code below. It works fine on my Sony Ericcson X8. However, on the Sony Ericsson Arc, I can't find the file when I look for it on the phone! I went line by line through the code and there are no failures. It's as if it's on the phone and I'm just blind. I can even see in the debugger that the value of gpxfile is:
/mnt/sdcard/MyCompany/MyLog
But when I use windows explorer to look for the file, I certainly don't see the directory MyCompany. Is there some setting on the phone that (silently) prevents writing to the SD Card?
Here is the code:
public static boolean generateNoteOnSD(String sFileName, String sBody) {
try {
String auxSDCardStatus = Environment.getExternalStorageState() ;
if (!auxSDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
Log.i(TAG, "generateNoteOnSD auxSDCardSTatus: " + auxSDCardStatus);
}
if (auxSDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
File root = new File(Environment.getExternalStorageDirectory(), "Dexcom");
if (!root.exists()) {
root.mkdirs();
}
File gpxfile = new File(root, sFileName);
FileWriter writer = new FileWriter(gpxfile, true);
String currentTimeString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
writer.append(currentTimeString + ", " + sBody +System.getProperty("line.separator") );
//writer.newLine();
writer.flush();
writer.close();
Log.d(TAG,"generateNoteOnSD: Saved to file: " + sBody);
return true;
} else {
return false;
}
} catch(IOException e) {
e.printStackTrace();
return false;
//importError = e.getMessage();
//iError();
}
}
In my case the problem was that I had the Xperia ARC attached to the laptop with a USB cable. Apparently, things don't work quite right if you do that. No problem with the X8, so I'm guessing that it's phone specific. Computer may be putting lock on the file thus preventing Android from updating file. Not sure why I don't get an error though.
Bottom line for future readers: Try disconnecting phone from computer.

Categories

Resources