I want to add a secret logging toggle switch so that when the QA guys here test the app, they should be able to do some magic secret trick which will switch on the logging for them onltytheir phones.
Magic secret trick meaning something like clicking on a few parts of the screen should switch it on or something else you suggest. This secret should be known only to the QA team and this should not affect the app in any other way.
I am planning to log the statements in a file on sd card.
What are your thoughts? What's the best way to do it?
What's the usual way of doing it?
Make a build for QA with logging on, turn it off for production. Avoid magic tricks.
A very simple way would be checking if a file (empty one, doesn't matter) exists on the sdcard. You could make the filename dynamic (based on date/month) or very obscure.
You could choose to not hide the functionality and just put a button (e.g. in your about box) that will enabled logging. Then if you have a problem at a customer site, that you have a hard time reproducing, you also have the possibility of having the customer sending you a log.
Otherwise I would also suggest checking for some magic file on the sd-card (e.g. app-xyz-enable-log) and if that exists you would automatically start logging to that sd-card. All your QA people would then make a empty file on their sd-card with that name prior to running your app.
The normal way to do it (other than having separate builds) is to use the standard Android logging. You can teach your QA guys to extract the LogCat logs or build a small script for them to do so. Then when you log, make sure to log only the level necessary. For example:
private static String LOG_TAG = "MyLogTag";
private static boolean D = Log.isLoggable(LOG_TAG, Log.DEBUG);
...
if (D) {
Log.d(LOG_TAG, "Something happened that I want to log!");
}
Then normally that statement won't log, but if you want to turn it on, you can run:
adb shell setprop log.tag.MyLogTag DEBUG
Related
I've searched for similar problems, but I didn't find anything useful - I'm working with eclipse, and I can't see my Logs.
The device is connected properly, the app runs and does what it's supposed to do, but I get no logs from it.
I get other logs messages from the device, not the ones that I print, e.g. Log.d("SMS", "hello"). On the other hand, if I use the statement System.out.println("hello"), I do see it, tagged as System.out.
I've tried to disconnect and reconnect the device, restart it, close and open eclipse, choose the device from Device window. It happens both with a 'real' device and an emulator. I've also tried to remove the filtering, but nothing helps - I still don't get the logs.
Okay, I've found the problem -
Apprently there are some illegal tags, and I've used one of them.
My app is spam SMS blocker, and I've used the tag SMS. If I change it to another tag (like SMSBlocker) it suddenly appears in the LogCat.
Check if your project is using proguard.
Basically proguard will remove all the debug logs and optimize your code while creating apk.
Try adding proguard.enabled=false in your project.properties
I think you should use TAG.
When you log from your android app, the first parameter is a TAG string. So if you set it up to a unique string (like your app name) then you can later filter by it in Eclipse.
Example : Log.e(TAG, "state error");
I used to use an app called Log Collector to see system logs. It would send them to my email or via bluetooth,
However, on Jelly Bean the "read log" permission for apps no longer exists and apps can't read the logs, and Log Collector is obviously no exception.
So does one now need to root the device to see system logs? There must be a way for the user to read them. I don't need to access them from an application, I need to read them as a human being. Is there a way?
I got the answer in this google groups thread:
https://groups.google.com/forum/?fromgroups#!searchin/android-developers/READ_LOGS/android-developers/6U4A5irWang/8xOi74KfRIYJ
the message by Mark Murphy replying to Matteo Sisti Sette (which is me).
(it doesn't seem to be possible to link to a particular message, is it?)
POWER + VOLUME_UP + VOLUME_DOWN will generate a report and a screenshot that you can send via email or upload to Drive (ridiculous you can't share it in an arbitrary way such as send via bluetooth or open as text file, but anyways).
(seems you have to hold them for a while and the action is launched when you release them)
At first I thought he was making fun of me and that would just reboot or something, but then I tried and it works.
Quote from Google+ and credits to +Ian Clifton :
"If you go into the developer options of a device running 4.2, you can check the box to add the Bug Report option to the power menu. This also adds it to the quick notifications menu (not sure of the proper name, but slide down the notification shade with two fingers on a phone or on the right side of a tablet)."
..and that would be right answer.. Cheers
My boss hopes that there is no information leak when users use our android apps.
And I found even I set the android:debuggable="false" it still can see my logs from Logcat or command line.
I searched android:debuggable someone also have the same problem.
I got some answers from internet, such as next:
There are a property called debugable of Avd. You can print by adb
shell get prop. I don't (know) if it is the cause of your problem.
If you have a pre-production device, you
can still debug an app that has debuggable set to false.
I just think, even I delete all my logs, there are also many logs about my app from OS.
My questions:
1.Is there a way I can do let my "android:debuggable" work well and
2.Is there any other way to hide all my logs except delete all my logs?
3.What does "android:debuggable" really mean?
4.What is "a pre-production device" when it goes on android device?
Thank you for your help. I will try some other ways, and try my best to share my information in here.
I simply create wrapper functions around Log that first check the value of a static boolean called loggineEnabled if it is set to true then log gets called otherwise the calls to log are ignored.
Then I simply set this variable to false before I compile a version of my app that I distribute.
void LogD(String msg){
if (loggingEnabled)
Log.d(MyTag, msg)
}
Is your code guaranteed to be bug-free? If not, why do you want to stop users having information that they might be able to use to shed light on bugs in your app?
Come back when you can write bug-free code, then we’ll talk.
On Android I am using the android.util.Log to log within my application and during development I am using the adb logcat or Eclipse to see the logs - I use it even more then debugging...
On device I can save the logfile from my code or use some application form Android Market to save the logs - e.g. aLogCat.
Now can I do the same on the iPhone? I can use the NSLog(#"message");, but can I easily save the log file from my application and access it? Are there any ways for that?
Regards,
STeN
This is from NSFoundation reference
NSLog:
Simply calls NSLogv, passing it a variable number of arguments.
NSLogv:
Logs an error message to the Apple System Log facility (see man 3 asl). If the STDERR_FILENO file descriptor has been redirected away from the default or is going to a tty, it will also be written there. If you want to direct output elsewhere, you need to use a custom logging facility.
Thus, it is only a matter of redirecting the file-descriptor "stderr" (2) to a custom file, and you will get everything that you print using NSLog in that file.
This seems to be exactly what you want.
Note that if you want to get logs on console when you are connected to the debugger, you can wrap your code around this to avoid redirection in this case:
if (!isatty(STDERR_FILENO)) { // Not connected to any terminal
// your redirection code
}
You can access the console log from Organizer->Device->Your device->console.
If that is not powerful enough, consider using utilities like NSLogger.
The previous answers are good; also see this if you're inclined to making system calls.
I'm writing an application that must not run on rooted devices. I want to store some secure data and which is possible only on non-rooted devices as nobody can access files in /data/data/package-name.
Does anyone know:
1) Is it possible to prevent the installation of an application on rooted devices? I read something about the "copy-protection mechanism" of Android Market. This feature seems to be outdated and replaced by the licensing feature. However, licensing is only possible for paid application and mine is free...
2) Is it possible to check programmatically whether a device is rooted or not? If it would be possible to do so I could simply stop the application if the device is rooted.
Any help regarding this topic is appreciated!
Execute
Runtime.getRuntime().exec("su");
and check the result code.
In other words, if you can exec su, then you have root access. it doesn't matter if the user allows or denies it, you have your answer.
I think your approach is a bit flawed. First of all, the user can first install your application and data, then "root" the device (even if rooting wipes the data, one can make the backup first). Next, the general rule is that whatever is in user's hands is not yours anymore. The hacker will find a way to get to your data sooner or later.
If you care about secure data, don't put it to device. As Android is net-centric device (yes, I know, that's subjective, but it was initially developed and positioned as such), accessing the data online is not uncommon.
What I would say is to run su and then check the output. If the user allows your app to have root, then use root to uninstall your own application (one way might be to place a script into init.d and then force a reboot).
If the user DOES NOT allow your app to run as root, then:
They DENIED your app permissions.
They are not rooted.
Now, denying permissions (and rooted) means that they have some sort of SUPERUSER management app, and that's where this next part comes in.
I would then proceed to use PackageManager to retrieve a list of all packages and then check them against the handful SuperUser management apps available, namely the ones by Koush, ChainsDD, and Chainfire
The relevant package names are:
com.noshufou.android.su
eu.chainfire.supersu
com.koushikdutta.superuser
Use those methods which will help you check for root
public static boolean findBinary(String binaryName) {
boolean found = false;
if (!found) {
String[] places = { "/sbin/", "/system/bin/", "/system/xbin/",
"/data/local/xbin/", "/data/local/bin/",
"/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/" };
for (String where : places) {
if (new File(where + binaryName).exists()) {
found = true;
break;
}
}
}
return found;
}
private static boolean isRooted() {
return findBinary("su");
}
Now try to check whether the device is rooted.
if (isRooted() == true){
//Do something to prevent run this app on the device
}
else{
//Do nothing and run app normally
}
For example you can force stop the app if the device is rooted
If you are trying to protect data for the user, it's their business to worry about other apps.
If you are trying to protect data from the user, what business do you have putting it on their device?
To answer your question, they are in control of the machine so expect them to be able to trap any call to an API checking 'Is this rooted?' and lie to you. Instead, encrypt the data on the client with a key known to the client, but make it non-obvious where and how you are doing it. Generally make things annoying for whoever is looking.
Enjoy the ensuing game of whack-a-mole. Every time someone cracks into it, you'll make a better fix, they'll make a better crack, and all along the way you will be raising the barrier for cracking it.
Don't fight against freedom - why should you turn away customers with free devices anyway? - instead, if you want a particular outcome, make it so Bother To Get Data > Value Of Getting Data. Then it won't happen. If you truly must have fool-proof security, keep the data server-side.
I believe that one of the 'drawbacks' of the traditional copy protection was that it did not allow the application to be installed on rooted devices, but it also has its own share of problems and will be deprecated soon.
As for client-side checks, you simply cannot rely on a programmatic approach to detect if you're running on a rooted device or not -- anything that is in client-side code can and will be hacked and removed. You'd be surprised at how easy it is to modify even Proguard-obfuscated code. At best, you force the hacker to spend a few hours or days to edit the code and recompile. This is security through obscurity, and not a viable protection mechanism.
1) no. how would you deny installation? why would a rooted device deny installation of something the user wants to install on the fs? being the whole point of rooting that you can make the device do basically whatever.
2) no. not for your purposes. you can check if you can gain root for your application through the usual methods. so you can make a check for a positive but you cannot prove programmatically that it is not rooted, from within your app.
also, what you are asking if you can make perfect copy protection drm system - you might also be missing the point that the user can alter your application, removing your root check. if you have a checksum/crc check of some kind, the user can fake the result of that as well.