How can I implement a timer to start inside the alarm receiver even after the application exits?

I used Alarm Service. I ran an alarm to start every 1 minute. So the onReceive of the broadcast receiver gets called even after the application exits. I want to implement a timer inside this onReceive method. I have to start tracking location and wait 20 seconds after that, I have to stop tracking location.

I tried below,

TimerTask
Handler
Local Broadcast Receiver

      

But all of the above doesn't work as soon as the application exits.

Inside the alarm receiver, I want to implement a timer to wait 20 seconds.
How can I achieve this when the application is in a complete state?

My AlaramReceiver onReceive method:

 @Override
public void onReceive(Context context, Intent intent) {
    mContext = context;
    mSharedPrefManager = SharedPrefManager.getInstance(mContext);

    mAppUtilInstance.logDebugMessage(TAG, "Track interval alarm receiver.");

    // // Check the preference having any current activity
    if (mSharedPrefManager.checkForCurrentActivityPref()) {
        userActivity = mSharedPrefManager.getCurrentUserActivityPref();

        if (mSharedPrefManager.getIsUserMovedPref()) {
            // User MOVED
            // Call the location service
            LocationUpdateTimer locationUpdateTimer = new LocationUpdateTimer(
            mContext, userActivity, true);
                locationUpdateTimer.initialize();
            mSharedPrefManager.setIsUserMovedPref(false);
        } else {
            // User not MOVED in between the track interval period. He is
            // IDLE
            // Check whether the location information is returned by the
            // google API
            if (mSharedPrefManager.checkForLocationEntityPref()
                    && mSharedPrefManager.getLocationEntityPref()
                            .getLatitude().length() > 0) {
                // Send the packet information to the Fleetilla server
                StoreAndSendLocationInformation storeAndSendLocationInformation = new StoreAndSendLocationInformation(
                        mContext,
                        mSharedPrefManager.getLocationEntityPref(),
                        userActivity);
                storeAndSendLocationInformation.storeAndSend();
            } else {
                // If the location information is not available
                mAppUtilInstance
                        .logDebugMessage(TAG,
                                "Location information is not generated to store and send.");
            }
        }
    }
}

      

Location update time class:

/**
 * LocationUpdateTimer Constructor
 */
public LocationUpdateTimer(Context context, String userActivity,
        boolean isTosend) {
    // Save the context
    mContext = context;
    mUserCurrentActivity = userActivity;
    isToSendLocationInfo = isTosend;
}

/**
 * To start the location reporting
 */
private void startLocationReporting() {
    if (mLocationProviderStatusListener != null) {
        mLocationProviderStatusListener
                .requestLocationProvidersToUpdateStatus(mConstants.EMPTY_STRING);
        scheduleTimerTask();
    }
}

/**
 * To schedule the 20 seconds timer task to get the best location
 * information and send it to Fleetilla server.
 */
private void scheduleTimerTask() {
    bestGPSInfoTimerHandler = new Handler();
    bestGPSInfoTimerHandler.postDelayed(bestGPSInfoRunnable,
            Constants.TIMER_TASK_DELAY);
    mAppUtilInstance.logDebugMessage(TAG,
            "20 Sec Location Update TimerTask Scheduled");
}

/**
 * To cancel the timer tack which was scheduled for 30sec location update
 */
private void cancelTimerTask() {
    if (bestGPSInfoTimerHandler != null) {
        mAppUtilInstance.logDebugMessage(TAG, "20 sec TimerTask canceled");
        bestGPSInfoTimerHandler.removeCallbacks(bestGPSInfoRunnable);
        bestGPSInfoTimerHandler = null;
    }
}
/**
 * A runnable will be called after the 20 sec time interval
 */
Runnable bestGPSInfoRunnable = new Runnable() {
    @Override
    public void run() {
        // Called after 20 seconds
        mAppUtilInstance.logDebugMessage(TAG,
                "TimerTask running after 20 sec interval.");
        stopLocationReporting();
        cancelTimerTask();

        if (isToSendLocationInfo) {
            // Check whether the location information is returned by the
            // google api
            if (mSharedPrefManager.checkForLocationEntityPref()
                    && mSharedPrefManager.getLocationEntityPref()
                            .getLatitude().length() > 0) {
                // Send the packet information to the server
                StoreAndSendLocationInformation storeAndSendLocationInformation = new StoreAndSendLocationInformation(
                        mContext,
                        mSharedPrefManager.getLocationEntityPref(),
                        mUserCurrentActivity);
                storeAndSendLocationInformation.storeAndSend();
            } else {
                // If the location information is not available
                mAppUtilInstance
                        .logDebugMessage(TAG,
                                "Location information is not generated to store and send.");
                mAppUtilInstance
                        .broadcastStatusMessage(
                                mContext,
                                Constants.STATUS_MSG_127
                                        + "Location information is not generated to store and send.",
                                Constants.STATUS_CODE_127);
            }
        }

    }
};

      

+3


source to share


2 answers


As of Android API 11, you can call goAsync () in onReceive()

. This method returns an object of type PendingResult . The Android system considers the receiver to be alive until you call PendingResult.finish()

on this object. With this option, you can initiate asynchronous processing in the receiver. Once this thread has finished, its task calls finish()

to indicate to the Android system that this component can be reworked.



Here is one Sample Project to demonstrate goAsync()

on BroadcastReceiver

.

+1


source


AlarmManager works with PendingIntent. This is how I do it in one of my applications:

    myAlarm = (AlarmManager) getSystemService(ALARM_SERVICE);
    Intent myNewIntent = new Intent(MyCurrentActivityClass.this, MyNewActivityClass.class);
    Calendar wakeUpTime = Calendar.getInstance(); 
    wakeUpTime.add(Calendar.MILLISECOND, (int) myTimeRemaining); 

    myPendingIntent = PendingIntent.getActivity(MyCurrentActivityClass.this, 0, myNewIntent, 0);
    myAlarm.set(AlarmManager.RTC_WAKEUP, wakeUpTime.getTimeInMillis(), myPendingIntent);

      



You can also put the following in your MyNewActivityClass to wake up the device and show the security screen.

public void onAttachedToWindow() {
    //make the activity show even the screen is locked.
    Window window = getWindow();

    window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
            + WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
            + WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
            + WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}

      

0


source







All Articles