Android Training Sample- Scheduler Sample-无法停止警报 [英] Android Training Sample- Scheduler Sample- unable to stop alarm

查看:83
本文介绍了Android Training Sample- Scheduler Sample-无法停止警报的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Android开发人员培训网站上提供的示例代码(Scheduler.zip)- http://developer.android.com/training/scheduling/index.html



下面是代码:-



MainActivity.java

  / * 
*版权所有2013 Android Open Source Project
*
*根据Apache许可2.0版(许可)许可;
*除非遵守许可,否则您不得使用此文件。
*您可以通过
*
* http://www.apache.org/licenses/LICENSE-2.0获得许可的副本
*
*除非根据适用法律的要求或书面同意,根据许可协议分发的软件
*将按原样分发,
*不作任何明示或暗示的保证或条件。
*有关许可管理的特定语言和
*许可下的限制,请参阅许可。
* /

包com.example.android.scheduler;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


/ **
*此示例演示如何安排导致服务启动
*的警报。当您要计划启动
*长时间运行的警报(例如检索每日预测)时,此功能很有用。
*这个特定的示例每天从Google主页中检索一次内容,而
*会在其中查找搜索字符串 doodle。如果找到该字符串,则表示
*该页面包含自定义涂鸦,而不是标准Google徽标。
* /
公共类MainActivity扩展了Activity {
SampleAlarmReceiver警报= new SampleAlarmReceiver();

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

@Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater()。inflate(R.menu.main,menu);
返回true;
}

//设置和取消警报的菜单选项。
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
//当用户单击 START ALARM时,设置警报。
case R.id.start_action:
alarm.setAlarm(this);
返回true;
//用户单击取消警报时,取消警报。
case R.id.cancel_action:

alarm.cancelAlarm(this);
返回true;
}
返回false;
}
}

SampleAlarmReceiver.java

  package com.example.android.scheduler; 

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v4.content.WakefulBroadcastReceiver;

import java.util.Calendar;

/ **
*发生警报时,此WakefulBroadcastReceiver接收广播的Intent
*,然后启动IntentService {@code SampleSchedulingService}进行一些工作。
* /
公共类SampleAlarmReceiver扩展了WakefulBroadcastReceiver {
//应用程序的AlarmManager,可用于访问系统警报服务。
私人AlarmManager AlarmMgr;
//警报触发时触发的挂起意图。
私人PendingIntent AlarmIntent;

@Override
public void onReceive(上下文上下文,意图意图){
// BEGIN_INCLUDE(alarm_onreceive)
/ *
*如果您的接收者意图包括需要传递给
*服务的其他内容,请使用setComponent()表示该服务应处理
*接收者的意图。例如:
*
* ComponentName comp = new ComponentName(context.getPackageName(),
* MyService.class.getName());
*
* //在此调用中传递的此意图将包括额外的唤醒锁以及
* //接收者意图的内容。
* startWakefulService(context,(intent.setComponent(comp)));
*
*在这个例子中,我们只是创建一个新的意图来交付给服务。
*此意图可额外标识唤醒锁。
* /
Intent服务= new Intent(上下文,SampleSchedulingService.class);

//启动服务,使设备在启动时保持唤醒状态。
startWakefulService(context,service);
// END_INCLUDE(alarm_onreceive)
}

// BEGIN_INCLUDE(set_alarm)
/ **
*设置每天运行一次的重复警报大约在上午8:30触发
*警报时,该应用会向此WakefulBroadcastReceiver广播一个Intent。
* @param context
* /
public void setAlarm(Context context){
alarmMgr =(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(上下文,SampleAlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context,0,intent,0);

日历日历= Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
//将闹钟的触发时间设置为上午8:30。
calendar.set(Calendar.HOUR_OF_DAY,8);
calendar.set(Calendar.MINUTE,30);

/ *
*如果您没有精确的时间要求,请使用不精确的重复警报
*尽量减少设备电池的消耗。
*
*下面的调用指定了警报类型,触发时间,触发警报的间隔
*和警报的关联PendingIntent。
*它使用警报类型RTC_WAKEUP(实时时钟唤醒),它将唤醒
*设备并根据设备时钟时间触发警报。
*
*或者,您可以使用警报类型ELAPSED_REALTIME_WAKEUP触发
*警报,该警报基于自设备启动以来已经过的时间。如果警报基于经过的时间,则
*是首选,例如,如果
*您只是希望警报每60分钟触发一次。如果您想在特定日期/时间触发警报,则只需要使用
* RTC_WAKEUP。请记住
*基于时钟的时间可能无法很好地转换为其他语言环境,并且
*应用的行为可能会受到用户更改设备时间设置的影响。
*
*以下是一些ELAPSED_REALTIME_WAKEUP的示例:
*
* //唤醒设备以在一分钟内发出一次警报。
* alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
* SystemClock.elapsedRealtime()+
* 60 * 1000,alarmIntent);
*
* //唤醒设备以在30分钟内触发警报,然后每30分钟
* //。
* alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
* AlarmManager.INTERVAL_HALF_HOUR,
* AlarmManager.INTERVAL_HALF_HOUR,alarmIntent);
* /

//根据设备的
//时钟,将闹钟设置为在上午8:30左右触发,并每天重复一次。
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),2 * 60 * 1000,alarmIntent);



