1.简述
由于9.0版本对系统安全性要求越来越严格,所以开关机的api对于应用层都不能调用了,要实现定时关机必须是系统应用 要在Androidmanifest.xml 中添加 android:sharedUserId=“android.uid.system”
2.代码部分
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v7.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast;
import com.android.tv.settings.R;
import java.util.Calendar;
import java.util.TimeZone;
import android.widget.TextView;
import android.support.v4.content.res.TypedArrayUtils;
import android.support.v7.preference.PreferenceViewHolder;
import android.content.Intent;
import android.app.Instrumentation;
import android.view.KeyEvent;
import android.widget.DatePicker;
import android.content.SharedPreferences;
import android.support.v7.preference.PreferenceManager;
import android.text.format.Time;
import java.util.Date;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import java.text.SimpleDateFormat;
import com.android.tv.settings.system.AlarmBroadcastReciver;public class PreferenceWithPowerOff extends Preference {private static final String TAG &#61; "PreferenceWithPowerOff";private TimePicker mTimepicker;private DatePicker mDatePicker;private Button btn;private Context mContext;private int mHour;private int Minute,mYear,Month,mDay;private Calendar calendar;private AlarmManager alarmManager;public PreferenceWithPowerOff(Context context, AttributeSet attrs, int defStyleAttr) {this(context, attrs, defStyleAttr, 0);}public PreferenceWithPowerOff(Context context, AttributeSet attrs) {this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.dialogPreferenceStyle,android.R.attr.dialogPreferenceStyle));}public PreferenceWithPowerOff(Context context) {this(context,null);}public PreferenceWithPowerOff(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr,defStyleRes);this.mContext&#61;context;alarmManager &#61; (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);}&#64;Overridepublic void onBindViewHolder(PreferenceViewHolder holder) {super.onBindViewHolder(holder);TextView txt &#61; (TextView) holder.itemView.findViewById(R.id.title_txt);txt.setText(mContext.getResources().getString(R.string.setting_power_off));mDatePicker &#61; (DatePicker)holder.itemView.findViewById(R.id.datetimepicker);mTimepicker &#61; (TimePicker) holder.itemView.findViewById(R.id.timepicker);mTimepicker.setDescendantFocusability(TimePicker.FOCUS_BLOCK_DESCENDANTS);mTimepicker.setIs24HourView(true);getCurData();btn &#61; (Button)holder.itemView.findViewById(R.id.power_on_btn);btn.setOnClickListener(new View.OnClickListener() {&#64;Overridepublic void onClick(View v) {if(!isLaterCurrentTime()) {Toast.makeText(mContext, "关机时间必须比当前时间晚1分钟....", Toast.LENGTH_SHORT).show();return;}String houroftime &#61;mHour<10? "0"&#43;mHour:""&#43;mHour;String hourofminute &#61;Minute<10? "0"&#43;Minute:""&#43;Minute;try {SharedPreferences prefs &#61;mContext.getSharedPreferences("data",Context.MODE_PRIVATE);SharedPreferences.Editor editor &#61;prefs.edit();editor.putString("set_poweroff",mYear&#43;"-"&#43;Month&#43;"-"&#43;mDay&#43;" "&#43;houroftime&#43;":"&#43;hourofminute&#43;":00");editor.putBoolean("is_poweroff",true);boolean result &#61; editor.commit();//实现定时关机的关机代码如下SimpleDateFormat simpleDateFormat &#61; new SimpleDateFormat("yyyy-MM-dd HH:mm");Date date &#61; simpleDateFormat.parse(mYear&#43;"-"&#43;Month&#43;"-"&#43;mDay&#43;" "&#43;houroftime&#43;":"&#43;hourofminute);Intent intent &#61; new Intent(mContext,AlarmBroadcastReciver.class);//是否显示关机提示dialog&#xff0c;true显示false不显示直接关机//intent.putExtra("android.intent.extra.KEY_CONFIRM", true);//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);PendingIntent pi &#61; PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);//Log.e("PreferenceWithPower","date:"&#43;mYear&#43;"-"&#43;Month&#43;"-"&#43;mDay&#43;" "&#43;houroftime&#43;":"&#43;hourofminute&#43;"---result:"&#43;result&#43;"----timer:"&#43;date.getTime());alarmManager.set(AlarmManager.RTC_WAKEUP, date.getTime(), pi);//设定时间启动定时器,new Thread(new Runnable() {&#64;Overridepublic void run() {new Instrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);}}).start();} catch (Exception e) {e.printStackTrace();}}});}private void getCurData(){calendar &#61; Calendar.getInstance();calendar.setTimeZone(TimeZone.getTimeZone("GMT&#43;8:00"));mYear&#61;calendar.get(Calendar.YEAR);Month&#61;calendar.get(Calendar.MONTH)&#43;1;mDay&#61;calendar.get(Calendar.DAY_OF_MONTH);mDatePicker.init(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), new DatePicker.OnDateChangedListener() {&#64;Overridepublic void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {// Log.e(TAG,"year:"&#43;year&#43;"--monthOfYear:"&#43;monthOfYear&#43;"---dayOfMonth:"&#43;dayOfMonth);mYear&#61;year;Month &#61; monthOfYear&#43;1;mDay &#61; dayOfMonth;}});mHour &#61; calendar.get(Calendar.HOUR_OF_DAY);Minute&#61;calendar.get(Calendar.MINUTE);mTimepicker.setHour(calendar.get(Calendar.HOUR_OF_DAY));mTimepicker.setMinute(calendar.get(Calendar.MINUTE));mTimepicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { //获取当前选择的时间&#64;Overridepublic void onTimeChanged(TimePicker view, int hourOfDay, int minute) {//Log.e(TAG,"hour:"&#43;hourOfDay&#43;"--minute:"&#43;minute);mHour &#61; hourOfDay;Minute &#61;minute;}});}private boolean isLaterCurrentTime(){int year &#61; calendar.get(Calendar.YEAR);int month &#61; calendar.get(Calendar.MONTH)&#43;1;int day &#61; calendar.get(Calendar.DAY_OF_MONTH);int hour &#61; calendar.get(Calendar.HOUR_OF_DAY);int minute &#61; calendar.get(Calendar.MINUTE);Log.e("PreferenceWithPower","off --year :"&#43;year&#43;"---month:"&#43;month &#43;"--day"&#43;day&#43;"--hour :"&#43;hour &#43;"--minute :"&#43;minute);if(year<mYear){return true;}else if(year &#61;&#61; mYear){if(month<Month){return true;}else if(month&#61;&#61;Month){if(day<mDay){return true;}else if(day&#61;&#61;mDay){if(hour<mHour){return true;}else if(hour&#61;&#61;mHour){if(minute<&#61;Minute-1){return true;}else{return false;}}else{return false;}}else{return false;}}else{return false;}}else{return false;}}
}
3.AlarmBroadcastReciver.class 广播部分代码
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
import android.os.Build;
import android.os.IBinder;
import java.lang.reflect.Method;
import java.io.DataOutputStream;
import java.io.IOException;/*** Created by hi on 2016/8/11.*/
public class AlarmBroadcastReciver extends BroadcastReceiver {&#64;Overridepublic void onReceive(Context context, Intent intent) {//Toast.makeText(context,"关机啦", Toast.LENGTH_SHORT).show();if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {try {Class<?> serviceManager &#61; Class.forName("android.os.ServiceManager");Method getService &#61; serviceManager.getMethod("getService", String.class);Object remoteService &#61; getService.invoke(null, Context.POWER_SERVICE);Class<?> stub &#61; Class.forName("android.os.IPowerManager$Stub");Method asInterface &#61; stub.getMethod("asInterface", IBinder.class);Object powerManager &#61; asInterface.invoke(null, remoteService);Method shutdown &#61; powerManager.getClass().getDeclaredMethod("shutdown",boolean.class, String.class, boolean.class);shutdown.invoke(powerManager, false, "", true);} catch (Exception e) {//nothing to do}}}
}