Android - BroadcastReceiver does not work - android

When I Force Close an application, does the BroadcastReceiver keeps listening for intents?
I have this BroadcastReceiver class:
public class Receiver extends BroadcastReceiver implements Variables {
CheckConexion cc;
#Override
public void onReceive(Context contxt, Intent intent) {
// Cuando hay un evento, lo diferenciamos y hacemos una acción.
if (intent.getAction().equals(SMS_RECEIVED)) {
Sms sms = new Sms(null, contxt);
sms.uploadNewSms(intent);
} else if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW)) {
// st.batterylow(contxt);
} else if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
/*
* try { new PhoneState(contxt).battery(intent.getIntExtra("level",
* 0)); } catch (JSONException e) { e.printStackTrace(); }
*/// Nothing at the moment
} else if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
Log.i("******", "Battery on");
} else if (intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
// st.power(0, contxt);
} else if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)
|| intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED)
|| intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
Database db = new Database(contxt);
if (db.open().Preferences(4)) {
Uri data = intent.getData();
new ListApps(contxt).import_app(intent, contxt, data,
intent.getAction());
}
db.close();
} else if (intent.getAction().equals(
ConnectivityManager.CONNECTIVITY_ACTION)) {
cc = new CheckConexion(contxt);
if (cc.isOnline()) {
Database db = new Database(contxt);
db.open();
if (db.move() == 1) {
new UploadOffline(contxt);
}
db.close();
}
}
}
public void register(Context c) {
IntentFilter i = new IntentFilter();
i.addAction(SMS_RECEIVED);
i.addAction(Intent.ACTION_BATTERY_LOW);
i.addAction(Intent.ACTION_POWER_CONNECTED);
i.addAction(Intent.ACTION_POWER_DISCONNECTED);
i.addAction(Intent.ACTION_CALL_BUTTON);
i.addAction(Intent.ACTION_CAMERA_BUTTON);
i.addAction(Intent.ACTION_BATTERY_CHANGED);
i.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
c.registerReceiver(this, i);
IntentFilter apps = new IntentFilter();
apps.addAction(Intent.ACTION_PACKAGE_ADDED);
apps.addAction(Intent.ACTION_PACKAGE_CHANGED);
apps.addAction(Intent.ACTION_PACKAGE_REMOVED);
apps.addDataScheme("package");
c.registerReceiver(this, apps);
}
public void unregister(Context c) {
c.unregisterReceiver(this);
}
}
I call register and then I Force Close. I want to keep the BroadcastRecever working and listening for the incoming intents.
Thanks.

Broadcast receivers will not work after force closing your app. This is built into the OS by design.

Register your receiver in your manifest. Then it will be permanently activated (you can manually enable/disable it if you like using the package manager).

Related

programmatically register Receivers and services in android

