1

I have created a BroadCastReceiver for SMS and I want it to work only when the application is running (either in forgeground or background) . The current code im using is :

public class BroadCastReceiver extends BroadcastReceiver 
{

    public void onReceive(Context context, Intent intent)
    {

        ActivityManager am = (ActivityManager) context
                .getSystemService(Activity.ACTIVITY_SERVICE);
        String packageName = am.getRunningTasks(1).get(0).topActivity
                .getPackageName();

    if(packageName.contains("com.example.sms") )
     {
        abortBroadcast();

     }else
     {

      }

     }
    }

But the problem is this code only works in foreground , so when the user hits back button or home button the application will work in background but the BroadCastReceiver will not work . So is there's any method to solve this issue ?? &Thanks in advance

AlphaCode
  • 439
  • 1
  • 3
  • 17
  • getRunningTasks is deprecated since Lollipop. It'll only return your own application's tasks. Also it was never intended to be used in production code to begin with. – DeeV Jan 07 '15 at 16:27
  • I know that but I haven't found any alternatives yet . I'm currently trying to use RunningAppProcessInfo . Which is also shall only be used for debugging , but I think I have no option in this case. – AlphaCode Jan 07 '15 at 16:33
  • So wait. I don't think the code you posted is consistent with what you said in the first sentence. Do you want the broadcast to only run when your app is running or when another app is running? – DeeV Jan 07 '15 at 18:21
  • Only when my APP is running . – AlphaCode Jan 07 '15 at 18:54

2 Answers2

1

If you only want to run a broadcast when your app is running, then you only have to register the broadcast when the app is running.

public class BroadCastReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        /** SMS received while app was running. Do whatever */
    }
}

public class MainActivity extends Activity {

  private BroadCastReceiver mBroadcastReceiver = new BroadCastReceiver();

  @Override
  public void onStart() {
    super.onStart();
    registerReceiver(myBroadcastReciever, new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
  }

  @Override
  public void onStop() {
    super.onStop();
    unregisterReceiver(myBroadcastReceiver);
  }
}

The broadcast receiver will only receive broadcasts when your app is running. No need to check running processes. You can move them to onResume()/onPause() if you only want to receive broadcasts when the app is visible to users. You can (un)register in onCreate()/onDestroy() if you want to start receiving broadcasts as soon as possible. You can do the same thing in a Service with its respective callbacks.

DeeV
  • 35,865
  • 9
  • 108
  • 95
  • Thanks for this answer . In my code I don't invoke the BroadCastReceiver in the MainActivity nor I pass intent extras . So Actually my MainActivity class file doesn't have anything to do with the BroadCastReceiver class , and when I launch the application the receiver starts automatically.So in my case do you think I can make it only work when invoked by MainActivity class ?? By the way , here's my code for the entire application(the updated BroadCastReceiver is the answer of the question) : – AlphaCode Jan 07 '15 at 19:43
  • http://stackoverflow.com/questions/27819477/android-block-incoming-sms-using-broadcastreceiver/27819623?noredirect=1#comment44046079_27819623 – AlphaCode Jan 07 '15 at 19:43
  • I apologize for those stupid questions ,, I'm still new to the world of java – AlphaCode Jan 07 '15 at 19:44
  • Yes. There's nothing particularly special about a BroadcastReceiver. It's a class. You import the class in your MainActivity, allocate a reference, then give the reference to the Android system via "registerReceiver". The system needs to know of your receiver's existence to send a broadcast to. Registering it in the Manifest will ensure that it *always* gets called. Registering it in your Activity will ensure that it only gets called when your app is running. – DeeV Jan 07 '15 at 19:47
  • You don't have to register receivers in the Manifest. This is only needed if you want the receiver to receive broadcasts whenever they're sent regardless of whether or not your app is running. This is not what you're looking for in this case. – DeeV Jan 07 '15 at 19:49
  • Ah so I have to remove the receiver from Manifest and invoke it from MainActivity . What should I particularly remove & add to the code (in Manifiest & MainActivity)?? Can you please answer on the link above as you will have the code in front of your eyes . Again I apologize for this , that's because I'm still new to the world of Java . – AlphaCode Jan 07 '15 at 19:51
  • I edited the code here to match your class names. Just remove the from your Manifest. – DeeV Jan 07 '15 at 20:03
  • That's very kind of you ! Thanks very very much . I'll try it tomorrow and I'll respond how things will go on . Thanks very much again that's really life saving :) – AlphaCode Jan 07 '15 at 23:20
  • This code is having the same problem ; The broadCastReceiver only works when the application is visible to user (foreground) while when it's not visible to the user (background) it doesn't . That's I believe due to "OnStop" . I've replaced "onStop" with "onDestroy" and it worked exactly as I want . Thanks very much again and sorry for taking much of your time – AlphaCode Jan 08 '15 at 00:02
0

You can run ps and check output for your package name

try {
    Process process = Runtime.getRuntime().exec("ps | grep \""+myPackageName+"\"");

    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    int bytes;
    char[] buffer = new char[4096];
    StringBuffer output = new StringBuffer();
    while ((bytes = reader.read(buffer)) > 0) {
        output.append(buffer, 0, bytes);
    }
    reader.close();
    process.waitFor();

    return output.toString().length()>1;
} catch (Exception e) {
}
Zielony
  • 16,239
  • 6
  • 34
  • 39