国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Android開(kāi)発マニュアル / AlarmManager(鬧鐘服務(wù))

AlarmManager(鬧鐘服務(wù))

本節(jié)引言:

本節(jié)帶來(lái)的Android中的AlarmManager(鬧鐘服務(wù)),聽(tīng)名字我們知道可以通過(guò)它開(kāi)發(fā)手機(jī)鬧鐘類(lèi)的APP, 而在文檔中的解釋是:在特定的時(shí)刻為我們廣播一個(gè)指定的Intent,簡(jiǎn)單說(shuō)就是我們自己定一個(gè)時(shí)間, 然后當(dāng)?shù)綍r(shí)間時(shí),AlarmManager會(huì)為我們廣播一個(gè)我們?cè)O(shè)定好的Intent,比如時(shí)間到了,可以指向某個(gè) Activity或者Service!另外官方文檔中有一些要注意的地方:

1.png
        另外要注意一點(diǎn)的是,AlarmManager主要是用來(lái)在某個(gè)時(shí)刻運(yùn)行你的代碼的,即時(shí)你的APP在那個(gè)特定 時(shí)間并沒(méi)有運(yùn)行!還有,從API 19開(kāi)始,Alarm的機(jī)制都是非準(zhǔn)確傳遞的,操作系統(tǒng)將會(huì)轉(zhuǎn)換鬧鐘 ,來(lái)最小化喚醒和電池的使用!某些新的API會(huì)支持嚴(yán)格準(zhǔn)確的傳遞,見(jiàn) setWindow(int, long, long, PendingIntent)和setExact(int, long, PendingIntent)。 targetSdkVersion在API 19之前應(yīng)用仍將繼續(xù)使用以前的行為,所有的鬧鐘在要求準(zhǔn)確傳遞的情況 下都會(huì)準(zhǔn)確傳遞。更多詳情可見(jiàn)官方API文檔:AlarmManager

1.Timer類(lèi)與AlarmManager類(lèi)區(qū)別:

如果你學(xué)過(guò)J2SE的話(huà),那么你對(duì)Timer肯定不會(huì)陌生,定時(shí)器嘛,一般寫(xiě)定時(shí)任務(wù)的時(shí)候 肯定離不開(kāi)他,但是在Android里,他卻有個(gè)短板,不太適合那些需要長(zhǎng)時(shí)間在后臺(tái)運(yùn)行的 定時(shí)任務(wù),因?yàn)锳ndroid設(shè)備有自己的休眠策略,當(dāng)長(zhǎng)時(shí)間的無(wú)操作,設(shè)備會(huì)自動(dòng)讓CPU進(jìn)入 休眠狀態(tài),這樣就可能導(dǎo)致Timer中的定時(shí)任務(wù)無(wú)法正常運(yùn)行!而AlarmManager則不存在 這種情況,因?yàn)樗哂袉拘袰PU的功能,可以保證每次需要執(zhí)行特定任務(wù)時(shí)CPU都能正常工作, 或者說(shuō)當(dāng)CPU處于休眠時(shí)注冊(cè)的鬧鐘會(huì)被保留(可以喚醒CPU),但如果設(shè)備被關(guān)閉,或者重新 啟動(dòng)的話(huà),鬧鐘將被清除!(Android手機(jī)關(guān)機(jī)鬧鐘不響...)


2.獲得AlarmManager實(shí)例對(duì)象:

AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

3.相關(guān)方法講解:

  • set(int type,long startTime,PendingIntent pi):一次性鬧鐘
  • setRepeating(int type,long startTime,long intervalTime,PendingIntent pi): 重復(fù)性鬧鐘,和3有區(qū)別,3鬧鐘間隔時(shí)間不固定
  • setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi): 重復(fù)性鬧鐘,時(shí)間不固定
  • cancel(PendingIntent pi):取消AlarmManager的定時(shí)服務(wù)
  • getNextAlarmClock():得到下一個(gè)鬧鐘,返回值A(chǔ)larmManager.AlarmClockInfo
  • setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) 和set方法類(lèi)似,這個(gè)鬧鐘運(yùn)行在系統(tǒng)處于低電模式時(shí)有效
  • setExact(int type, long triggerAtMillis, PendingIntent operation): 在規(guī)定的時(shí)間精確的執(zhí)行鬧鐘,比set方法設(shè)置的精度更高
  • setTime(long millis):設(shè)置系統(tǒng)墻上的時(shí)間
  • setTimeZone(String timeZone):設(shè)置系統(tǒng)持續(xù)的默認(rèn)時(shí)區(qū)
  • setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation): 設(shè)置一個(gè)鬧鐘在給定的時(shí)間窗觸發(fā)。類(lèi)似于set,該方法允許應(yīng)用程序精確地控制操作系統(tǒng)調(diào) 整鬧鐘觸發(fā)時(shí)間的程度。

