• 安卓权威编程指南 挑战练习(第26章 在 Lollipop 设备上使用 JobService)


    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);
                }
            });
    
    
        }
    
    
    
     
  • 相关阅读:
    Delphi程序结构
    SQL存储过程解密 Encrypted object is not transferable, and script can not be generated

    在河南呢
    还在河南,写随笔吧
    HAVING
    mIRC
    关于CAP理论
    开篇
    移动信息系统
  • 原文地址:https://www.cnblogs.com/chase1/p/7222263.html
Copyright © 2020-2023  润新知