//启用{@code SampleBootReceiver},以便在
设备重启后自动重启警报。
ComponentName接收者=新的ComponentName(上下文,SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();

pm.setComponentEnabledSetting(接收器,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
// END_INCLUDE(set_alarm)

/ **
*取消警报。
* @param context
* /
// BEGIN_INCLUDE(cancel_alarm)
public void cancelAlarm(Context context){
//如果已设置警报,则取消它。
if(alarmMgr!= null){
alarmMgr.cancel(alarmIntent);
}

//禁用{@code SampleBootReceiver},以便在重启设备时不会自动重启
//警报。
ComponentName接收者=新的ComponentName(上下文,SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();

pm.setComponentEnabledSetting(接收器,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
// END_INCLUDE(cancel_alarm)
}

SampleBootReceiver .java

  package com.example.android.scheduler; 

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/ **
*重启设备后,此BroadcastReceiver会自动(重新)启动警报。在
*应用程序的清单文件中,此接收器设置为禁用(android:enabled = false)。当用户设置警报时,将启用接收器。
*用户取消警报时,接收器被禁用,因此重新启动
*设备不会触发该接收器。
* /
// BEGIN_INCLUDE(autostart)
公共类SampleBootReceiver扩展了BroadcastReceiver {
SampleAlarmReceiver alarm = new SampleAlarmReceiver();
@Override
public void onReceive(Context context,Intent intent){
if(intent.getAction()。equals( android.intent.action.BOOT_COMPLETED))
{
alarm.setAlarm(context);
}
}
}
// END_INCLUDE(自动启动)

SampleSchedulingService.java

  package com.example.android.scheduler; 

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/ **
*此{@code IntentService}负责应用的实际工作。
* {@code SampleAlarmReceiver}(一个{@code WakefulBroadcastReceiver})在服务运行时为该服务持有
*部分唤醒锁。
*服务完成后,它将调用{@code completeWakefulIntent()}释放
*唤醒锁。
* /
公共类SampleSchedulingService扩展了IntentService {
public SampleSchedulingService(){
super( SchedulingService);
}

public static final String TAG =日程演示;
//用于发布通知的ID。
public static final int NOTIFICATION_ID = 1;
//应用程序在Google主页内容中搜索的字符串。如果应用程序找到
//字符串,则表示存在Doodle。
public static final String SEARCH_STRING = doodle;
//应用程序从中获取内容的Google主页URL。
//您可以在此处找到其他带有涂鸦的Google域的列表:
// http://en.wikipedia.org/wiki/List_of_Google_domains
public static final String URL = http://www.google.com;
私人NotificationManager mNotificationManager;
NotificationCompat.Builder构建器;

@Override
protected void onHandleIntent(Intent intent){
// BEGIN_INCLUDE(service_onhandle)
//从中获取内容的URL。
字符串urlString = URL;

字符串结果=;

//尝试连接到Google主页并下载内容。
try {
result = loadFromNetwork(urlString);
} catch(IOException e){
Log.i(TAG,getString(R.string.connection_error));
}

//如果应用在Google主页内容中找到字符串 doodle,则
//表示存在涂鸦。发布涂鸦警报通知。
if(result.indexOf(SEARCH_STRING)!= -1){
sendNotification(getString(R.string.doodle_found)));
Log.i(TAG, Found doodle !!);
} else {
sendNotification(getString(R.string.no_doodle));;
Log.i(TAG,未找到涂鸦。:-();
}
//释放BroadcastReceiver提供的唤醒锁。
SampleAlarmReceiver.completeWakefulIntent(intent );
// END_INCLUDE(service_onhandle)
}

//发布通知,指出是否找到了涂鸦
private void sendNotification(String msg){
mNotificationManager =(NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);

PendingIntent contentIntent = PendingIntent.getActivity(this,0,
new Intent(this,MainActivity) .class),0);

NotificationCompat.Builder mBuilder =
新的NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle (getString(R.string.doodle_alert))
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.s etContentText(msg);

mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID,mBuilder.build());
}

//
//此行下的方法从指定的URL获取内容,并以字符串形式返回
//内容。
//
/ **给定URL字符串,启动提取操作。 * /
private String loadFromNetwork(String urlString)throws IOException {
InputStream stream = null;
字符串str =;

试试{
stream = downloadUrl(urlString);
str = readIt(stream);
}最终{
if(stream!= null){
stream.close();
}
}
return str;
}

/ **
*给定URL的字符串表示形式,建立连接并获得
*输入流。
* @param urlString URL的字符串表示形式。
* @return从成功的HttpURLConnection检索的InputStream。
* @throws IOException
* /
private InputStream downloadUrl(String urlString)throws IOException {

URL url = new URL(urlString);
HttpURLConnection conn =(HttpURLConnection)url.openConnection();
conn.setReadTimeout(10000 / *毫秒* /);
conn.setConnectTimeout(15000 / *毫秒* /);
conn.setRequestMethod( GET);
conn.setDoInput(true);
//启动查询
conn.connect();
InputStream stream = conn.getInputStream();
返回流;
}

/ **
*读取InputStream并将其转换为String。
* @param流InputStream包含来自www.google.com的HTML。
* @return InputStream的字符串版本。
* @throws IOException
* /
私有字符串readIt(InputStream流)抛出IOException {

StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
for(字符串line = reader.readLine(); line!= null; line = reader.readLine())
builder.append(line);
reader.close();
return builder.toString();

}
}

我必须添加android-首先将support-v4.jar文件添加到构建路径以使其正常工作。



每隔2分钟我会收到通知,但是单击取消警报



因此,我尝试在cancelAlarm函数中删除了if条件,但是随后我得到了java.nullpointerexception。



所以基本上,alarmMgr变为空。



但是,我不明白为什么。



此外,由于这是示例代码,我认为其中必须没有错误,因此我一定会错过某些东西。



SampleAlarmReceiver.java:

  public void cancelAlarm(Context context){
if(alarmMgr == null){
alarmMgr =(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
}
Intent intent = new Intent(context,SampleAlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context,0,intent,0);
try {
alarmMgr.cancel(alarmIntent);
Log.e( Alarma cancelada,action);
} catch(异常e){
Log.e(错误警报a,未取消AlarmManager更新。 + e.toString());
}




I am using the sample code(Scheduler.zip) available on the Android developer training website- http://developer.android.com/training/scheduling/index.html

Here's the code:-

MainActivity.java

/*
 * Copyright 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.scheduler;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


/**
 * This sample demonstrates how to schedule an alarm that causes a service to
 * be started. This is useful when you want to schedule alarms that initiate
 * long-running operations, such as retrieving a daily forecast.
 * This particular sample retrieves content from the Google home page once a day and  
 * checks it for the search string "doodle". If it finds this string, that indicates 
 * that the page contains a custom doodle instead of the standard Google logo.
 */
public class MainActivity extends Activity {
    SampleAlarmReceiver alarm = new SampleAlarmReceiver();

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    // Menu options to set and cancel the alarm.
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            // When the user clicks START ALARM, set the alarm.
            case R.id.start_action:
                alarm.setAlarm(this);
                return true;
            // When the user clicks CANCEL ALARM, cancel the alarm. 
            case R.id.cancel_action:

                alarm.cancelAlarm(this);
                return true;
        }
        return false;
    }
}

SampleAlarmReceiver.java

package com.example.android.scheduler;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v4.content.WakefulBroadcastReceiver;

import java.util.Calendar;

/**
 * When the alarm fires, this WakefulBroadcastReceiver receives the broadcast Intent 
 * and then starts the IntentService {@code SampleSchedulingService} to do some work.
 */
public class SampleAlarmReceiver extends WakefulBroadcastReceiver {
    // The app's AlarmManager, which provides access to the system alarm services.
    private AlarmManager alarmMgr;
    // The pending intent that is triggered when the alarm fires.
    private PendingIntent alarmIntent;

    @Override
    public void onReceive(Context context, Intent intent) {   
        // BEGIN_INCLUDE(alarm_onreceive)
        /* 
         * If your receiver intent includes extras that need to be passed along to the
         * service, use setComponent() to indicate that the service should handle the
         * receiver's intent. For example:
         * 
         * ComponentName comp = new ComponentName(context.getPackageName(), 
         *      MyService.class.getName());
         *
         * // This intent passed in this call will include the wake lock extra as well as 
         * // the receiver intent contents.
         * startWakefulService(context, (intent.setComponent(comp)));
         * 
         * In this example, we simply create a new intent to deliver to the service.
         * This intent holds an extra identifying the wake lock.
         */
        Intent service = new Intent(context, SampleSchedulingService.class);

        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, service);
        // END_INCLUDE(alarm_onreceive)
    }

    // BEGIN_INCLUDE(set_alarm)
    /**
     * Sets a repeating alarm that runs once a day at approximately 8:30 a.m. When the
     * alarm fires, the app broadcasts an Intent to this WakefulBroadcastReceiver.
     * @param context
     */
    public void setAlarm(Context context) {
        alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, SampleAlarmReceiver.class);
        alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        // Set the alarm's trigger time to 8:30 a.m.
        calendar.set(Calendar.HOUR_OF_DAY, 8);
        calendar.set(Calendar.MINUTE, 30);

        /* 
         * If you don't have precise time requirements, use an inexact repeating alarm
         * the minimize the drain on the device battery.
         * 
         * The call below specifies the alarm type, the trigger time, the interval at
         * which the alarm is fired, and the alarm's associated PendingIntent.
         * It uses the alarm type RTC_WAKEUP ("Real Time Clock" wake up), which wakes up 
         * the device and triggers the alarm according to the time of the device's clock. 
         * 
         * Alternatively, you can use the alarm type ELAPSED_REALTIME_WAKEUP to trigger 
         * an alarm based on how much time has elapsed since the device was booted. This 
         * is the preferred choice if your alarm is based on elapsed time--for example, if 
         * you simply want your alarm to fire every 60 minutes. You only need to use 
         * RTC_WAKEUP if you want your alarm to fire at a particular date/time. Remember 
         * that clock-based time may not translate well to other locales, and that your 
         * app's behavior could be affected by the user changing the device's time setting.
         * 
         * Here are some examples of ELAPSED_REALTIME_WAKEUP:
         * 
         * // Wake up the device to fire a one-time alarm in one minute.
         * alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
         *         SystemClock.elapsedRealtime() +
         *         60*1000, alarmIntent);
         *        
         * // Wake up the device to fire the alarm in 30 minutes, and every 30 minutes
         * // after that.
         * alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
         *         AlarmManager.INTERVAL_HALF_HOUR, 
         *         AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);
         */

        // Set the alarm to fire at approximately 8:30 a.m., according to the device's
        // clock, and to repeat once a day.
        alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,  
                calendar.getTimeInMillis(), 2*60*1000, alarmIntent);



        // Enable {@code SampleBootReceiver} to automatically restart the alarm when the
        // device is rebooted.
        ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);           
    }
    // END_INCLUDE(set_alarm)

    /**
     * Cancels the alarm.
     * @param context
     */
    // BEGIN_INCLUDE(cancel_alarm)
    public void cancelAlarm(Context context) {
        // If the alarm has been set, cancel it.
        if (alarmMgr!= null) {
            alarmMgr.cancel(alarmIntent);
        }

        // Disable {@code SampleBootReceiver} so that it doesn't automatically restart the 
        // alarm when the device is rebooted.
        ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);
    }
    // END_INCLUDE(cancel_alarm)
}

