7

I realise this question appears elsewhere on SO, however I've tried all solutions that I can find on the site and am still having difficulty. These questions (and their answers) are also several years old, and rather than commenting on old questions, I thought I'd consolidate information here for others and investigate potentially related changes to Android between then and now. Still, if you feel this question qualifies as a duplicate, mark it as such.

Edit: As I stated, other answers on SO have not solved the problem. I don't see how commenting on each and every potential fix with "Doesn't work for me" is conducive to helping myself and others solve the problem, but if that's the case, so be it. For reference, 3 people have marked the questions as a potential duplicate of this question, so I have added those non-working answers to the list below.

My application has some very specific needs, but for the sake of brevity, let's just assume I need to set the system time and date manually to a fixed value. Below I have detailed some notes about my progress in attempting to get this working.

The app has a minimum SDK version of, and is targeting, 24. Others found that they needed to increase the version to this level.

The device has been rooted, and the application is being installed to /system/app so that I can change the date/time.

Some have commented that it is outright impossible for apps to set the time, however looking at apps such as ClockSync, this does not seem to be the case. I'm aware that my app will not be available on the Play store.

The app must set the date/time automatically without user input, so using the following code to make a user set it will not help;

startActivity(new Intent(android.provider.Settings.ACTION_DATE_SETTINGS));

I added the set time permission to the manifest in two ways, on their own and then together. I also tried adding the part about removing the maxSDKversion.

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

<permission android:name="android.permission.SET_TIME"
    android:protectionLevel="signature|system"/>

I had read that certain permissions required not only a manifest entry, but for the user to accept and allow them. However, SET_TIME is not listed among these. I did try doing it anyway, however my permission request was automatically rejected without showing the confirmation box, probably because it did not actually require the permission in the first place.

The code I'm using to try and set the time is as follows:

try {
        Calendar c = Calendar.getInstance();
        c.set(2017, 11, 21, 12, 32, 30);
        AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
        am.setTime(c.getTimeInMillis());
    } catch (Exception e) {
        Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
    }

The error I receive in a toast when this fails is:

java.lang.securityexception: setTime: neither user 10051 nor current process has android.permission.SET_TIME

I have tried the two solutions in the question referenced in my above edit, both of which involve running code to set the date as such:

Runtime.getRuntime().exec("su && date -s 20171122.153720");}

Both of those answers do nothing - the time does not change and no exceptions are thrown. The other answer requires internet access which is outside the scope of my question.

Considering all of the above, is there any key step I have missed in making this work, or anything in the code that would indicate a problem?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
AlternateView
  • 83
  • 1
  • 7
  • 2
    I tend to agree that this isn't a duplicate - the other answers I saw seemed to suggest adding the SET_TIME permission, which I see you already tried. I voted to reopen. – EJoshuaS - Stand with Ukraine Nov 22 '17 at 16:19
  • Thank you, if there's a better way of handling this scenario within SO then I'd appreciate someone actually explaining how to do so rather than just marking it and moving on. I can't exactly comment with this level of detail on all existing answers - in fact, with my rep level, I can't comment full stop yet. – AlternateView Nov 22 '17 at 16:25
  • 1
    It looks like the question is now (correctly, in my opinion) reopened. – EJoshuaS - Stand with Ukraine Nov 23 '17 at 16:30
  • Possible duplicate of [How to set mobile system time and date in android?](https://stackoverflow.com/questions/1332269/how-to-set-mobile-system-time-and-date-in-android) – Imran Ali Khan Nov 27 '17 at 12:05
  • The approach using `AlarmManager.setTime()` only works for system apps, i.e. those signed with the system key and running as the system user. Usually this is only possible if you build the whole system yourself, e.g. using AOSP. Rooting a device does not help. – Ber Jun 11 '21 at 14:42

2 Answers2

2

if you need set second too use this format : MMddhhmmyy.ss

if you have long value of time use this :

SimpleDateFormat dateFormat = new SimpleDateFormat("MMddhhmmyy.ss");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeValue);
Date date = calendar.getTime();

Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());

String command = "date " + dateFormat.format(date)  + "\n";

os.writeBytes(command);
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();
Ali Elahi
  • 131
  • 1
  • 10
1

As it turns out, the answer did lie in the referenced question found here. However, the command is different for Android 7 (and possibly 6, I have not tested) devices. I do not have the reputation to comment over there, so if someone wishes to paste/reference this answer on that question, go right ahead.

The date code I used was in the format MMddhhmmyy, rather than yyyyMMdd.hhmmss; this works for me on Android 7. I also removed the appended '-s'. The full working code I used to set the system time is below. Again it should be noted that this requires rooting the device so is only useful in certain scenarios like mine.

     try {

        Process process = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(process.getOutputStream());
        String command = "date 1123104017\n";
        // Log.e("command",command);
        os.writeBytes(command);
        os.flush();
        os.writeBytes("exit\n");
        os.flush();
        process.waitFor();

    } catch (InterruptedException e) {
        Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
    }

The date I entered, for clarity, is November 23rd 2017 at 10:40 AM.

AlternateView
  • 83
  • 1
  • 7