javaandroidsystemrootsetalarmclock

How to programmatically turn on (Power-On) the android device at a certain time?


How to implement it in Android Studio(API LEVEL >= 17) in my App(System-App + rooted device)?

I know it is possible because my phone(Lenovo A516) and some others have this feature --->>>Screenshot<<<---

..need some ideas to start with.. Can i use AlarmClock for this?


Solution

  • Here is a solution(tested on Lenovo A516, API LEVEL 17, but it should work similar for other devices with "Scheduled power On/Off feature" like described here):

    Uninstall /system/app/SchedulePowerOnOff.apk

    Compile and install this code

    enableAlertPowerOn(...) is the function where the magic happens:

    private static void enableAlertPowerOn(Context context, long atTimeInMillis){
       AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
       Intent intent = new Intent(context, SchPwrOnReceiver.class);
       PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
       am.set(7, atTimeInMillis, sender);
    }
    

    SchPwrOnReceiver.java:

    package com.mediatek.schpwronoff.receivers;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    public class SchPwrOnReceiver extends BroadcastReceiver {
        private static final int STALE_WINDOW = 1800;
        private static final String TAG = "SchPwrOnReceiver";
    
        @Override
        public void onReceive(Context context, Intent intent) {
            //TODO optional
        }
    }
    

    build.gradle(:app), applicationId has to be "com.mediatek.schpwronoff":

    apply plugin: 'com.android.application'
    
    android {
      compileSdkVersion 29
      defaultConfig {
        applicationId "com.mediatek.schpwronoff"
        minSdkVersion 17
        targetSdkVersion 29
        versionCode 17
        versionName "4.2.2"
      }
      buildTypes {
        release {
          minifyEnabled false
          proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
      }
    }
    
    dependencies {
      implementation 'com.android.support:support-compat:28.0.0'
    }
    

    AndroidManifest.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="17" android:versionName="4.2.2" package="com.mediatek.schpwronoff">   
    
    <application
        android:name=".MYApplication"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
           android:launchMode="singleTop">
           <intent-filter>
             <action android:name="android.intent.action.MAIN" />
    
             <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
        </activity>
               <receiver android:name=".receivers.SchPwrOnReceiver">
                 <intent-filter>
                     <action android:name="com.android.settings.schpwronoff.PWR_ON_ALERT"/>
                 </intent-filter>
              </receiver>      
      </application>
    
    </manifest>
    

    Example how to call enableAlertPowerOn(Context context, long atTimeInMillis) from Activity:

      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            showDateTimePickerPowerOn(this);
      }
    
    
    
    public void showDateTimePickerPowerOn(Context context) {
              final Calendar currentDate = Calendar.getInstance();
              date = Calendar.getInstance();
              new DatePickerDialog(context, new DatePickerDialog.OnDateSetListener() {
                  @Override
                  public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                      date.set(year, monthOfYear, dayOfMonth);
                      new TimePickerDialog(context, new TimePickerDialog.OnTimeSetListener() {
                          @Override
                          public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                              date.set(Calendar.HOUR_OF_DAY, hourOfDay);
                              date.set(Calendar.MINUTE, minute);
                              date.set(Calendar.SECOND, 0);                             
    
                              long cTimeInMillis = date.getTimeInMillis();
                              enableAlertPowerOn(context, cTimeInMillis);
                          }
                      }, currentDate.get(Calendar.HOUR_OF_DAY), currentDate.get(Calendar.MINUTE), true).show();
                  }
              }, currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE)).show();
    }