android, how to use "dumpsys meminfo" programmatically - android-memory

Would like to use "dumpsys meminfo" programmatically to printout the memory usage for the application at certain time points,
added <uses-permission android:name="android.permission.DUMP" />, and tested on emulator with the following code, but got exception:
"java.io.IOException: Cannot run program "adb": error=13, Permission denied"
fun dump() {
val process = Runtime.getRuntime().exec("adb shell dumpsys meminfo com.testapp.demo")
process.waitFor()
val bufferedReader = BufferedReader(InputStreamReader(process.getInputStream()))
var buffer: String? = ""
while (bufferedReader.readLine().also({ buffer = it }) != null) {
Log.i("+++", buffer)
}
buffer = ""
val buffered = BufferedReader(InputStreamReader(process.getErrorStream()))
while (buffered.readLine().also({ buffer = it }) != null) {
Log.w("+++", buffer)
}
}

Runtime.getRuntime().exec() runs inside the tablet, So adb shell is unnecessary command.
You can thus try this...?
Runtime.getRuntime().exec("dumpsys meminfo com.testapp.demo")

Related

Save Image to android local folder fails in some device

I'm saving images from bitmap to android local folder using below code,
val relativeLocation = Environment.DIRECTORY_PICTURES + "/" + "MyAppName"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "Filename")
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation)
}
}
val resolver = reqireActivity().contentResolver
val uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
uri?.let { uri ->
val stream = resolver.openOutputStream(uri)
stream?.let { stream ->
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream)) {
throw IOException("Failed to save bitmap.")
}
} ?: throw IOException("Failed to get output stream.")
} ?: throw IOException("Failed to create new MediaStore record")
It works well in all devices, but now in crashlytics, i'm getting following error message from MI-Note4(android-7.0) and Mi Redmi 5Plus(android-8.1.0) devices,
Fatal Exception: java.lang.IllegalArgumentException
Unknown URL content://media/external/images/media
at android.content.ContentResolver.insert
Not sure really how to solve this issue

VS Code task process stdout/stderr

I'm attempting to write some test for a VS Code extension.
The extension basically creates some tasks, using ShellExecution to run a local executable file, for example:
new Task(
definition,
folder,
name,
source,
new ShellExecution('./runme', { cwd })
);
I would like to be able to test the shell process, but don't have access to this process and so cannot attach to any of the output streams nor get the exit code.
In my tests, I execute the task like so: await vscode.tasks.executeTask(task); which runs successfully regardless of the exit code of the process created by ShellExecution.
Is there any way I can get access to the child process generated from executing a task?
With Node.js' child_process this is simple to do. I use it to run an external Java jar and capture its output to get the errors. The main part is:
let java = child_process.spawn("java", parameters, spawnOptions);
let buffer = "";
java.stderr.on("data", (data) => {
let text = data.toString();
if (text.startsWith("Picked up _JAVA_OPTIONS:")) {
let endOfInfo = text.indexOf("\n");
if (endOfInfo == -1) {
text = "";
} else {
text = text.substr(endOfInfo + 1, text.length);
}
}
if (text.length > 0) {
buffer += "\n" + text;
}
});
java.on("close", (code) => {
let parser = new ErrorParser(dependencies);
if (parser.convertErrorsToDiagnostics(buffer)) {
thisRef.setupInterpreters(options.outputDir);
resolve(fileList);
} else {
reject(buffer); // Treat this as non-grammar error (e.g. Java exception).
}
});

Command to re-calibrate magnetic sensor

Is there any command through which I can reset the magnetic sensor in an Android device?
I tried echo 1 > /sys/class/sensors/proximity_sensor/prox_cal as suggested here but it's not working.
Are these commands handset dependent?
I am trying this code:
Process process ;
try {
process = Runtime.getRuntime().exec("echo 1 > /sys/class/sensors/proximity_sensor/prox_cal");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
System.out.println("Executing ADB Command");
}
catch(IOException e)
{
System.out.println("Some error while executing ADB Command");
}
It's always going in the catch block. Can anyone help me on this?

ExecuteReader requires an open connection

I am getting the error: "ExecuteReader requires an open connection" and I know the fix is to add a connection.Open() / connection.Close(). My question pertaining to this error is more for me to understand exactly what happen under the hood.
I am currently using the "USING" statement which I expect it to open and close/dispose the connection for me. So I guess I don't understand why it didn't work as expected and I needed to explicitly code the connection.Open() / connection.Close() myself to fix the issue. I did some research and found people experienced similar issue because they were using static connection. In my case, I am creating a new instance of the connection... hence, it bothers me and hoping to get to the bottom of this instead of just fix it and move on. Thank you in advance.
Here is the code:
try
{
using (SqlConnection connection = new SqlConnection(myConnStr))
using (SqlCommand command = new SqlCommand("mySPname", connection))
{
command.CommandType = CommandType.StoredProcedure;
//add some parameters
SqlParameter retParam = command.Parameters.Add("#RetVal", SqlDbType.VarChar);
retParam.Direction = ParameterDirection.ReturnValue;
/////////////////////////////////////////////////
// fix - add this line of code: connection.Open();
/////////////////////////////////////////////////
using(SqlDataReader dr = command.ExecuteReader())
{
int success = (int)retParam.Value;
// manually close the connection here if manually open it. Code: connection.Close();
return Convert.ToBoolean(success);
}
}
}
catch (Exception ex)
{
throw;
}
Using does not open any connections, it only disposes of any allocated memory after calling End Using.
For the SqlConnection, you have to explicitly open it inside the using block, you just don't need to close it though.
I also notice that you are missing a set of brackets {} around the using SqlConnection. Maybe that's the issue? It should be like this:
try
{
using (SqlConnection connection = new SqlConnection(myConnStr))
{
connection.Open();
using (SqlCommand command = new SqlCommand("InsertProcessedPnLFile", connection))
{
command.CommandType = CommandType.StoredProcedure;
//add some parameters
SqlParameter retParam = command.Parameters.Add("#RetVal", SqlDbType.VarChar);
retParam.Direction = ParameterDirection.ReturnValue;
/////////////////////////////////////////////////
// fix - add this line of code: connection.Open();
/////////////////////////////////////////////////
using(SqlDataReader dr = command.ExecuteReader())
{
int success = (int)retParam.Value;
// manually close the connection here if manually open it. Code: connection.Close();
return Convert.ToBoolean(success);
}
}
}
}

Using java.lang.ProcessBuilder

From a java application I run a bat file which starts another java application:
ProcessBuilder processBuilder = new ProcessBuilder("path to bat file");
Process process = processBuilder.start();
But the process never starts and no errors gets printed. But if I add the line:
String resultString = convertStreamToString(process.getInputStream());
after : Process process = processBuilder.start();
where:
public String convertStreamToString(InputStream is) throws IOException {
/*
* To convert the InputStream to String we use the Reader.read(char[]
* buffer) method. We iterate until the Reader return -1 which means there's
* no more data to read. We use the StringWriter class to produce the
* string.
*/
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {
return "";
} }
it runs fine! Any ideas?
If it's really a batch file, you should run the command line interpreter as process (e.g. cmd.exe) with that file as parameter.
Solved here:
Starting a process with inherited stdin/stdout/stderr in Java 6
But, FYI, the deal is that sub-processes have a limited output buffer so if you don't read from it they hang waiting to write more IO. Your example in the original post correctly resolves this by continuing to read from the process's output stream so it doesn't hang.
The linked-to article demonstrates one method of reading from the streams. Key take-away concept though is you've got to keep reading output/error from the subprocess to keep it from hanging due to I/O blocking.