2

I have registered receiver on onCreate method of Service and unregister it onDestroy? It works perfectly, but on certain Samsung Galaxy s3 i still recives receiver even i stopped service. How to find a solution? is it possible? Please help me. Thanks in advance

package com.sms.sendsms.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;

/**
 * Created by Navruz on 30.03.2016.
*/
public class SendSmsService extends Service {

private static Logger LOGGER = LoggerFactory.getLogger(SendSmsService.class);

@Override
public void onCreate() {
    super.onCreate();
    LOGGER.info("Service is onCreate");
    registerReceiver(incomingCallReceiver, new IntentFilter(
            TelephonyManager.ACTION_PHONE_STATE_CHANGED));


}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    LOGGER.info("Service is onStartCommand");

    return START_STICKY;

}


@Override
public void onDestroy() {
    super.onDestroy();        
    unregisterReceiver(incomingCallReceiver);
}

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

private BroadcastReceiver incomingCallReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        LOGGER.info("IncomingCallReceiver is received.");
        TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        telephony.listen(new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
                LOGGER.info("state : " + state);

            }
        }, PhoneStateListener.LISTEN_CALL_STATE);
    }
};

}

nAkhmedov
  • 3,522
  • 4
  • 37
  • 72
  • Can you post your code ? – Damien Belard Apr 21 '16 at 09:14
  • 2
    Uraaaaa:)))))))) I have found a solution. The problem was telephony.listen(new PhoneStateListener(), ..) not reciver. All i need to do is that telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE); onDestroy method. – nAkhmedov Apr 21 '16 at 10:22

3 Answers3

0

It's not a good idea to call unregisterReceiver(...) in onDestroy() since it is not always guaranteed to be called.

From Official Documentation

Perform any final cleanup before an activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.

Note: do not count on this method being called as a place for saving data! For example, if an activity is editing data in a content provider, those edits should be committed in either onPause() or onSaveInstanceState(Bundle), not here. This method is usually implemented to free resources like threads that are associated with an activity, so that a destroyed activity does not leave such things around while the rest of its application is still running. There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it, so it should not be used to do things that are intended to remain around after the process goes away.

References:

  1. Android Activity onDestroy() is not always called and if called only part of the code is executed
  2. Activity OnDestroy never called?
  3. Is ondestroy not always called?

EDIT

Ok so just found this answer from @CommonsWare where it says that Service's onDestroy() will not get called in some situations as:

  • If the user Force Stops you from the Settings app

  • If Android needs RAM in a hurry (e.g., to process an incoming phone call) and elects to terminate your process to free up that RAM

  • You terminate the process from DDMS

  • Also, if your service crashes with an unhandled exception somewhere, Android may consider the service to be defunct and skip onDestroy()

I guess you are either force stopping the Service or the device is running low on RAM; and hence onDestroy() is not being called.

Community
  • 1
  • 1
camelCaseCoder
  • 1,447
  • 19
  • 32
0

If you getting problem in some device you can try disabling the receiver component explicitly..This will do same regardless of what has specified in manifest.

BroadcastReceiver class

public class Reg extends BroadcastReceiver{
  @Override
  public void onReceive(Context context, Intent intent) {
        // your stuff
  }
}

call this at onDestroy()

ComponentName comp = new ComponentName(this,"com.example.Reg");    //package name,broadcast receiver class path
PackageManager pkg = this.getPackageManager();
pkg.setComponentEnabledSetting(comp,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);

add this to manifest file

<receiver android:name="com.example.Reg" />

COMPONENT_ENABLED_STATE_DISABLED

ENABLING DISABLING BROADCAST RECEIVER DURING RUNTIME

Iamat8
  • 3,888
  • 9
  • 25
  • 35
0

I have a solution, it works for me:

/**
 * if service is going to destroy, unregister broadcast receiver by main activity context.
 */
@Override 
public void onDestroy() {
Log.e(TAG, ">>>>>UEventObserverService.onDestroy()");
getApplicationContext().unregisterReceiver(screen_state_receiver);
super.onDestroy();
}
Mou
  • 145
  • 1
  • 6