In my android App, there is an Activity which shows time string according to the System Time Format (12Hr. / 24Hr.).
I am writing espresso test to test this behavior whether the time displays gets changed as the System time format changes.
In order to achieve this, i want to change my System time format through my Instrumentation test for pure testing purpose. and i've added permission in test project's manifest, like this
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
and wrote the following code to change system time format
Context context = InstrumentationRegistry.getContext();
Settings.System.putString(context.getContentResolver(),Settings.System.TIME_12_24, "12");
and it is throwing Permission Denial error. (you can use below link to see the stack trace)
Error StackTrace Screenshot
i am not able to understand, since the code which is trying to change the system time format in the test project itself and it has permission to change the system time setting,
I verified Using this command
adb shell dumpsys package com.my.app.package | grep permission
Please tell me, what i am missing here ?
I've already found an explanation to your issue. Here is it:
The user application does not have permission to change the device
time. Please read the answer by cashbash in the following post
for the alternate option.
Copying here for quick reference:
According to this thread, user apps cannot set the time,
regardless of the permissions we give it. Instead, the best approach
is to make the user set the time manually. We will use:
startActivity(new Intent(android.provider.Settings.ACTION_DATE_SETTINGS));
Unfortunately, there is no way to link them directly to the time
setting (which would save them one more click). By making use of
ellapsedRealtime, we can ensure that the user sets the time correctly.
From: Set Android's date/time programmatically
Try also instead of using Espresso, use uiatomator as that instrumentation test framework can perform actions with Dialogs, Marshmallow permissions or lockscreen.
It works perfectly with Espresso.
Check this site: http://qathread.blogspot.com/2015/05/espresso-uiautomator-perfect-tandem.html
Hope it help
Related
I know from https://developer.android.com/guide/topics/connectivity/telecom/selfManaged, that you can set the default dialer by having the necessary items in your manifest and permissions listed. One of those being the Dial intent.
What i'm trying to do is build a library that does all of these content provider calls and provide a nice reactive way of doing things to my application. While building the library I would like to add some integration tests around these device calls.
There's the GrantPermissionsRule that helps with setting permissions already defined in your manifest but how does one deal with becoming the default dialer or SMS application? I'd accept even an adb command that you could run using a Runtime execute command.
I also tried testing on an emulator and I noticed that you can give your app WRITE_SECURE_SETTINGS but not MANAGE_USERS which is the other necessary permission you need if you were to use reflection to access the https://android.googlesource.com/platform/frameworks/base/+/master/telecomm/java/android/telecom/DefaultDialerManager.java
Any help is much appreciated!
you can try adb command:
adb shell settings put secure dialer_default_application com.google.android.dialer
replacing com.google.android.dialer with your package.
I'm preparing my app to target Android 6.0 Marshmallow.
When setting the target api to 23, the app immediately crashes upon launch. There is no useful information in the logcat output. (It gives a "Requested window does not exist" IllegalStateException, but still, nothing actually useful like class name or line number.)
This is fine (not really), I eventually narrowed it down to my launch activity where I get the user's device IMEI code (TelephonyManager.getDeviceId()). There needs to be a runtime permission request added. I understand this.
However, the app has something like 60 classes across numerous activities, so there is a lot of code to sort through. How can I possibly search through the code to find all of the cases where runtime permissions are required?
Surely Google must have thought of an easy way for developers to track down where the permission requests are required? I thought perhaps commenting out the permissions in the manifest would trigger a compile-time error where the permissions are used, or something of the sort, but nope.
My current method is by going through the app and when it crashes, do like the above with my launch activity and very slowly narrow down where it is. This is extremely inefficient and time-consuming. I'm tempted to just leave it at API 22 for now, but I know sooner or later this will have to be done.
Delete all AndroidManifest.xml permission.
Analyze -> Run Inspection by Name ->Constant and Resource Type Mismatches in Android Studio.
You can detect permission.
But this detection is not perfect...
Because this detects only method that contains this xmls files.
https://android.googlesource.com/platform/tools/adt/idea/+/master/android/annotations/android
https://android.googlesource.com/platform/tools/adt/idea/+/master/android/annotations/android/accounts/annotations.xml#118
What worked for me is this :
Analyze -> Run Inspection by Name -> Missing Permissions
I trying some stuffs with android as i am learning android development, now i have a scenario here.
I want to change the android phone's system date through my application( first i would like to know is this doable? )
Layout is as below
Now what i want is when the user clicks the button the date should increase by say 20 days
how can i do this.
i am unable to start...please help
As I already said that's impossible. You need the SET_TIME permission and that permission is granted by system only to applications that are in the Android system image. If You are able to gain that privilege you can easily change with the AlarmManager. SystemClock.setCurrentTimeMillis write the /dev/allarm file
adb shell ls -l /dev/alarm
crw-rw-r-- system radio 10, 46 2013-06-12 10:46 alarm
c stays for Character special file (stored in /dev).
system is the owner of the file
radio is the group
system and radio have read and write permissions (rw-, tree bits, int value 6), the others have only the read permission (r, int value 4). So the file permission is 664. If you can get root user (running su), you can change the permission of this file and wrote in it a new value. A bug report has been filled in order to ask google to allow apps to modify programmatically the mobile date but it has been declied. Here the reference
On Android, the only way for an application do have write access to the time&date is to get the SET_TIME permission, which is only possible for "applications that are in the Android system image or that are signed with the same certificate as the application that declared the permission." (see signatureOrSystem protection level).
The only way for your application to reach this protection level is to run on a rooted device, or build and sign your own android rom.
If this is your case, you can easily use the AlarmManager or simply the Calendar instance.
Good luck!
Normal user applications does not have permission to change the device time. Read the answer by cashbash in the following post for the alternate option.
Unfortunately, blackbelt is right; android lets us do a lot of cool things, but changing system time programmatically is not one of them.
Since I see that you are looking for more credible/official sources, I suggest you check out this open ticket with Google, which suggests this is an open problem--it ought to work, but doesn't, and it doesn't seem Google is going to fix it anytime soon. The gist of it is that the SET_TIME protection level is set higher than it ought to be. (for more information on permissions, see here)
Although this is not quite the same as changing the time programmatically, you can still make the user change the system time for you if for some reason you do need system time to be changed. This thread will explain how to go about implementing that if you want to go that route.
Hope this was helpful information!
Let's say I have taken over development of an Android app, and my boss asks me why our app requires certain permissions to be displayed to users who buy the app on the Android Market.
Are there any tools or tricks I can use to determine what code triggers each permission, so I can figure out why our app functionally needs those permissions? In particular, I am interested in these permissions:
Phone Calls - Read phone status and identity
System Tools - Retrieve running applications - Allows app to retrieve information about currently and recently running tasks, May allow malicious apps to discover private information about other apps.
The app is a GPS tracking app, and it's not obvious why this permission might be needed.
It would also be helpful to get any tips on why this permission might be needed, even if you can't tell me how to directly analyze the code to find out.
Here is how I would track these down.
Step 1 - Find the manifest permissions declared in your AndroidManifest.xml
Basically everything inside the <uses-permission /> tags e.g.:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Step 2 - Search developer.android.com for classes that use these permissions
Let's take the case of READ_PHONE_STATE, the goal is to find which packages require this permission. A simple search on the dev portal for "READ_PHONE_STATE" starts our search, we are looking for classes here, in the top 5 search results I see the following classes:
TelephonyManager
PhoneStateListener
Click on the classes and get their package names:
android.telephony.TelephonyManager
android.telephony.PhoneStateListener
Step 3 Find classes in your project that import these packages
A simple grep will do, or a Ctrl-H in eclipse, File Search -> Containing text
Step 4 Comment out the import and see what breaks
These are likely candidates for why the permission is required. Confirm the methods in question by looking at the dev portal to validate that the permission is indeed required by that method.
Finally you should be able to tell your boss, READ_PHONE_STATE is required because we call function XYZ which gives us UVW.
Remove a permission and see where the app fails. The answer will be in the logcat output.
That's not an ideal solution though, since you might not know what you need to do in the app to trigger that permission.
I suspect "Read phone status and identity" means that the app is using the device IMEI or similar identifying information to uniquely identify the device to ensure that the app is only being run on a registered device. Or it might just be used as a sort of cookie to track the owner. Look for that code. And remove it, because that's the wrong way to do it. If you need to identify a specific android device, use ANDROID_ID from the Settings.Secure class. http://developer.android.com/reference/android/provider/Settings.Secure.html
As for "Retrieve running applications", I find that one somewhat suspicious. A very common way to implement GPS tracking is to launch a separate service in its own process. This way, if the app should crash, the service will keep going and can be re-attached. In this case, it's possible that the app is using the "Retrieve running applications" to identify and kill the service process. But if so, it's a clumsy way to do it.
With the latest build tools, you can run lint check which will highlight for you all the android SDK method calls which are requiring permissions.
See announcement here http://android-developers.blogspot.com/2015/07/get-your-hands-on-android-studio-13.html and documentation here https://developer.android.com/tools/debugging/annotations.html#permissions .
This is based on android annotations and after some adoption time 3rd party libraries can integrate permission annotations also
The answer for your boss is "because certain API features/calls/methods we use in our app require calee to hold certain permissions. It is for security reasons, and that's the way Android works". As for mentioned permissions - you have to check the code to see if these permissions are really required. Read phone status and identity may indicate your app try to get IMEI or something like this to uniquely identify device. Retrieve running applications - see no reason for GPS tracking app to hold this. But maybe you use 3rd party lib/code that uses this.
My application should have some changes after some time (in hours or days) and I would like to test that.
I try to use SystemClock.setCurrentTimeMillis() in my unit test to simulate the change of time/date, but without any luck.
I declared the <uses-permission android:name="android.permission.WRITE_SETTINGS" /> in the manifest of both the application and the test application, that did not change anything.
At this time, I am running those tests on the emulator if that makes any difference...
Edit : With Nick's help, also requested SET_TIME permission:
<uses-permission android:name="android.permission.SET_TIME" />
But now, the logcat shows :
WARN/PackageManager(59): Not granting permission android.permission.SET_TIME to package com.matthieu.tests (protectionLevel=3 flags=0xbe46)
Another Edit : With dtmilano's answer...
Added this code (with the right try/catch) in my test:
Runtime.getRuntime().exec("date \"$((10800 + $(date +%s)))\"").waitFor();
When I go on the shell, I can run that command without any problem and I see the time changing in the emulator (I am trying to add 3 hours). When I run my tests with my code, the time does not change at all... ?
What I do on the command line is :
date "$((10800 + $(date +%s)))"
I doubt I need to add the "adb shell" part in the Runtime.exec...
Seems like this is on the right path, but still not able to get it running. And it might also go along what Nick pointed to that it needs to be a system process to be able to change the time... ?
Add android.permission.SET_TIME_ZONE to your manifest if you need to change the timezone,
then from your activity (or wherever you need it.. but you'll need to grab an appropriate context..)
Context context = getContext(); // or (Context) this, or whatever depending on where you are
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mgr.setTimeZone(timezoneid); // replace timezoneid with the time zone you need e.g. "pacific/Auckland"
mgr.setTime(timeinmillis); // replace timeinmillis with the time you need in millis, probably from a Date or Calendar object... but watch the timezone in the calendar ;-)
The whole point being that the AlarmManager system service contains members to set the system time and timezone..
http://developer.android.com/reference/android/Manifest.permission.html#SET_TIME
I searched "android permissions" then on the permissions page, did a find on the word "time". if you are past api level 8, i would recommend you request that permission.
Update: based on this link, I do not think it is possible to set the system time from a user space app. For your testing purposes, you may need to manually change the time on the emulator. The only other option I have found requires building and signing your own Android build.
From your host (assuming you are using linux) you may run:
$ adb shell date $(date --date='2011-06-11 12:10:10' +%s.0)
mainly if is the emulator. Replace the date and time with the desired values.
You should find a way of synchronizing this change with your tests or you can even run it from your tests using Runtime.exec().