Android app using android.permission.READ_LOGS - is that impolite? - android

I have an app that is available from the Android Market.
Some users have asked for a way of debugging when things don't work out as expected.
I have been looking into adding a menu item that will display the output of
Process mLogcatProc = null;
BufferedReader reader = null;
mLogcatProc = Runtime.getRuntime().exec(
new String[] {"logcat", "-d", "AndroidRuntime:E BDtN:V *:S" });
reader = new BufferedReader(new InputStreamReader (mLogcatProc.getInputStream()));
String line;
ArrayList listOfLogLines = new ArrayList();
while ((line = reader.readLine()) != null)
{
listOfLogLines.add(line);
}
Basically I am extracting the parts of the Log.* lines that my app has been writing and the errors that the AndroidRuntime has been throwing.
I have a working prototype that will display to the user the contents of the part of the log that I have extracted in a ListView.
I will have to add android.permission.READ_LOGS to the AndroidManifest.xml file in order for my app to have read access to the log, and this of course will be information that the user will be prompted with before installing.
And the question is if this is considered impolite, dangerous or otherwise out of the ordinary. Will it keep users from installing?

I wouldn't install an app that did this. If all you want is your own logs, your app can keep its own private log buffer that it writes into along with the system log.
You may not even need to do this though: http://android-developers.blogspot.com/2010/05/google-feedback-for-android.html

Don't make your live difficult and risk problems with your user! java.util.logging is available on android as well (and even forwarded to android.util.Log) and a java.util.logging.Handler will do everything you want.

Related

How to get current Thermal values in Android Programatically?

I am trying to get thermal values of my device programatically. I am able to do it in adb but unable to do this programatically. How can I loop over each and every directory in the directory "thermal" to get the particular value. Some part of my code is as following :
Process p=Runtime.getRuntime().exec("cd sys/class/thermal/");
You cannot access /sys/class/thermal/ through an app because the user performing the action (something like u0_aXYZ) does not have enough permission to perform this action compared to a (root) adb shell.
You can do for instance:
adb shell
run-as your-app-package-name
and from now on you can navigate across the device file system and take a look at the folders your app can access.
If you want to proceed with that your only option is to have a rooted device and build an app with root permissions.
Now I found to do this programatically. I used for loop to find the values. Visit the detailed answer here.
for(int i=0;i<29;i++){
float temp;
Process process = Runtime.getRuntime().exec("cat sys/class/thermal/thermal_zone" + i + "/temp");
process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = reader.readLine();
if (line != null) {
temp = Float.parseFloat(line);
}
reader.close();
process.destroy();
}

My application freezes after a superuser request

I am writing an application which involves getting information on all running processes (name/package name to begin with). I am doing this by invoking "ps" in my code. I requested superuser access from within the application before invoking the "ps" command. However, when I attempt to read the input stream, the application freezes and I do not get any output in the Logcat. Below is the code that I am using:
Process process = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(process.getOutputStream());
outputStream.writeBytes("ps -t -x -P -p -c");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String topInfo = bufferedReader.readLine(); //Where it freezes
while(topInfo != null)
{
Log.i(appInfo, topInfo);
topInfo = bufferedReader.readLine();
}
outputStream.flush();
outputStream.close();
The code works as expected without superuser request, however the result only consists of my application and the "ps" process.
Is there something that I have missed, or something I need to research before I attempt to fix this?I have tried to search this issue on the Internet before asking here, without success. Any help is appreciated.
Thanks in advance.
P.S The application is being run on a rooted device running Android 7.1.1
I have found the cause of the problem. As it turns out, the BufferedReader was not ready to read, therefore it was not getting any input from the input stream. I confirmed this with the following code:
while(bufferedReader.ready())
{
String topInfo;
while ((topInfo = bufferedReader.readLine()) != null)
{
Log.i(appInfo, topInfo);
}
}
The fix to this problem is to wait for the BufferedReader to be ready to to read the process input stream. This can either be done by pausing the thread for some time, or including a loop that will loop through till the BufferedReader is ready to read. I opted for the latter, as shown below:
do
{
//Wait
} while(!bufferedReader.ready());
This gave me the desired results, which was a list of processes running on my device.

Getting Shared Preferences while Migrating Project from Cocos2dX to Unity Android

I had to port my game from Cocos2dX to Unity for various reasons.
I have now ported the project successfully but to launch it I have to make a mechanism to get old user data and store it in new structure, like number of levels locked, high score of users etc.
While searching I came to know that COCOS2dX stored data on user's device on following path
system/data/data/mygamepackage/shared_prefs/Cocos2dxPrefsFile.xml
Is there anyway to get data from above mentioned path?
The above path should be accessible by the app it self.
I am not able to read that file I get following error.
ENOENT No Such file or Directory
The file is there I can see that on rooted device via Root Browser but I get the error when I run the app on same device.
All I need is to access the file programmatically and later I will parse it and will store it via Unity for future use.
Looking forward for a positive and quick response.
I dont know why I am unable to get the file through Unity Engine, I had to write custom plugin is Java and use that in Unity Project and that some how has worked.
Following is the code which return string after reading the file on both rooted and non rooted devices
public static String getCocos2DPrefsFile(String mPackageName)
{
//Get the text file
File file = new File("/data/data/"+mPackageName+"/shared_prefs/","Cocos2dxPrefsFile.xml");
//Read text from file
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
}
catch (IOException e) {
//You'll need to add proper error handling here
Log.d("Error", e.toString());
}
return text.toString();
}

