3

I have used Alarm Service. I have implemented the the alarm to run on every 1 minute. So the broadcast receiver onReceive method gets called even after the app quits. I want to implement a timer inside of this onReceive method. I have to start location tracking and wait for 20 Seconds after that I need to stop the location tracking.

I have tried the below,

TimerTask
Handler
Local Broadcast Receiver

But all the above not capable of running once the app quits.

Inside the alarm receiver I want to implement timer to wait for 20 seconds.
How can I achieve this when the app is in quit 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 Timer 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);
            }
        }

    }
};
gnat
  • 6,213
  • 108
  • 53
  • 73
M Vignesh
  • 1,586
  • 2
  • 18
  • 55

2 Answers2

1

Since Android API 11 you can call the goAsync() in onReceive() method. This method returns an object of the PendingResult type. The Android system considers the receiver as alive until you call the PendingResult.finish() on this object. With this option you can trigger asynchronous processing in a receiver. As soon as that thread has completed, its task calls finish() to indicate to the Android system that this component can be recycled.

Here is one Sample Project to demonstrate goAsync() on BroadcastReceiver.

Sufiyan Ghori
  • 18,164
  • 14
  • 82
  • 110
  • I have tried. I have started a Handler with post delayed duration of 20 sec. But it never calling the handler at the specified time interval once the app quits. I tried goAsync() also . But still the receiver is not alive I think. – M Vignesh Dec 30 '14 at 10:36
  • please see the mentioned `goAsync` example code, that would work fine. – Sufiyan Ghori Dec 30 '14 at 10:36
0

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

    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 the device and show through 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);
}
TTransmit
  • 3,270
  • 2
  • 28
  • 43
  • Why is this answer -1? It is working code from an app that does exactly what is described in the question. – TTransmit Dec 30 '14 at 09:59
  • I was inside of the alarm onReceive method. Inside of this metho I have to implement a timer. The code you have shared is to set the alarm. I already did this. – M Vignesh Dec 30 '14 at 10:02
  • 1
    You had not posted the contents of your classes or any Java when my answer was given a -1 and my answer is a valid working solution to your problem. Even though it does not work exactly how you specify it would functionally do what you want. I tested my app and the activity starts even when I shutdown the app. – TTransmit Dec 30 '14 at 10:09