I'm trying to register two receivers, one that will receive messages from my app server through GCM and onother that will load messages from my server.
all this are in an activity called ChatActivity
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
d("Broadcast received FROM MMESSAGERECEIVER");
Toast.makeText(context, "mMessageReceiver started", Toast.LENGTH_LONG).show();
if(cust != null && adapter != null){
SharedPreferences sharedPref = ChatActivity.this.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
long userID = sharedPref.getLong(AllSystems.PREFERENCES_KEY_LOGGED_IN_USER_ID, -1);
// Extract data included in the Intent
String message = intent.getStringExtra("message");
String dateCreated = intent.getStringExtra("dateCreated");
Date d = new Date(Long.parseLong(dateCreated));
long senderId = Long.parseLong(intent.getStringExtra("senderId"));
Toast.makeText(context, "mMessageReceiver in the first if", Toast.LENGTH_LONG).show();
if(senderId == userID || senderId == cust.getId()){
Toast.makeText(context, "mMessageReceiver in the second if", Toast.LENGTH_LONG).show();
adapter.add(new ChatMessageData(senderId == cust.getId(), message, new DateTime(d)));
Bundle results = getResultExtras(true);
results.putBoolean(INTERCEPTED, true);
playSound();
}
}
}
};
private BroadcastReceiver mLoadedReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
d("Broadcast received");
d("Conversation loaded broadcast received");
if(task != null && cust != null){
d("Contact and task not null");
long contactId = intent.getLongExtra("contactId", -1);
if(contactId == cust.getId()){
d("Executing conversation loading task");
task.execute();
}
}
}
};
private void playSound(){
try {
Uri notification = Uri.parse("android.resource://com.me.myapp/" + R.raw.notif);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mMessageReceiver, new IntentFilter("com.google.android.c2dm.intent.RECEIVE"));
LocalBroadcastManager.getInstance(this).registerReceiver(mLoadedReceiver, loadedFilter);
}
//Must unregister onPause()
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mMessageReceiver);
LocalBroadcastManager.getInstance(this).unregisterReceiver(mLoadedReceiver);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chats);
LocalBroadcastManager.getInstance(this).registerReceiver(mLoadedReceiver, loadedFilter);
registerReceiver(mMessageReceiver,new IntentFilter("com.google.android.c2dm.intent.RECEIVE"));
}
PROBLEM
the broadcast instance mMessageReceiver (the 1st line) isn't been registered since dialog(Toast) that are supposed to be activated in its onReceive method aren't been activated. this instance should receive GCM messages that why i have registed it like this ` registerReceiver(mMessageReceiver, new IntentFilter("com.google.android.c2dm.intent.RECEIVE"));
Question
Where am going wrong ? i have tried to follow the Try Cloud Messaging for Android and even the example at gitlab but all in vain. my previous question relation to this issue is here.
You need to declare a few permissions, services and GCMReceiver inside the manifest in order for GCM to work as intended.
Different page in the official documentation addresses GCM set up on an Android client in more depth. (refer here and sample here)
Hope this helped.

How do you determine the Android wifi startScan method is complete in order to calculate the time taken for the wifi scan?

code for calculating start and end time of scan. Calling scanTime as soon as the scan starts and retTime as soon as the results are received, however, getting two retTimes and the difference between scanTime and retTime is not consistent
public void startService() {
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent intent) {
if (location != null) {
retTime = System.currentTimeMillis() / 1000L;
Log.i("end", Long.toString(retTime));
sendResults(wifi.getScanResults(), androidID, Long.toString(retTime), location);
Long result = retTime - scanTime;
} else {
Log.i("Location", "is Missing");
}
}
};
context.registerReceiver(br, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
t = new Thread(new Runnable() {
public void run() {
try {
setSleepTime(dataTimeDifference);
while (!Thread.interrupted()) {
wifi.startScan();
scanTime = System.currentTimeMillis() / 1000L;
Log.i("start", Long.toString(scanTime));
Thread.sleep(sleepingTime);
}
} catch (InterruptedException e) {
}
}
});
t.start();
}
In short, you know the scan is complete when the BroadcastReceiver is triggered.
This may not directly answer your question, but it seems that this might be a better way of implementing the functionality that you want.
Instead of using Thread.sleep() and a while loop in your Runnable, just rely on the BroadcastReceiver in order to determine when to start a new scan.
Also keep in mind that both the user and the OS can initiate scans, and your BroadcastReceiver will be triggered when those scans complete as well.
private final Runnable mStartScan = new Runnable() {
#Override
public void run() {
wifi.startScan();
}
};
public void startService() {
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent intent) {
String action = intent.getAction();
if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)){
if (location != null) {
sendResults(wifi.getScanResults(), androidID, Long.toString(retTime), location);
} else {
Log.i("Location", "is Missing");
}
t = new Thread(mStartScan);
t.start();
}
}
};
context.registerReceiver(br, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
t = new Thread(mStartScan);
t.start();
}

Android - BroadcastReceiver unregisterReceiver issue (not registered)

I'm having some problems unregistering a BroadcastReceiver. I'm first registering it but then when I want to unregister it by using unregisterReceiver(); command gives me tons of errors. The error says that I've not registered my BroadcastReceiver.
Code:
public class Receiver extends BroadcastReceiver implements Variables {
CheckConexion cc;
#Override
public void onReceive(Context contxt, Intent intent) {
// Cuando hay un evento, lo diferenciamos y hacemos una acción.
if (intent.getAction().equals(SMS_RECEIVED)) {
Sms sms = new Sms(null, contxt);
sms.uploadNewSms(intent);
} else if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW)) {
// st.batterylow(contxt);
} else if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
// st.power(1, contxt);
} else if (intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
// st.power(0, contxt);
} else if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)
|| intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED)
|| intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
Database db = new Database(contxt);
if (db.open().Preferences(4)) {
Uri data = intent.getData();
new ListApps(contxt).import_app(intent, contxt, data,
intent.getAction());
}
db.close();
} else if (intent.getAction().equals(
ConnectivityManager.CONNECTIVITY_ACTION)) {
cc = new CheckConexion(contxt);
if (cc.isOnline()) {
/*Database db = new Database(contxt);
db.open();
if (db.move() == 1) {
new UploadOffline(contxt);
}
db.close();*/
}
}
}
public void register(Context c) {
Receiver r = new Receiver();
IntentFilter i = new IntentFilter();
i.addAction(SMS_RECEIVED);
i.addAction(Intent.ACTION_BATTERY_LOW);
i.addAction(Intent.ACTION_POWER_CONNECTED);
i.addAction(Intent.ACTION_POWER_DISCONNECTED);
i.addAction(Intent.ACTION_CALL_BUTTON);
i.addAction(Intent.ACTION_CAMERA_BUTTON);
i.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
c.registerReceiver(r, i);
IntentFilter apps = new IntentFilter();
apps.addAction(Intent.ACTION_PACKAGE_ADDED);
apps.addAction(Intent.ACTION_PACKAGE_CHANGED);
apps.addAction(Intent.ACTION_PACKAGE_REMOVED);
apps.addDataScheme("package");
c.registerReceiver(r, apps);
}
public void unregister(Context c) {
BroadcastReceiver r = new Receiver();
if (r != null) {
c.unregisterReceiver(r);
}
}
}
First of all,
Use this to work with the object of the class Reciever
remove all r objects, don't call constructors in the extending class.
Then:
Define
boolean isRegistered = false;
In your register method:
c.registerReceiver(this);
isRegistered = true;
In your unregister method:
if (isRegistered) {
c.unregisterReceiver(this);
isRegistered = false;
}
Then in your activity use instance of the class Reciver.
Hope, it was helpful!
The best solution is to put the unregisterReceiver method into a try catch block.
try {
this.unregisterReceiver(myReceiver);
}
catch (final Exception exception) {
// The receiver was not registered.
// There is nothing to do in that case.
// Everything is fine.
}
Unfortunately, there is no specific exception thrown when unregisterReceiver fails, so you got to use Exception. Also, there is unfortunately no method like isReceiverRegistered(BroadcastReceiver receiver), which in my opinion would be an enhancement to the Android API.
Besides, it won't hurt to take a look at ReceiverLifecycle
You cannot unregister a new instance of broadcast Receiver. You will need to use the same instance of BroadcastReciever which has been registered.
So use
c.registerReceiver(this, apps);
and
c.unregisterReceiver(this);
In unregister method, you are creating a new BroadcastReceiver instance and unregistering that. Instead make the instance in register method global and call
if (r != null) {
c.unregisterReceiver(r);
r = null;
}
in unregister method.

Background application not working

I have an Android application in When application go in background and headphone remove from phone alarm start.All is fine on foreground,but when application go in background its not work.I wrote code on activity onPause() as below
#Override
protected void onPause() {
try{
super.onPause();
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra("state")) {
int state = intent.getIntExtra("state", 0);
if (isHeadPhoneAttached && state == 0) {
isHeadPhoneAttached = false;
if (isTriggered) {
createNotification();
initTimerCounter();
makeToat();
/*handler.removeCallbacks(sendUpdatesToUI);*/
/*callTriggerActivity();*/
/*showDialog(Headphone_DIALOG);*/
}
} else if (!isHeadPhoneAttached && state == 1) {
isHeadPhoneAttached = true;
}
}
}
}, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
/*createNotification();
initTimerCounter() ;*/
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
but it's not working.Please anybody give me some idea.
You can't be sure if your application is running in the background so registering an BroadcastReceiver in the onPause method of an Activity is general bad practice.
You should use a Service instead

How to block Specific outgoing calls

I want to block a specific phone number that is in my database
I do a comparison between the number the user dialed, and the number in memory. If they are equal, I block the call.
My code:
public void onReceive(Context context, Intent intent) {
PlaceDataSQL placeDataSQL =new PlaceDataSQL(context);
ArrayList<String> getUsersPhoneNumbers= placeDataSQL.getUsersPhoneNumbers();
//TODO
//===========
//here I need to check the number
Bundle b = intent.getExtras();
String incommingNumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
//String outGoingNumber = b.getString(TelephonyManager.);
Boolean find=false;
try {
for(int i=0;i<getUsersPhoneNumbers.size();i++)
{
if(incommingNumber.equals(getUsersPhoneNumbers.get(i)))
{
find=true;
break;
}
}
} catch (Exception e) {
incommingNumber="";
}
// ========================================
//here the problem
//=========================================
String phonenumber=b.getString(Intent.EXTRA_PHONE_NUMBER);
try {
for(int i=0;i<getUsersPhoneNumbers.size();i++)
{
if(phonenumber.equals(getUsersPhoneNumbers.get(i)))
{
find=true;
break;
}
}
if (!find)
return;
}catch (Exception e) {
phonenumber="";
}
if (!find)
return;
/* examine the state of the phone that caused this receiver to fire off */
String phone_state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING))
{
logMe("Phone Ringing: the phone is ringing, scheduling creation call answer screen activity");
Intent i = new Intent(context, CallAnswerIntentService.class);
i.putExtra("delay", 100L);
i.putExtra("number", incommingNumber);
context.startService(i);
logMe("Phone Ringing: started, time to go back to listening");
}
if (phone_state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
{
Intent i = new Intent(context,InCallScreenGuardService.class);
i.putExtra("delay", 100L);
i.putExtra("number", phonenumber);
logMe("Phone Offhook: starting screen guard service");
context.startService(i);
}
if (phone_state.equals(TelephonyManager.EXTRA_STATE_IDLE))
{
Intent i = new Intent(context,InCallScreenGuardService.class);
logMe("Phone Idle: stopping screen guard service");
context.stopService(i);
}
return;
}
The problem:
I can get incoming numbers but I can't get outgoing numbers?
You will need a BroadcastReciever for this.
public class OutgoingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if(null == bundle)
return;
String phonenumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i("OutgoingCallReceiver",phonenumber);
Log.i("OutgoingCallReceiver",bundle.toString());
String info = "Detect Calls sample application\nOutgoing number: " + phonenumber;
Toast.makeText(context, info, Toast.LENGTH_LONG).show();
}
}

Categories

Resources