SampleBootReceiver.java

package com.example.android.scheduler;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * This BroadcastReceiver automatically (re)starts the alarm when the device is
 * rebooted. This receiver is set to be disabled (android:enabled="false") in the
 * application's manifest file. When the user sets the alarm, the receiver is enabled.
 * When the user cancels the alarm, the receiver is disabled, so that rebooting the
 * device will not trigger this receiver.
 */
// BEGIN_INCLUDE(autostart)
public class SampleBootReceiver extends BroadcastReceiver {
    SampleAlarmReceiver alarm = new SampleAlarmReceiver();
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
        {
            alarm.setAlarm(context);
        }
    }
}
//END_INCLUDE(autostart)

SampleSchedulingService.java

package com.example.android.scheduler;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * This {@code IntentService} does the app's actual work.
 * {@code SampleAlarmReceiver} (a {@code WakefulBroadcastReceiver}) holds a
 * partial wake lock for this service while the service does its work. When the
 * service is finished, it calls {@code completeWakefulIntent()} to release the
 * wake lock.
 */
public class SampleSchedulingService extends IntentService {
    public SampleSchedulingService() {
        super("SchedulingService");
    }

    public static final String TAG = "Scheduling Demo";
    // An ID used to post the notification.
    public static final int NOTIFICATION_ID = 1;
    // The string the app searches for in the Google home page content. If the app finds 
    // the string, it indicates the presence of a doodle.  
    public static final String SEARCH_STRING = "doodle";
    // The Google home page URL from which the app fetches content.
    // You can find a list of other Google domains with possible doodles here:
    // http://en.wikipedia.org/wiki/List_of_Google_domains
    public static final String URL = "http://www.google.com";
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;