關(guān)鍵參數(shù)講解

  • Type(鬧鐘類(lèi)型): 有五個(gè)可選值: AlarmManager.ELAPSED_REALTIME: 鬧鐘在手機(jī)睡眠狀態(tài)下不可用,該狀態(tài)下鬧鐘使用相對(duì)時(shí)間(相對(duì)于系統(tǒng)啟動(dòng)開(kāi)始),狀態(tài)值為3; AlarmManager.ELAPSED_REALTIME_WAKEUP鬧鐘在睡眠狀態(tài)下會(huì)喚醒系統(tǒng)并執(zhí)行提示功能,該狀態(tài)下鬧鐘也使用相對(duì)時(shí)間,狀態(tài)值為2; AlarmManager.RTC鬧鐘在睡眠狀態(tài)下不可用,該狀態(tài)下鬧鐘使用絕對(duì)時(shí)間,即當(dāng)前系統(tǒng)時(shí)間,狀態(tài)值為1; AlarmManager.RTC_WAKEUP表示鬧鐘在睡眠狀態(tài)下會(huì)喚醒系統(tǒng)并執(zhí)行提示功能,該狀態(tài)下鬧鐘使用絕對(duì)時(shí)間,狀態(tài)值為0; AlarmManager.POWER_OFF_WAKEUP表示鬧鐘在手機(jī)關(guān)機(jī)狀態(tài)下也能正常進(jìn)行提示功能,所以是5個(gè)狀態(tài)中用的最多的狀態(tài)之一,該狀態(tài)下鬧鐘也是用絕對(duì)時(shí)間,狀態(tài)值為4;不過(guò)本狀態(tài)好像受SDK版本影響,某些版本并不支持;
  • startTime:鬧鐘的第一次執(zhí)行時(shí)間,以毫秒為單位,可以自定義時(shí)間,不過(guò)一般使用當(dāng)前時(shí)間。 需要注意的是,本屬性與第一個(gè)屬性(type)密切相關(guān),如果第一個(gè)參數(shù)對(duì)應(yīng)的鬧鐘使用的是相對(duì)時(shí)間 (ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本屬性就得使用相對(duì)時(shí)間 (相對(duì)于系統(tǒng)啟動(dòng)時(shí)間來(lái)說(shuō)),比如當(dāng)前時(shí)間就表示為:SystemClock.elapsedRealtime(); 如果第一個(gè)參數(shù)對(duì)應(yīng)的鬧鐘使用的是絕對(duì)時(shí)間(RTC、RTC_WAKEUP、POWER_OFF_WAKEUP), 那么本屬性就得使用絕對(duì)時(shí)間,比如當(dāng)前時(shí)間就表示 為:System.currentTimeMillis()。
  • intervalTime:表示兩次鬧鐘執(zhí)行的間隔時(shí)間,也是以毫秒為單位.
  • PendingIntent:綁定了鬧鐘的執(zhí)行動(dòng)作,比如發(fā)送一個(gè)廣播、給出提示等等。 PendingIntent是Intent的封裝類(lèi)。需要注意的是,如果是通過(guò)啟動(dòng)服務(wù)來(lái)實(shí)現(xiàn)鬧鐘提 示的話(huà),PendingIntent對(duì)象的獲取就應(yīng)該采用Pending.getService (Context c,int i,Intent intent,int j)方法;如果是通過(guò)廣播來(lái)實(shí)現(xiàn)鬧鐘 提示的話(huà),PendingIntent對(duì)象的獲取就應(yīng)該采用 PendingIntent.getBroadcast (Context c,int i,Intent intent,int j)方法;如果是采用Activity的方式來(lái)實(shí) 現(xiàn)鬧鐘提示的話(huà),PendingIntent對(duì)象的獲取就應(yīng)該采用 PendingIntent.getActivity(Context c,int i,Intent intent,int j)方法。 如果這三種方法錯(cuò)用了的話(huà),雖然不會(huì)報(bào)錯(cuò),但是看不到鬧鐘提示效果。

4.使用示例:一個(gè)簡(jiǎn)單的定時(shí)任務(wù)

要說(shuō)的是,此例子只在Android 4.4以下的系統(tǒng)可行,5.0以上并不可行,后續(xù)如果有5.0 以上AlarmManager的解決方案,到時(shí)再補(bǔ)上!另外,這里用set方法可能有點(diǎn)不準(zhǔn),如果要 更精確的話(huà)可以使用setExtra()方法來(lái)設(shè)置AlarmManager!

運(yùn)行效果圖

2.png3.png

實(shí)現(xiàn)代碼

首先一個(gè)簡(jiǎn)單的布局文件:activity_main.xml,另外在res創(chuàng)建一個(gè)raw文件夾,把音頻文件丟進(jìn)去! 另外創(chuàng)建一個(gè)只有外層布局的activity_clock.xml作為鬧鐘響時(shí)Activity的布局!沒(méi)東西,就不貼了

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_set"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="設(shè)置鬧鐘" />

    <Button
        android:id="@+id/btn_cancel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="關(guān)閉鬧鐘"
        android:visibility="gone" /></LinearLayout>

接著是MainActivity.java,也很簡(jiǎn)單:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn_set;
    private Button btn_cancel;
    private AlarmManager alarmManager;
    private PendingIntent pi;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }

    private void bindViews() {
        btn_set = (Button) findViewById(R.id.btn_set);
        btn_cancel = (Button) findViewById(R.id.btn_cancel);
        alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

        Intent intent = new Intent(MainActivity.this, ClockActivity.class);
        pi = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);

        btn_set.setOnClickListener(this);
        btn_cancel.setOnClickListener(this);

    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_set:
                Calendar currentTime = Calendar.getInstance();
                new TimePickerDialog(MainActivity.this, 0,
                        new TimePickerDialog.OnTimeSetListener() {
                            @Override
                            public void onTimeSet(TimePicker view,
                                                  int hourOfDay, int minute) {
                                //設(shè)置當(dāng)前時(shí)間
                                Calendar c = Calendar.getInstance();
                                c.setTimeInMillis(System.currentTimeMillis());
                                // 根據(jù)用戶(hù)選擇的時(shí)間來(lái)設(shè)置Calendar對(duì)象
                                c.set(Calendar.HOUR, hourOfDay);
                                c.set(Calendar.MINUTE, minute);
                                // ②設(shè)置AlarmManager在Calendar對(duì)應(yīng)的時(shí)間啟動(dòng)Activity
                                alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);
                                Log.e("HEHE",c.getTimeInMillis()+"");   //這里的時(shí)間是一個(gè)unix時(shí)間戳
                                // 提示鬧鐘設(shè)置完畢:
                                Toast.makeText(MainActivity.this, "鬧鐘設(shè)置完畢~"+ c.getTimeInMillis(),
                                        Toast.LENGTH_SHORT).show();
                            }
                        }, currentTime.get(Calendar.HOUR_OF_DAY), currentTime
                        .get(Calendar.MINUTE), false).show();
                btn_cancel.setVisibility(View.VISIBLE);
                break;
            case R.id.btn_cancel:
                alarmManager.cancel(pi);
                btn_cancel.setVisibility(View.GONE);
                Toast.makeText(MainActivity.this, "鬧鐘已取消", Toast.LENGTH_SHORT)
                        .show();
                break;
        }
    }
}

