0

In a View class, I override onFinishInflate() to invoke setupEventHandlers() which defines some listeners. For example:

setDate.setOnClickListener( new OnSingleClick() {
    @Override
    public void onSingleClick( final View v ) {
            controller.onSetDate();
        }
    }
} );

In controller.onSetDate() I have the command:

SystemClock.setCurrentTimeMillis(dateTime.getMillis());

(dateTime is a DateTime Object)

After this method is called, the system kind of freezes. The listeners stop working. Nothing happens when I click the attached buttons (also checked in debug mode - it doesn't enter the listener when a button is clicked). Only pressing back (on the android device itself) works, and then the system returns to normal again (it recognizes the listeners).

Why is this happening?

EDIT:

I'm working on a rooted device, and all the permissions are set.

Now my code looks like this:

AlarmManager alarm = (AlarmManager) MainApplication.getAppContext().getSystemService( Context.ALARM_SERVICE );
long time = dateTime.getMillis();
DateTimeZone zone = dateTime.getZone();
alarm.setTime( time );
alarm.setTimeZone( zone.toTimeZone().getID() );
TimeZone.setDefault( zone.toTimeZone() );
DateTimeZone.setDefault( zone );

The problem occurs only when I try to set the time/date backwards. Setting it forward works fine.

Alaa M.
  • 4,961
  • 10
  • 54
  • 95
  • Since [that method "requires the calling process to have appropriate permissions"](http://developer.android.com/reference/android/os/SystemClock.html#setCurrentTimeMillis%28long%29), my guess is that your app lacks those permissions. – CommonsWare Mar 30 '15 at 11:43
  • It doesn't. Changing the time works. I run `"chmod 666 /dev/alarm"` before calling `SystemClock.setCurrentTimeMillis()` – Alaa M. Mar 30 '15 at 11:45

2 Answers2

2

The javadoc about SystemClock.setCurrentTimeMillis indicates that your app must have the appropriate permission. A quick look into the code shows that SystemClock.setCurrentTimeMillis is finally calling AlarmManager.setTime which requires the permission : android.permission.SET_TIME

You should add the permission in your manifest :

<uses-permission android:name="android.permission.SET_TIME"/>

Note that this a System level permission, so your app must be signed with the appropriate signature (system) otherwise the permission won't be granted.

You can check that the permission is granted with :

String permission = "android.permission.SET_TIME";
int res = context.checkCallingOrSelfPermission(permission);
boolean permissionSetTimeGranted = (res == PackageManager.PERMISSION_GRANTED);

Remark about your comment : I don't see why running a chmod 666 /dev/alarm would change anything (except that it is probably why your app is freezing instead of simply returning false)

ben75
  • 29,217
  • 10
  • 88
  • 134
  • 1
    As this answer points out, a 3rd party app won't be able to use that permission, claimed in the manifest or not. It's indeed an interesting question what happens if the chmod is not run first (a step which of course would not be possible on a secured consumer device to begin with). If the program fails in a more traditional way, then the issue can clearly be blamed on hacking the device allowing unworkable program flow - apart from permissions, many aspects of internal state can only be safely modified in coordination with other parts buried deep in the system. – Chris Stratton Mar 30 '15 at 12:21
  • I got the `chmod` method from [here](http://stackoverflow.com/a/8752130/900394) . And it works. Without it, the time doesn't change. – Alaa M. Mar 30 '15 at 12:24
  • @ben75 BTW, `permissionSetTimeGranted ` gives `false` value although I have the permission line in the MANIFEST, and used `chmod 666`. 2 notes though: 1. The time changes so apparently I do have permissions. 2. I can clearly see the **alarm** Permissions changing in DDMS from `crw-rw-r-` to `crw-rw-rw-` after applying `chmod 666` – Alaa M. Mar 30 '15 at 12:33
  • No, the chmod method doesn't work - as your experiment has shown, **changing the time without broader coordination is unworkable.** Likely you should drop this project (it won't work on end-user's devices anyway) but at the least you should go find and study whatever in AOSP sources would let a user set the time on a device that doesn't derive it from the network. – Chris Stratton Mar 30 '15 at 12:33
  • *The time changes so apparently I do have permissions* ... imho no! it just means that you found a way to hack the system on your rooted device. Look at your logcat. what's the output when it freeze ? – ben75 Mar 30 '15 at 14:25
1

The solution is:

re-inflate the view after setting the date/time:

dateAndTimeView = ( DateAndTimeSetupView ) View.inflate( DateAndTimeSetupController.this, R.layout.date_and_time_setup, null );
setContentView( dateAndTimeView );  
Alaa M.
  • 4,961
  • 10
  • 54
  • 95