Android automatic switch implementation

Source: Internet
Author: User
Android automatic switch implementation

There are many applications and examples on the Internet for Android automatic shutdown. Compared with automatic boot, automatic shutdown can be achieved by setting alarm at the application layer. However, automatic start-up is rarely introduced on the Internet, because it requires the support of the underlying RTC clock. Some time ago, the machine was automatically switched on and off based on customer requirements. Here we will share with you.

1. Introduction

My implementation is to add an interface in the setup program to allow users to set the automatic switch. The setting of this automatic switch can refer to the setting of the alarm clock. For automatic shutdown, you may have some important operations during shutdown, so you should be given a chance to cancel the current shutdown.

1) A broadcastreceiver receives the following information:

A) custom action_request_power_off: An rtc_wakeup clock set through alarmmanager when setting auto power off. When the shutdown time is set, the action previously set to alarmmanager will be broadcast. After the broadcastreceiver receives the message, we need to start the power off process.

B) custom action_request_power_on: An rtc_wakeup clock set through alarmmanager when setting auto power on. We know that a RTC alarm should be set for power on, so what is the alarm of rtc_wakeup? In fact, when the user sets automatic shutdown, I set two clocks, one is the RTC clock, used to start the instance when the instance is shut down, and the other is the rtc_wakeup clock. The reason for setting this clock is actually like this. For example, if you set the clock to automatically start up at half past seven every day from Monday to Friday, and on Thursday morning, you open your phone at half past seven, so that, the previously set clock has expired. If you do not reset it, it will not automatically start on Friday morning. So at this time, the previously set rtc_wakeup will receive such information and reset the next automatic boot clock.

C) boot_complete, timezone changed, time set, and other time-related actions: when the system is started up or the time and time zone change, you must reset alarm.

2) a service that processes power off. When broadcastreceiver receives action_request_power_off, we will give you a chance to cancel the current automatic shutdown. This service is used to start a page without background and prompt users. At the same time, the user sets the prompt sound or vibration.

3) one activity: displays a dialog prompt prompting the user to automatically shut down and countdown with a timer. When the user confirms the shutdown or the timer reaches the time, the shutdown is performed. Otherwise, cancel the current shutdown and reset the next automatic shutdown of alarm.


2. implement automatic shutdown. The implementation of automatic shutdown is relatively simple. Here we mainly talk about how to set alarm and shutdown:

1) set alarm for automatic shutdown:

 

    AlarmManager am = (AlarmManager) context                .getSystemService(Context.ALARM_SERVICE);        Intent intent = new Intent(                "com.android.settings.action.REQUEST_POWER_OFF");        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,                intent, PendingIntent.FLAG_CANCEL_CURRENT);        am = (AlarmManager) context                .getSystemService(Context.ALARM_SERVICE);        am.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);

2) the automatic shutdown is./frameworks/base/services/Java/COM/Android/Server/shutdownactivity. Java:

        Intent newIntent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);        newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        startActivity(newIntent);

Intent. action_request_shutdown is a hidden action in intent.

 

3. Implementation of Automatic boot. I have been working on upper-layer applications and frameworks, but I am not very familiar with the underlying layer. Some colleagues have previously shut down the alarm, so we can make a slight change to his previous implementation. When the system powers off, it automatically starts up. We need to set an RTC clock. When the user sets automatic boot, alarmmanagerservice will set the clock. This requires underlying support. The implementation here is to define our own RTC Alarm Type:

1) first define in the header file:

A) kernel/include/Linux/android_alarm.h

#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOW(4, type, struct timespec)#define ANDROID_ALARM_SET_RTC               _IOW('a', 5, struct timespec)/* we define ANDROID_RTC_ALARM_SET for auto power off */#define ANDROID_RTC_ALARM_SET               _IOW('a', 7, int)#define ANDROID_ALARM_BASE_CMD(cmd)         (cmd & ~(_IOC(0, 0, 0xf0, 0)))

