AlarmManager被应用程序杀死了

时间:2016-06-14 14:07:04

标签: android alarmmanager

我创建了一个使用闹钟管理器发送消息的应用程序,但如果我长时间发出警报,应用程序会被android自动杀死,所以我需要阻止该应用程序被杀。请告诉我该怎么做

Calendar cal = Calendar.getInstance();
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
if (currentApiVersion > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
    cal.set(Calendar.MINUTE, time_picker.getMinute());
    cal.set(Calendar.HOUR_OF_DAY, time_picker.getHour());
} else {
    //Setting the date and time from the time picker
    cal.set(Calendar.MINUTE, time_picker.getCurrentMinute());
    cal.set(Calendar.HOUR_OF_DAY, time_picker.getCurrentHour());
}
//System clock time
Calendar c = Calendar.getInstance();
Long a ;//=(long) (Calendar.getInstance().get(Calendar.SECOND) * 1000);
if(cal.get(Calendar.HOUR_OF_DAY) < c.get(Calendar.HOUR_OF_DAY))
    h = (cal.get(Calendar.HOUR_OF_DAY) + 24 - c.get(Calendar.HOUR_OF_DAY)) * 60;
else
    h = (cal.get(Calendar.HOUR_OF_DAY) - c.get(Calendar.HOUR_OF_DAY * 60;
m = (cal.get(Calendar.MINUTE) - c.get(Calendar.MINUTE));
a = (m + h) * 60;
myIntent = new Intent(this, MyReceiver.class);
myIntent.putExtra("pos", array.select);


//Pending Intent for sending the intent afterwards
pendingIntent[array.select] = PendingIntent.getBroadcast(this.getApplicationContext(), array.select, myIntent, 0);
alarmManager[array.select] = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
alarmManager[array.select].set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + a * 1000, pendingIntent[array.select]);

pendingarray.add(pendingIntent[array.select]);
sms_list.Phone[array.select] = Phone;
Intent back = new Intent(this, sms_list.class);
back.putExtra("PHONE", Phone);
back.putExtra("Flag",2);
back.putExtra("MSG", Message);
back.putExtra("HOUR", (int) cal.get(Calendar.HOUR_OF_DAY));
back.putExtra("MIN", (int) cal.get(Calendar.MINUTE));
back.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(back);

如果答案是唤醒锁定,请告诉我在哪里使用它。

3 个答案:

答案 0 :(得分:3)

您可以使用服务来执行此操作,这在设备重新启动后也可以使用。您还必须提供服务foreground以防止系统将其终止。可以通过添加持续通知来完成。请参阅下面的服务代码。

在你的清单中添加以下内容

    <receiver
        android:name=".Autostart"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>

    <service
        android:name=".StarterService"
        android:enabled="true"
        android:exported="true" />

然后按如下方式创建一个新类:

public class Autostart extends BroadcastReceiver {

    /**
     * Listens for Android's BOOT_COMPLETED broadcast and then executes
     * the onReceive() method.
     */
    @Override
    public void onReceive(Context context, Intent arg1) {
        Log.d("Autostart", "BOOT_COMPLETED broadcast received. Executing starter service.");

        Intent intent = new Intent(context, StarterService.class);
        context.startService(intent);
    }
}

最后你的服务如下:

public class StarterService extends Service {
    private static final String TAG = "MyService";

    /**
     * starts the AlarmManager.
     */

    @Override
    public void onCreate() {
        super.onCreate();
        //TODO: Start ongoing notification here to make service foreground
    }
    @Override
    public void onStart(Intent intent, int startid) {

       //TODO: Put your AlarmManager code here
       //TODO: you also need to add some logic to check if some previous work is pending in case of a device reboot
        Log.d(TAG, "onStart");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        //TODO: cancel the notification
        Log.d(TAG, "onDestroy");
    }
}

现在,只要您需要发送消息,您需要做的就是call the service。 PS:我知道接受了答案,但希望这可以帮助你或其他人。

答案 1 :(得分:0)

应在广播接收器中触发警报。

如果它执行长期操作,则应使用线程或服务。它们都可以从接收器发射。

修改

作为一个简短的例子,我在活动中的按钮onClickListener中使用此方法:

scheduleAlarm(name);

方法:

public void scheduleAlarm(String client)
{
    SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
    String delay = sharedPref.getString(SettingsActivity.PREF_DELIVERY_DELAY, "48");

// time at which alarm will be scheduled here alarm is scheduled at 1 day from current time,
// we fetch  the current time in milliseconds and added 1 day time
// i.e. 24*60*60*1000= 86,400,000   milliseconds in a day
Long time = new GregorianCalendar().getTimeInMillis()+ Integer.parseInt(delay) * 1000; //todo change seconds to hours

// create an Intent and set the class which will execute when Alarm triggers, here we have
// given AlarmReciever in the Intent, the onRecieve() method of this class will execute when
// alarm triggers and
//we will write the code to send SMS inside onRecieve() method pf Alarmreciever class
Intent intentAlarm = new Intent(this, AlarmReceiver.class);
intentAlarm.putExtra("CLIENT", client);

// create the object
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

//set the alarm for particular time
//todo string res
alarmManager.set(AlarmManager.RTC_WAKEUP,time, PendingIntent.getBroadcast(this,1,  intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
Toast.makeText(this, "Alarm Scheduled in " + delay + " hours", Toast.LENGTH_LONG).show();

}

最后,AlarmReceiver.java

package com.patrickmiller.test2;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent)
    {
        Toast.makeText(context, "Alarm received", Toast.LENGTH_SHORT).show();

        String client = intent.getStringExtra("CLIENT");

        Notify(context, client);
    }

    public void Notify(Context context, String client) {

        //todo expanded layout with options Fiche de contact | Rapport and cover image
        //todo send name, address, phone, email and id through Intent to ContactClientActivity
        //todo delete notification when generated


        try {
            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(context)
                            //todo set notification icon, content title and content text as string resources
                            .setSmallIcon(R.drawable.warning)
                            .setContentTitle(client)
                            .setContentText("N'oubliez pas de générer le rapport du client");

            Intent resultIntent = new Intent(context, ContactClientActivity.class);

            //todo may need to expend instead of calling activity. Buttons will do.
            // Because clicking the notification opens a new ("special") activity, there's
            // no need to create an artificial back stack.
            PendingIntent resultPendingIntent =
                    PendingIntent.getActivity(
                            context,
                            0,
                            resultIntent,
                            PendingIntent.FLAG_UPDATE_CURRENT
                    );

            mBuilder.setContentIntent(resultPendingIntent);

            // Sets an ID for the notification
            int mNotificationId = 001;

            // Gets an instance of the NotificationManager service
            NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);

            // Builds the notification and issues it.
            mNotifyMgr.notify(mNotificationId, mBuilder.build());

        }

        catch(Exception e) {
            Toast.makeText(context, String.valueOf(e), Toast.LENGTH_LONG).show();
        }

    }

}

您不必关心客户的事情。就像我安排闹钟的方式..

我的操作是短暂的,即发送通知。如果您计划长期操作,则应从接收方启动服务或线程( onReceive 回调方法)。

答案 2 :(得分:0)

好吧,你的应用程序已完成,因为它正在主线程中运行,所以你需要在应用程序关闭时未被杀死的其他线程中进行此过程。从官方页面查看此documentation。如果您决定开始使用asyncTask类,请检查此reference