I have two apps each with an accessibility service. The accessibility service of one app sends a broadcast and the accessibility service of the other app receives it.
Here is the service sending the broadcast:
Intent intent = new Intent();
intent.setAction("com.corps.mypackage");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //this is needed if broadcast not being sent from activity
sendBroadcast(intent);
And here is the service that receives the broadcast:
IntentFilter intentFilter = new IntentFilter("com.corps.mypackage");
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Do some things
}
};
registerReceiver(receiver, intentFilter);
The broadcast is not being received. What could be the reason?
As per the Android documentation:
Context-registered receivers receive broadcasts as long as their registering context is valid. For example, if you register within an Activity context, you receive broadcasts as long as the activity is not destroyed. If you register with the Application context, you receive broadcasts as long as the app is running.
Your receiving app's context is likely not valid. Consider using a manifest-declared receiver instead.
Related
I'm using an Android foreground Service to download files and I'm showing the progress of the download to the user in a Notification.
I also have a progress bar in a fragment in the app.
I'm using a broadcast Receiver to communicate the progress of the download happenning in the service to my fragment.
My problem is that the onReceive of my BroadcastReceiver is not trigger above Android 11 bu works perfectly fine on android 10, What had change about broadcast reveiver since Android 11 ?
On my fragment i'm declaring my broadcast receiver :
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if ("SHOW_PROGRESS".equals(intent.getAction())) {
showProgress(intent.getIntExtra("progress", 0));
}
}
};
And registering it in OnCreateView :
IntentFilter filter = new IntentFilter();
filter.addAction("SHOW_PROGRESS");
getContext().registerReceiver(receiver, filter);
From my service I'm calling it :
Intent broadcastIntent = new Intent().setAction("SHOW_PROGRESS").putExtra("progress", downLoadState.getGlobalPercent());
getApplicationContext().sendBroadcast(broadcastIntent);
I have nothing in my manifest since my service don't interacts with device components
Not sure how to get the receiver to work on the activity once the app is forced closed.
What am I missing to get this to work even if the app was forced closed? Any help would be appreciated.
I am getting the BroadcastReceiver service to work, Just not getting anything to pick up on the activity level.
I have my receiver (Service):
public class MyReceiver extends BroadcastReceiver {
public static final String SEND_NOTIFICATION_ACTION = "com.clover.sdk.app.intent.action.APP_NOTIFICATION";
#Override
public void onReceive(Context context, Intent intent) {
Log.i("MyReceiver", "Triggered MyReceiver");
String action = intent.getAction();
Bundle getIntent = intent.getExtras();
if (action.equals(SEND_NOTIFICATION_ACTION)) {
Log.i("MyReceiver Gotten", "Found");
intent = new Intent("broadCastName");
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("orderId", getIntent.getString("payload"));
Log.i("Receiver OrderID", getIntent.getString("payload"));
context.sendBroadcast(intent);
}
}
}
My Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(broadcastReceiver, new IntentFilter("broadCastName"));
}
}
Then my broadcastReceiver in my activity:
// Add this inside your class
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("MyReceiver Gotten 2", "Found");
Bundle b = intent.getExtras();
Log.i("MyReceiver Gotten 3", b.getString("orderId"));
new SpecificOrderAsyncTask(MainActivity.this).execute(b.getString("orderId"));
}
};
Not sure how to get the receiver to work on the activity once the app is forced closed. What am I missing to get this to work even if the app was forced closed?
That's contradictory - you can't get a receiver to work in an Activity that registered it at runtime if that Activity that is hosting the receiver is killed. When you force close, every in the app process - including the Activity and the receiver you registered with it - disappears.
The point of calling registerReceiver is to listen for broadcasts only during a specific time frame or lifecycle.
If you want the receiver to work even when the app is closed, don't register it at runtime - register it in the manifest.
Simple,
Registering service in an activity is temporary, registering service in a manifest will run even after closing the application.
But the broadcast you use is a simple message transfer system, that won't work even after you register in manifest and close the application. You have to create a background service that runs always in background in android system and should awake listening to some events passed.
I have a thread that listens for an inputStream and can send some data with some ouputStream that I got from a Bluetooth socket.
Here is what I'm trying to achieve: I have a MainActvity And Activity B. I need to have both to be capable to receive data from the Thread or send data to the Thread.
I can't just make a new instance of my thread cause it's going to cut the connection.
I'm a new to android and programming so it's very hard to know what I really need.
I tried my best with handlers, Broadcast receiver but had no luck for making it work in Activity B.
Whatever may work for my case. It would be nice having an example of it.
You can use a LocalBroadcastManager in a Service which runs your Thread and let the Activities register receivers on it.
In your Activity:
final LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getApplicationContext());
final IntentFilter filter = new IntentFilter();
filter.addAction("SAMPLE_ACTION");
lbm.registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive() called with: context = [" + context + "], intent = [" + intent + "]");
}
}, filter);
In your Service
final LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getApplicationContext());
final Intent intent = new Intent("SAMPLE_ACTION");
lbm.sendBroadcast(intent);
I want to send a heartbeat from my application to the GCM server, so the connection will stay alive.
How can I do that, and how can I know the URL of my GCM server??
Thanks in advance!!
How to send the heartbeat
This class can sent the proper intents
public class GcmKeepAlive {
protected CountDownTimer timer;
protected Context mContext;
protected Intent gTalkHeartBeatIntent;
protected Intent mcsHeartBeatIntent;
public GcmKeepAlive(Context context) {
mContext = context;
gTalkHeartBeatIntent = new Intent(
"com.google.android.intent.action.GTALK_HEARTBEAT");
mcsHeartBeatIntent = new Intent(
"com.google.android.intent.action.MCS_HEARTBEAT");
}
public void broadcastIntents() {
System.out.println("sending heart beat to keep gcm alive");
mContext.sendBroadcast(gTalkHeartBeatIntent);
mContext.sendBroadcast(mcsHeartBeatIntent);
}
}
if you just want to send the heartbeat you can do the following in an Activity
GcmKeepAlive gcmKeepAlive = new GcmKeepAlive(this);
gcmKeepAlive.broadcastIntents();
I don't think you need to set any additional permissions for this but here are the gcm related permissions I have in my manifest
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name=your_package_name.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="your_package_name.permission.C2D_MESSAGE" />
One way to send the heartbeats on a regular basis
If you want to send them on a regular basis, here is how I am doing that:
public class GcmKeepAliveBroadcastReceiver extends BroadcastReceiver {
private GcmKeepAlive gcmKeepAlive;
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("inside gcm keep alive receiver");
gcmKeepAlive = new GcmKeepAlive(context);
gcmKeepAlive.broadcastIntents();
}
}
I also have a service that has an Dagger injected alarmmanger and pendingintent
#Inject AlarmManager alarmManager;
#Inject PendingIntent gcmKeepAlivePendingIntent;
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, 4*60*1000, gcmKeepAlivePendingIntent);
Here is the section of the Dagger module that provides the alarm manager and pending intent.
There are several ways to have an alarm manager periodically call a method, so assuming you don't use Dagger, you should still be able to pull out the relevant parts. Your question was how to send the heartbeat, not how to use an alarm manager. There are lots of answers to that already so search on that.
#Provides PendingIntent provideGcmKeepAlivePendingIntent() {
System.out.println("pending intent provider");
Intent gcmKeepAliveIntent = new Intent("com.gmail.npnster.first_project.gcmKeepAlive");
return PendingIntent.getBroadcast(mContext, 0, gcmKeepAliveIntent, PendingIntent.FLAG_CANCEL_CURRENT);
}
#Provides AlarmManager provideGcmKeepAliveAlarmManager() {
return (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
}
I have a receiver , that would receive a broadcast in future from an intentservice .
I have initialized the receiver inside my activity .
Sometimes the IntentService takes a while to complete, so by the time it broadcasts its result , the cellphone device is sleeping , so the broadcast is not received.
I have confirmed that even if the cellphone is sleeping , the IntentService runs to completion , only the broadcast receiver doesn't receive anything .
I know that I have to obtain a partial wake lock somehow and somewhere :( . I am in the dark about this .
This is my simple activity , with the only the relevant parts only .
public class NewsActivity extends Activity implements OnDownloadComplete{
...
..
..
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
..
System.out.println("Called"); // Not printed on logcat if the cell is sleeping
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_news);
..
..
..
/*LAUNCHING SERVICE*/
Intent intent = new Intent(context, NewsSyncTask.class);
intent.putExtra( NewsSyncTask.NOTIFICATION, Footer.this.receiverNotificationClass);
context.startService(intent);
}
}
Please help .
BroadcastReceiver should receive broadcast, you can try in this way first wright a separate class and extend it with BroadcastReceiver declare your BroadcastReceiver in menifest.xml under reciver tag, you should set intent filter to it so that it should listen only the broadcast which your intent service dose.
Use AlarmManager with a _WAKEUP-style alarm. Here is a sample project illustrating its use (along with a WakefulIntentService you will want, to make sure the device does not fall back asleep during your network I/O).
Try something like this :
MainActivity:
PowerManager pm = (PowerManager) this
.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
//Start the Service
wl.release();