应用程序关闭时,Alarm Manager不会启动

时间:2016-09-19 07:15:57

标签: java android service alarmmanager

我已经为我的应用程序实现了警报管理器,但因为我的警报管理器在应用程序关闭/死亡时无法启动而感到困惑 我在谷歌搜索很多建议,但没有一个建议工作。 这个我的场景

  1. 打开应用程序 - >自动启动服务/报警管理器
  2. 当应用程序每隔10分钟打开一次,应用程序检查服务器以下载数据并插入数据库
  3. 当应用程序每隔10分钟关闭一次,应用程序检查服务器以下载数据并插入数据库
  4. 问题是当应用程序关闭时服务也停止。 这是我的示例代码

    MainActivity.java

    AlarmReceiver alarm = new AlarmReceiver();
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        alarm.setAlarm(this);
    }
    

    AlarmReceiver.Java

    public class AlarmReceiver extends WakefulBroadcastReceiver {
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    
    @Override
    public void onReceive(Context context, Intent intent) {   
    
        Intent service = new Intent(context, SchedulingService.class);
        startWakefulService(context, service);
    }
    
    public void setAlarm(Context context) {
        alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, AlarmReceiver.class);
        alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
    
    
         alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                  10000,
                  10000, alarmIntent);
    
        ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
        PackageManager pm = context.getPackageManager();
    
        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);           
    }
    
    public void cancelAlarm(Context context) {
        // If the alarm has been set, cancel it.
        if (alarmMgr!= null) {
            alarmMgr.cancel(alarmIntent);
        }
    
    
        ComponentName receiver = new ComponentName(context, BootReceiver.class);
        PackageManager pm = context.getPackageManager();
    
        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);
    } }
    

    BootReceiver.java

    public class BootReceiver extends BroadcastReceiver {
    AlarmReceiver alarm = new AlarmReceiver();
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
        {
            alarm.setAlarm(context);
        }
    }}
    

    ScheduleService.java

    public class SchedulingService extends IntentService {
    public SchedulingService() {
        super("SchedulingService");
    }
    
    public static final String TAG = "Scheduling Demo";
    public static final int NOTIFICATION_ID = 1;
    public static final String SEARCH_STRING = "Active";
    public static final String URL = "http://localhost/TMALive";
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;
    
    @Override
    protected void onHandleIntent(Intent intent) {
        String urlString = URL;
        String result ="";
        try {
            result = loadFromNetwork(urlString);
        } catch (IOException e) {
            Log.i(TAG, getString(R.string.connection_error));
        }
    
        if (result.indexOf(SEARCH_STRING) != -1) {
            sendNotification(getString(R.string.live_found));
            Log.i(TAG, "Your Post Live!!");
        } else {
            sendNotification(getString(R.string.no_live));
            Log.i(TAG, "Your Post Off. :-(");
        }
        AlarmReceiver.completeWakefulIntent(intent);
    
    }
    
    
    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.pos_alert))
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(msg))
        .setContentText(msg);
    
        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }
    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;
    }
    
    
    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;
    }
    
    
    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();
    }}
    

    这个代码在应用程序打开时工作正常,但是当应用程序关闭时没有显示通知并且在重新启动后也是如此。

    你能否更好地使用这种方法或使用服务方法给我建议?

    非常感谢

2 个答案:

答案 0 :(得分:0)

有同样的问题,而在我的情况下,原来是因为一个名为“自动启动管理器”的股票应用程序。在我测试的设备(华硕手机)上,这会阻止应用程序在后台启动,除非用户明确允许。 (不给任何警告)

虽然机会很小,但如果您根据本书执行了所有操作,则可能需要检查系统上是否正在运行类似的软件,并且在应用程序运行时它仍然无效。

答案 1 :(得分:0)

每当应用关闭或从最近的应用中删除时,它都会调用onTrimMemory()方法。

您需要在应用程序关闭或从最近的应用程序中删除时再次设置警报管理器。 在类中覆盖以下方法,该方法扩展Application

@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    // set alarm here 
}