然后是鬧鈴頁(yè)面的ClockActivity.java

/**
 * Created by Jay on 2015/10/25 0025.
 */
public class ClockActivity extends AppCompatActivity {

    private MediaPlayer mediaPlayer;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_clock);
        mediaPlayer = mediaPlayer.create(this,R.raw.pig);
        mediaPlayer.start();
        //創(chuàng)建一個(gè)鬧鐘提醒的對(duì)話(huà)框,點(diǎn)擊確定關(guān)閉鈴聲與頁(yè)面
        new AlertDialog.Builder(ClockActivity.this).setTitle("鬧鐘").setMessage("小豬小豬快起床~")
                .setPositiveButton("關(guān)閉鬧鈴", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        mediaPlayer.stop();
                        ClockActivity.this.finish();
                    }
                }).show();
    }
}

代碼非常簡(jiǎn)單,核心流程如下:

  • AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);獲得系統(tǒng)提供的AlarmManager服務(wù)的對(duì)象
  • Intent設(shè)置要啟動(dòng)的組件: Intent intent = new Intent(MainActivity.this, ClockActivity.class);
  • PendingIntent對(duì)象設(shè)置動(dòng)作,啟動(dòng)的是Activity還是Service,又或者是廣播!PendingIntent pi = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
  • 調(diào)用AlarmManager的set( )方法設(shè)置單次鬧鐘的鬧鐘類(lèi)型,啟動(dòng)時(shí)間以及PendingIntent對(duì)象!alarmManager.set(AlarmManager.RTC_WAKEUP,c.getTimeInMillis(), pi);

另外假如出現(xiàn)鬧鈴無(wú)效的話(huà),你可以從這些方面入手:

  1. 系統(tǒng)版本或者手機(jī),5.0以上基本沒(méi)戲,小米,自行百度吧~ 2.ClockActivity有注冊(cè)沒(méi)? 3.假如你用的是alarmManager發(fā)送廣播,廣播再激活A(yù)ctivity的話(huà),則需要為Intent設(shè)置一個(gè)flag: i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

  2. 4.

  3. 4.png

  4. 這些地方?jīng)]寫(xiě)錯(cuò)吧~別把getActivity寫(xiě)成了getService等哦~


另外,關(guān)于AlarmManager結(jié)合后來(lái)Service實(shí)現(xiàn)定時(shí)后臺(tái)任務(wù)的例子,可見(jiàn):4.2.2 Service進(jìn)階


5.代碼示例下載:

AlarmManagerDemo.zip


本節(jié)小結(jié):

好的,本節(jié)跟大家講解了Android中的AlarmManager(鬧鐘服務(wù))的使用,除了可以像例子那樣定制 一個(gè)自己的鬧鐘,也可以結(jié)合Service,Thread來(lái)完成輪詢(xún)等,用法多多,還需各位自行探究,嗯 本節(jié)就到這里,謝謝~5.gif