    @Override
    protected void onHandleIntent(Intent intent) {
        // BEGIN_INCLUDE(service_onhandle)
        // The URL from which to fetch content.
        String urlString = URL;

        String result ="";

        // Try to connect to the Google homepage and download content.
        try {
            result = loadFromNetwork(urlString);
        } catch (IOException e) {
            Log.i(TAG, getString(R.string.connection_error));
        }

        // If the app finds the string "doodle" in the Google home page content, it
        // indicates the presence of a doodle. Post a "Doodle Alert" notification.
        if (result.indexOf(SEARCH_STRING) != -1) {
            sendNotification(getString(R.string.doodle_found));
            Log.i(TAG, "Found doodle!!");
        } else {
            sendNotification(getString(R.string.no_doodle));
            Log.i(TAG, "No doodle found. :-(");
        }
        // Release the wake lock provided by the BroadcastReceiver.
        SampleAlarmReceiver.completeWakefulIntent(intent);
        // END_INCLUDE(service_onhandle)
    }

    // Post a notification indicating whether a doodle was found.
    private void sendNotification(String msg) {
        mNotificationManager = (NotificationManager)
               this.getSystemService(Context.NOTIFICATION_SERVICE);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            new Intent(this, MainActivity.class), 0);

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle(getString(R.string.doodle_alert))
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(msg))
        .setContentText(msg);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }

//
// The methods below this line fetch content from the specified URL and return the
// content as a string.
//
    /** Given a URL string, initiate a fetch operation. */
    private String loadFromNetwork(String urlString) throws IOException {
        InputStream stream = null;
        String str ="";

        try {
            stream = downloadUrl(urlString);
            str = readIt(stream);
        } finally {
            if (stream != null) {
                stream.close();
            }      
        }
        return str;
    }

    /**
     * Given a string representation of a URL, sets up a connection and gets
     * an input stream.
     * @param urlString A string representation of a URL.
     * @return An InputStream retrieved from a successful HttpURLConnection.
     * @throws IOException
     */
    private InputStream downloadUrl(String urlString) throws IOException {

        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        // Start the query
        conn.connect();
        InputStream stream = conn.getInputStream();
        return stream;
    }

    /** 
     * Reads an InputStream and converts it to a String.
     * @param stream InputStream containing HTML from www.google.com.
     * @return String version of InputStream.
     * @throws IOException
     */
    private String readIt(InputStream stream) throws IOException {

        StringBuilder builder = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
        for(String line = reader.readLine(); line != null; line = reader.readLine()) 
            builder.append(line);
        reader.close();
        return builder.toString();

    }
}

I had to add the android-support-v4.jar file to the build path first of all to make it work.

I am getting notifications after every 2 mins, but on clicking the "Cancel Alarm" button, the alarm is not getting canceled.

So , I tried removing the if condition in the cancelAlarm function, but I then got a java.nullpointerexception.

So basically, the alarmMgr is becoming null.

But, I am not able to understand why.

Also, since this is a sample code, I think there must be no errors in it, so I must be missing out on something.

解决方案

I think it is because the instance of alarmManager (alarmMgr) could be uninitialized, as it is initialized in setAlarm. So you have to initialize it also in the cancelAlarm method, in case it is null.

SampleAlarmReceiver.java:

public void cancelAlarm(Context context) {        
    if (alarmMgr==null) {
        alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);           
    }
    Intent intent = new Intent(context, SampleAlarmReceiver.class);
    PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0 , intent, 0);
    try{
        alarmMgr.cancel(alarmIntent);
        Log.e("Alarma cancelada", action );
    }catch (Exception e) {
        Log.e("Error alarma", "AlarmManager update was not canceled. " + e.toString());
    }
    .
    .
    .

这篇关于Android Training Sample- Scheduler Sample-无法停止警报的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