B) bionic/libc/kernel/common/Linux/android_alarm.h

#define ANDROID_RTC_ALARM_SET _IOW('a', 7, int)

2) After the definition is complete, you also need to implement: In the alarm_ioctl method of the kernel/Drivers/RTC/alarm-dev.c file, add a case to set alarm

    case ANDROID_RTC_ALARM_SET:        {            unsigned int rtc_alarm_time;            struct rtc_time rtc_now;            if (copy_from_user(&rtc_alarm_time, (void __user *)arg,                sizeof(rtc_alarm_time))) {                rv = -EFAULT;                goto err1;            }            if (pmic_rtc_get_time(&rtc_now) < 0) {                rtc_now.sec = 0;                if (pmic_rtc_start(&rtc_now) < 0) {                    printk("get and set rtc info failed\n");                    break;                }            }            pmic_rtc_disable_alarm(PM_RTC_ALARM_1);            rtc_now.sec += rtc_alarm_time;            pmic_rtc_enable_alarm(PM_RTC_ALARM_1, &rtc_now);            break;        }

Of course, do not forget to add an include:

#include <mach/pmic.h>

3) Add a method in frameworks/base/services/JNI/com_android_server_alarmmanagerservice.cpp to set the clock:

static void android_server_AlarmManagerService_updateRtcAlarm(JNIEnv* env, jobject obj, jint fd, jint seconds){#if HAVE_ANDROID_OS    int result = ioctl(fd, ANDROID_RTC_ALARM_SET, &seconds);    LOGE("set rtc alarm to %d later: %s\n", seconds, strerror(errno));    if (result < 0)    {        LOGE("Unable to set rtc alarm to %d later: %s\n", seconds, strerror(errno));    }#endif}

Also, do not forget to define the interface:

{"updateRtcAlarm", "(II)V", (void*)android_server_AlarmManagerService_updateRtcAlarm},

4) In frameworks/base/services/Java/COM/Android/Server/alarmmanagerservice. java defines the method for setting alarm for native, and then calls it to set the alarm for automatic shutdown:

Definition: Private native void updatertcalarm (int fd, int seconds );

Call:

    public void setRepeating(int type, long triggerAtTime, long interval,             PendingIntent operation) {        if (operation == null) {            Slog.w(TAG, "set/setRepeating ignored because there is no intent");            return;        }        synchronized (mLock) {            Alarm alarm = new Alarm();            alarm.type = type;            alarm.when = triggerAtTime;            alarm.repeatInterval = interval;            alarm.operation = operation;            // Remove this alarm if already scheduled.            removeLocked(operation);            if (localLOGV) Slog.v(TAG, "set: " + alarm);            int index = addAlarmLocked(alarm);            if (index == 0) {                setLocked(alarm);            }            // Start to setup auto power on alarm            if ((alarm.type == AlarmManager.ELAPSED_REALTIME_WAKEUP) &&                                 alarm.operation.getTargetPackage().equals("com.android.settings")) {                updateRtcAlarm(mDescriptor, (int)((alarm.when - System.currentTimeMillis()) / 1000));            }            // End to setup auto power on alarm        }    }

5) set Automatic startup at the application layer

        AlarmManager am = (AlarmManager) context                .getSystemService(Context.ALARM_SERVICE);        Intent intent = new Intent(                "com.android.settings.action.REQUEST_POWER_ON");        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,                intent, PendingIntent.FLAG_CANCEL_CURRENT);        am = (AlarmManager) context                .getSystemService(Context.ALARM_SERVICE);        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, pendingIntent);

4. Summary

1) the principle of automatic boot is relatively simple, but it requires the support of the underlying layer. Therefore, it is a little troublesome for technical staff who are working on the application or framework layer.
2) There are many situations to consider when setting automatic switch-on, such as whether to set a time/Time Zone change, whether the mobile phone is currently in the boot or shutdown status, etc.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.