Faster media scanning algorithm for android

I am working n in the meanwhile learning to code in android
I came across this mediastore which returns all the details about all the mp3 files stored on the card(Internal & External).
But this method is very very slow
I guess that's what has been implemented in the default music application
No wonder it sometimes fails to find out all the files...
I was thinking of implementing a faster search algorithm for this purpose, But am confused with the initial requirements of these algorithms
1: I thought of implementing the Binary search method (Divide n Conquer) to find files, but then the algorithm requires information about the number of files to be scanned.How do I get that?
2: I thought of implementing separate threads for each divided cluster.But then will it really work?
Plz help me in this!
the last question : How in the world does poweramp find out all the files so quickly,
My android has about 200 songs on the card, but this app only takes some seconds to get them all!!
Really puzzled!!
Try this code:
go to Download and DCIM folder there you can use this command to get all files and if you want to filter files then here is the link
Process process = null;
try {
process = Runtime.getRuntime().exec("ls -l");
} catch (IOException ez) {
ez.printStackTrace();
}
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder total = new StringBuilder();
String line;
try {
while ((line = in.readLine()) != null) {
System.out.println("line: "+line.toString());
total.append(line);
}
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.println("Command Output: "+total.toString());

Android - reading a text file from Assets seems to include a LOT of junk before/after the actual data?

I package a text file with my Android App (in Assets) which I read within the App itself.
To avoid this file being compressed, it's named 'mytestfile.mp3' and until recently, that worked just fine.
In one of the recent SDK/ADT changes, it seems something 'odd' is happening when reading from Assets and I'm open to ideas as to what it is...
I use code something like this
AssetFileDescriptor descriptor = getAssets().openFd("mytextfile.mp3");
BufferedReader f = new BufferedReader(new FileReader(descriptor.getFileDescriptor()));
String line = f.readLine();
while (line != null) {
// do stuff
Log.d("TAG",line);
}
What I'm now seeing from the Log is rather odd - if the file contained something like this
Fred
Barney
Wilma
I'm seeing huge amounts of nonsense like this in the log
��ߴ�!�c�W���6�f����m�>ߩ���'�����6�#6���l0��mp�
followed - eventually by my text content
Fred
Barney
Wilma
followed by another metric tonne of gibberish - some of which looks like this
����������4�u?'����������������������������������������res/drawable-mdpi/icon.pngPK��������|v?,������������'�����������������������������res/layout-land/dialog_color_picker.xmlPK��������|v?1�!�����t2�������������������������������classes.dexPK��������|v?թVڝ����5���������������������������������META-INF/MANIFEST.MFPK��������|v?�v������j���������������������������������META-INF/CERT.SFPK��������|v?W7#�]�������������������������������������META-INF/CERT.RSAPK������������������������
As you can see, that appears to be raw binary content from the APK (and nothing to do with the text file)??
Is this a recent packaging issue or am I missing something? I'm using ADT15 but I've not tried the recent upgrade just yet!?
p.s. I've upgraded to the latest SDK/ADT and this problem persists - obviously I'd like to escalate it with whoever is at fault (no idea if the problem is Eclipse/ADT/ANT or Android centered) and so I'll start a bounty for ideas...
This is because AssetFileDescriptor.getFileDescriptor() is for your .apk and not the mytextfile.mp3 file inside the .apk. To work with AssetFileDescriptor you need to take e.g. AssetFileDescriptor.getStartOffset() into account as well, which is the offset to the actual file i.e. mytextfile.mp3 in your case.
But there's an easy solution to your problem. Use AssetManager.open(String) instead, which will give you an InputStream to the mytextfile.mp3 file. Like this:
InputStream inputStream = getAssets().open("mytextfile.mp3");
BufferedReader f = new BufferedReader(new InputStreamReader(inputStream));
// ...
Eclipse/ADT occasionally gets the resources corrupted. Try doing a project clean and rebuild to see if that fixes it.
I had the same problem with my app. Try using Apache Commons IO's FileUtils.
This adds another 100kb to your apk, but make File handling much easier.
And if you store the file as myfile.txt instead of .mp3, does it give the same output?
And did you create the file with a Windows or Linux/Unix System? (And with what application?)
/edit: This works for me:
AssetManager am = this.getAssets();
InputStream is = am.open("mytextfile.mp3");
InputStreamReader inputStreamReader = new InputStreamReader(is);
BufferedReader f = new BufferedReader(inputStreamReader);
String line = f.readLine();
while (line != null) {
// do stuff
Log.d("TAG", line);
line = f.readLine();
}

Categories

Resources