1. 程式人生 > >安卓權威編程指南 挑戰練習(第26章 在 Lollipop 設備上使用 JobService)

安卓權威編程指南 挑戰練習(第26章 在 Lollipop 設備上使用 JobService)

gallery sha params build 運行 intent ble 一次 lol

26.11 挑戰練習:在 Lollipop 設備上使用 JobService
請創建另一個 PollService 實現版本。新的 PollService 應該繼承 JobService 並使用
JobScheduler 來運行。在 PollService 啟動代碼中,檢查系統版本是否為Lollipop:如果是,就
使用 JobScheduler 計劃運行 JobService ;如果不是,依然使用 AlarmManager 實現。

JobService類:

  1 package com.bignerdranch.android.photogallery;
  2 
  3 import
android.app.Notification; 4 import android.app.PendingIntent; 5 import android.app.job.JobInfo; 6 import android.app.job.JobParameters; 7 import android.app.job.JobScheduler; 8 import android.content.ComponentName; 9 import android.content.Context; 10 import android.content.Intent; 11 import
android.content.res.Resources; 12 import android.os.AsyncTask; 13 import android.support.v4.app.NotificationCompat; 14 import android.support.v4.app.NotificationManagerCompat; 15 import android.util.Log; 16 17 import java.util.List; 18 19 /** 20 * Created by Leo on 2017/7/22. 21 */ 22 23
public class JobService extends android.app.job.JobService { 24 25 private static final String TAG = "PollService"; 26 27 private PollTask mCurrentTask; 28 29 @Override 30 public boolean onStartJob(JobParameters parms){ //服務啟動後執行 31 mCurrentTask = new PollTask(); 32 mCurrentTask.execute(parms); //開啟AsyncTask 33 return true; 34 } 35 36 @Override 37 public boolean onStopJob(JobParameters params) { 38 if(mCurrentTask != null){ 39 mCurrentTask.cancel(true); 40 } 41 return false; 42 } 43 44 45 public static void setServiceAlarm(Context context,Boolean shouldStartAlarm){ //Fragment中啟動服務需要調用的方法.用於在Fragment啟動JobService 46 final int JOB_ID = 1; 47 JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); 48 if(shouldStartAlarm){ 49 scheduler.cancel(JOB_ID); 50 }else{ 51 JobInfo jobInfo = new JobInfo.Builder(JOB_ID, new ComponentName(context, JobService.class)) 52 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) 53 .setPeriodic(1000 * 60) 54 .setPersisted(true) 55 .build(); 56 scheduler.schedule(jobInfo); 57 } 58 59 } 60 61 //判斷是否已經計劃好了任務 62 public static boolean isHasBeenScheduled(Context context){ 63 64 final int JOB_ID = 1; 65 66 JobScheduler scheduler = (JobScheduler)context.getSystemService(JOB_SCHEDULER_SERVICE); 67 68 boolean hasBeenScheduled = false; 69 70 for (JobInfo jobInfo : scheduler.getAllPendingJobs()) { 71 if (jobInfo.getId() == JOB_ID) { 72 hasBeenScheduled = true; 73 } 74 } 75 76 return hasBeenScheduled; 77 } 78 79 public JobService(){ 80 super(); 81 } 82 83 84 //用於執行 85 private class PollTask extends AsyncTask<JobParameters,Void ,List<GalleryItem>> { 86 //在doInBackground()方法中獲取到最新的結果集。 87 @Override 88 protected List<GalleryItem> doInBackground(JobParameters... params) { 89 JobParameters jobParams = params[0]; 90 91 //不需要手動判斷網絡連接狀態了 92 93 String query = QueryPreferences.getStoredQuery(JobService.this); //獲取查詢值 94 95 List<GalleryItem> items; 96 97 //獲取最新結果集 98 if(query == null){ 99 items = new FlickrFetcher().fetchRecentPhotos(); 100 }else{ 101 items = new FlickrFetcher().searchPhotos(query); 102 } 103 104 jobFinished(jobParams,false); 105 106 return items; //將items返回出去, onPostExcute()方法會接受到 107 } 108 109 @Override 110 protected void onPostExecute(List<GalleryItem> items) { 111 String lastResultId = QueryPreferences.getLastResultId(JobService.this); 112 //獲取第一條結果 113 String resultId = items.get(0).getId(); 114 //確認是否不同於上一次結果ID ,不同的話彈出Notification。 115 if(resultId.equals(lastResultId)){ 116 Log.i(TAG, "Got a old result" + resultId); 117 }else{ 118 Log.i(TAG, "Got a new result" + resultId); 119 120 Resources resources = getResources(); 121 Intent i = PhotoGalleryActivity.newIntent(JobService.this); 122 PendingIntent pi = PendingIntent.getActivity(JobService.this,0,i,0); 123 124 Notification notification = new NotificationCompat.Builder(JobService.this) 125 .setTicker(resources.getString(R.string.new_pictures_title)) 126 .setSmallIcon(android.R.drawable.ic_menu_report_image) 127 .setContentTitle(resources.getString(R.string.new_pictures_title)) 128 .setContentText(resources.getString(R.string.new_pictures_text)) 129 .setContentIntent(pi) 130 .setAutoCancel(true) 131 .build(); 132 133 NotificationManagerCompat notificationManager = NotificationManagerCompat.from(JobService.this); 134 notificationManager.notify(0,notification); 135 } 136 //將第一條結果存入SharedPreferences 137 QueryPreferences.setLastResultId(JobService.this,resultId); 138 } 139 } 140 }
PhotoGalleryFragment類:
onOptionsSelected()方法:
@Override
    public boolean onOptionsItemSelected(MenuItem item){
        switch (item.getItemId()){
            case R.id.menu_item_clear:
                QueryPreferences.setStoredQuery(getActivity(),null);
                updateItems();
                return true;
            case R.id.menu_item_toggle_polling:
                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
                    boolean shouldStartAlarm  = JobService.isHasBeenScheduled(getActivity()); //啟動服務
                    JobService.setServiceAlarm(getActivity(),shouldStartAlarm);
                    getActivity().invalidateOptionsMenu();
                }else{
                    boolean shouldStartAlarm  = !PollService.isServiceAlarmOn(getActivity());
                    PollService.setServiceAlarm(getActivity(),shouldStartAlarm);
                    getActivity().invalidateOptionsMenu(); //刷新菜單項

                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }

onCreateOptionsMenu()方法:



public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater){
        super.onCreateOptionsMenu(menu,menuInflater);
        menuInflater.inflate(R.menu.fragment_photo_gallery,menu);

        MenuItem searchItem = menu.findItem(R.id.menu_item_search); //將MenuItem取出並保存在searchItem變量中。
        mSearchView = (SearchView)searchItem.getActionView(); //取出SearchView對象。


        //設置監聽器
        mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {//提交搜索查詢時。這個方法執行。
                Log.d(TAG, "onQueryTextSubmit: "+ s);
                QueryPreferences.setStoredQuery(getActivity(),s); //存儲用戶提交的查詢信息。
                updateItems();
                hintSoftInputAndSearchField(); //隱藏鍵盤的方法
                return true;
            }

            @Override
            public boolean onQueryTextChange(String s) { //搜索框的文字有變化時,這個方法執行。
                Log.d(TAG, "onQueryTextChange: " + s);
                return false;
            }
         });

        MenuItem toggleItem = menu.findItem(R.id.menu_item_toggle_polling);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
            if(JobService.isHasBeenScheduled(getActivity())){
                toggleItem.setTitle(R.string.stop_polling);
            }else {
                toggleItem.setTitle(R.string.start_polling);
            }
        }else{
            if (PollService.isServiceAlarmOn(getActivity())) {
                toggleItem.setTitle(R.string.stop_polling);
            } else {
                toggleItem.setTitle(R.string.start_polling);
            }
        }

        mSearchView.setOnSearchClickListener(new View.OnClickListener() { //設置點擊按鈕時,顯示之前搜索過的值
            @Override
            public void onClick(View v) {
                String query = QueryPreferences.getStoredQuery(getActivity());
                mSearchView.setQuery(query,false);
            }
        });


    }

 

安卓權威編程指南 挑戰練習(第26章 在 Lollipop 設備上使用 JobService)