1

I have created Broadcast Receiver for detect incoming call. It works fine when app is in foreground but it stopped working after kill app. So i used Work Manager for achieve but it also wont work. I am not sure if i implemented Work Manager properly.

Please help me to make Broadcast Receiver alive when app is killed also suggest me right way if i made any mistake for get the result.

PhoneStateBroadcastReceiver.java

public class PhoneStateBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    telephonyManager.listen(new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String phoneNumber) {
            super.onCallStateChanged(state, phoneNumber);
            try {
                if (state == TelephonyManager.CALL_STATE_RINGING) {
                    Log.e("phoneNumber", phoneNumber);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     }, PhoneStateListener.LISTEN_CALL_STATE);
   }
 }

PhoneStateWorkManager.java

public class PhoneStateWorkManager extends Worker {
PhoneStateBroadcastReceiver phoneStateBroadcastReceiver;

public PhoneStateWorkManager(@NonNull Context context, @NonNull WorkerParameters workerParams) {
    super(context, workerParams);
}

@NonNull
@Override
public Result doWork() {
    if (phoneStateBroadcastReceiver == null) {
        phoneStateBroadcastReceiver = new PhoneStateBroadcastReceiver();
    }
    IntentFilter filter = new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
    getApplicationContext().registerReceiver(phoneStateBroadcastReceiver, filter);
    return Result.success();
  }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addAutoStartup();
    Constraints constraints = new Constraints
            .Builder()
            .setRequiredNetworkType(NetworkType.NOT_REQUIRED)
            .build();
    WorkRequest phoneStateRequest = new OneTimeWorkRequest
            .Builder(PhoneStateWorkManager.class)
            .setConstraints(constraints)
            .build();
    WorkManager.getInstance(MainActivity.this).enqueue(phoneStateRequest);
}

private void addAutoStartup() {
    try {
        Intent intent = new Intent();
        String manufacturer = android.os.Build.MANUFACTURER;
        if ("xiaomi".equalsIgnoreCase(manufacturer)) {
            intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));
        } else if ("oppo".equalsIgnoreCase(manufacturer)) {
            intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity"));
        } else if ("vivo".equalsIgnoreCase(manufacturer)) {
            intent.setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity"));
        } else if ("Letv".equalsIgnoreCase(manufacturer)) {
            intent.setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity"));
        } else if ("Honor".equalsIgnoreCase(manufacturer)) {
            intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity"));
        }

        List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        if (list.size() > 0) {
            startActivity(intent);
        }
    } catch (Exception e) {
        Log.e("exc", String.valueOf(e));
    }
   }
 }
Sandip Patel
  • 1,003
  • 1
  • 8
  • 15

1 Answers1

1

There are two ways to get callbacks when the phone state changes: PhoneStateListener and a BroadcastReceiver that listens to android.intent.action.PHONE_STATE.

I would recommend not using PhoneStateListener at all, and go with the BroadcastReceiver approach only, which can be setup via AndroidManifest which allows it to be called even when the app is not currently active.

See this tutorial: https://medium.com/@saishaddai/how-to-know-when-a-device-is-ringing-in-android-57e516d0ab42

Please note, that when an app is killed via "FORCE CLOSE" by the user, all the app's broadcast receiver are immediately put on pause, and the system prevents them from receiving future broadcasts until the user manually reopens that app.

see here

So as long as the user doesn't FORCE CLOSE your app, you should be able to receive phone state changes.

marmor
  • 27,641
  • 11
  • 107
  • 150