Hi am trying to use broadcast receiver to trigger some action
Activity A will broadcast action "ACTION_EXIT" and come to Main Activity.
Whenever Main Activity receive the broadcast "ACTION_EXIT" it will close the app.
My code on Activity A (to send broadcast)
Intent broadcastIntent = new Intent(Beacon_MainActivity.this, MainActivity.class);
broadcastIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
broadcastIntent.setAction("com.package.ACTION_EXIT");
sendBroadcast(broadcastIntent);
finish();
Code on Main Activity to receive the broadcast and trigger ACTION_EXIT
private void registerReceiver(){
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.package.ACTION_EXIT");
registerReceiver(myBroadcastReceiver, intentFilter);
}
#Override
public void onResume() {
registerReceiver();
super.onResume();
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(myBroadcastReceiver);
}
BroadcastReceiver myBroadcastReceiver =
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("onReceive", "Logout in progress");
Toast.makeText(MainActivity.this, "what the ****", Toast.LENGTH_SHORT).show();
finish();
}
};
Don't know why it's not working, anyone can help should be much appreciate
(app should be close when Main_Activity receive the broadcast on
resume)
Your MainActivity is paused while ActivityA is running, during which time your Receiver is unregistered, and therefore not getting the broadcast. You can accomplish what you want with result forwarding instead.
In MainActivity, start LoginActivity with the startActivityForResult() method, and override the onActivityResult() method to handle the result.
public static final int REQUEST_CODE = 0;
public static final String EXTRA_EXIT = "exit";
...
Intent actLogin = new Intent(this, LoginActivity.class);
startActivityForResult(actLogin, REQUEST_CODE);
...
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case REQUEST_CODE:
if(data == null) {
return;
}
boolean shouldExit = data.getBooleanExtra(EXTRA_EXIT, false);
if(shouldExit) {
finish();
}
break;
...
}
}
Then, in LoginActivity, add FLAG_ACTIVITY_FORWARD_RESULT to the Intent used to start ActivityA.
Intent actA = new Intent(this, ActivityA.class);
actA.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
startActivity(actA);
finish();
In ActivityA, set a boolean value to indicate whether to exit, add it to a result Intent, set that as the result, and finish the Activity.
boolean shouldExit = ...
Intent result = new Intent();
result.putExtra(MainActivity.EXTRA_EXIT, shouldExit);
setResult(Activity.RESULT_OK, result);
finish();
The result will then be delivered back to MainActivity. This can also be done with only result codes, but I prefer using Intent extras.
Related
I am trying to open new activity and pass some data from service to activity when the foreground service stops even if the app is killed.
My service class tried this thing in onDestroy
#Override
public void onDestroy() {
Intent intent = new Intent("UsedTime");
intent.putExtra("Status", "1500");
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Intent i = new Intent(this, UsedTimeActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setAction(Intent.ACTION_MAIN);
startActivity(i);
}
and here is My UsedTimeActivity
public class UsedTimeActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vpnused_time);
LocalBroadcastManager.getInstance(context).registerReceiver(
mMessageReceiver, new IntentFilter("UsedTime"));
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("Status");
Log.i("TAGUSEDTIME", "onReceive: " + message);
}
};
}
It doesn't work when the app is killed from the background and works fine when the user interacting with the user
Tested Device - Redmi9A (Android 10) & RedmiNote10Pro (Android 12)
I have a class that extends AccessibilityService and when there is a certain event starts an activity.
The problem is that when the activity ends, it should send data back to 'AccessibilityService'. Does anyone have an idea on how to do that?
Example:
public class MyAccessibilityService extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType()==AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED){
Intent intent=new Intent(getApplicationContext(),DialogActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
// String resul=set result When Activity is closed
}
}
Thanks in advance!
AccesibilityService is an inherited class from Service class. So we can refer that question to this:
How to have Android Service communicate with Activity
The easiest way for your question:
1) Call startService() in your Activity's onDestroy() method:
#Override
protected void onDestroy() {
super.onDestroy();
Intent intent = new Intent(getApplicationContext(), MyAccessibilityService.class);
intent.putExtra("data","yourData");
startService(intent);
}
2) Override your MyAccessibilityService's onStartCommand() method:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
String data="";
if(intent.getExtras().containsKey("data"))
data = intent.getStringExtra("data");
return START_STICKY;
}
1)Call startActivity(intent) from your accessibility service on any event.
String msg = "your message";
Intent intent = new Intent(serviceContext, activityClassName.class);
intent.putExtra("message",msg);
startActivity(intent);
2)Now in your activities onCreate(Bundle bundle) method you can get intent.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String msg = intent.getStringExtra("message");
Log.e(LOG_TAG,"Message From Service - "+msg); //Message From Service - your message
}
Using Intent you can pass data from Service to Activity.
I have one Activity(MainActivity) which starts a Service (FirstService) and FirstService starts another Service (SsecondService). The scenario is that MainActivity should wait for result from FirstService, but this will only send a result when it receives something from SecondService.
The problem is that the "onDestroy()" method of FirstService is called and unregisters SecondService before MainActivity gets the final result.
>> I/FirstService: On create...
>> I/FirstService: Handling intent...
>> I/SecondService: On create...
>> I/SecondService: On handling intent..
>> I/FirstService: OnDestroy receiver...
>> I/SecondService: Handling result ...
>> I/SecondService: Publishing result ...
In my Activity:
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_home) {
// Handle the camera action
} else if (id == R.id.nav_camera) {
} else if (id == R.id.nav_pictures) {
startAction();
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
public void startAction {
Log.i("MainActivity", "Starting FirstService");
Intent intent = new Intent(this, FirstService.class);
intent.setAction(FirstService.ACTION_FETCH_PICTURES);
intent.putExtra(FirstService.EXTRA_ACCOUNT, account);
this.startService(intent);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("MainActivity", "Waiting for onReceive");
Bundle bundle = intent.getExtras();
if (bundle != null) {
resultCode = bundle.getInt(FirstService.RESULT);
switch (resultCode) {
case FirstService.RESULT_CODE_OK: [...]
}
[...]
}
}
}
}
};
#Override
protected void onResume() {
super.onResume();
Log.i("MainActivity", "on resume");
registerReceiver(receiver, new IntentFilter(FirstService.NOTIFICATION));
}
#Override
protected void onPause() {
super.onPause();
Log.i("MainActivity", "Unregister receiver...");
unregisterReceiver(receiver);
}
My FirstService:
#Override
public void onCreate() {
super.onCreate();
Log.i("FirstService", "On create...");
registerReceiver(secondReceiver, new IntentFilter(SecondService.NOTIFICATION_SECOND));
}
#Override
protected void onHandleIntent(Intent intent) {
Log.i("SecondService", "Handling intent...");
if (intent != null) {
final String action = intent.getAction();
// .... some more code
Intent intent = new Intent(this, SecondService.class);
intent.setAction(SecondService.ACTION_FETCH_VALIDITY);
intent.putExtra(SecondService.EXTRA_ACCOUNT, accNumber);
this.startService(intent);
}
}
private void publishResults(int result) {
Log.i("FirstService", "Publishing result...");
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(RESULT, result);
sendBroadcast(intent);
}
public BroadcastReceiver secondReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("SecondService", "On receiving result...");
Bundle bundle = intent.getExtras();
if (bundle != null) {
result = bundle.getInt(SecondService.RESULT);
switch (result) {
//[....]
}
publishResults(result);
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
Log.i("SecondService", "OnDestroy receiver...");
unregisterReceiver(secondReceiver);
}
I am struggling with this for hours now and couldn't find a solution. What am I doing wrong and what should I do to make it work? Any ideas are well welcomed.
Cheers!
Basically, you have two options:
Use a static BroadcastReceiver
You can work with a standalone BroadcastReceiver. It has to be registered in the application Manifest. Whenever your SecondService wants to publish something it broadcasts the results just like before. The receiver could then start another Service to process the results.
See also the documentation
If you read the link you'll find out that there are disadvantages to using a static BroadcastReceiver. So why don't you just skip the receiver and start some (third?) Service directly from SecondService ?
Which brings us to the second option:
Implement the first Service as "normal" Service
Right now, FirstService is extending IntentService.
If FirstService was implemented as a started Service then you could make sure it remains alive as long as needed by returning START_STICKY from Service.onStartCommand(). You'd continue using a dynamic BroadcastReceiver or even access the Service directly via onStartcommand(). And as soon as it is finished your Service would unregister the receiver and call stopSelf().
The advantage of an IntentService is that it does not do its work on the UI thread. But a started Service can use AsyncTask, so it can avoid freezing the UI just as well.
You should not use IntentService. If you look at the documentation of IntentService, service starts and do its work in onHandleIntent and then finishes. It does not wait for anything. That's why FirstService is being destroyed because it has finished its work. Instead, use the Simple Service and in handler thread do your work. This is the case your service will continue to run.
I have 1 activity that I would like to start at different times with different variables from a Broadcast Receiver.
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase("tv.abcd.v4.ORIGINAL_VIDEO_SCENE")){
channelName = intent.getExtras().getString("com.abcd.Channel");
JSONObject json = new JSONObject(intent.getExtras().getString("com.abcd.Data"));
String incomingScene = json.getString("url");
scene.putExtra("channel", channelName);
scene.putExtra("url", incomingScene);
scene.addFlags(Intent.FLAG_FROM_BACKGROUND);
scene.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
scene.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(scene);
}
I have the code to start the activity via Intent and in the activity receiver the extras to make data appear.
Intent intent = getIntent();
sceneUrl = intent.getStringExtra("url");
Log.d("Image.incomingscene.url",sceneUrl);
channelName = intent.getStringExtra("channel");
Log.d("Image.incomingSceneAvatar",networkAvatar);
image = (ImageView)findViewById(R.id.imageView1);
image.setScaleType(ScaleType.FIT_CENTER);
progressBar = (ProgressBar)findViewById(R.id.progressBar1);
Picasso.with(this).load(sceneUrl).skipMemoryCache().fit().into(image, new EmptyCallback() {
});
Now after that I want to start the same activity again from the Broadcast Reciever with different data. So i want the previous activity to get out the way and allow this new instance to start up.
How to accomplish this feat?
register another broadcast receiver from the activity. Then, when you want to kill it, send a broadcast message from the broadcast receiver that you mentioned .
In your broadcastReceiver do something like the following :
public static final String CLOSE_Activity= "com.mypackage.closeactivity";
and in yopr OnReceive method do like the following :
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("HIT OUTGOING");
Intent i = new Intent();
i.setAction(CLOSE_Activity);
context.sendBroadcast(i);
}
then in your activity craete a receviver and register it in the onResume method and unregeister it in the onPause method , like the following :
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(RECEIVER_Class.CLOSE_Activity)) {
finish();
}
}
}
activity onResume method :
#Override
public void onResume() {
registerReceiver(broadcastReceiver, new IntentFilter(RECEIVER_Class.CLOSE_Activity));
}
activity onPause method :
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
Please give me some feedback
Hope that helps .
I'm trying to start an IntentService from a fragment tab but i have no responce. the code from my fragment is below:
private Intent prepareIntent(boolean isSending) {
Intent localIntent = new Intent(getActivity(), StartIActivity.class);
Log.d(THIS_FILE, "StartIActivity");
localIntent.putExtra("incoming", isSending);
localIntent.putExtra("remote_contact", setValidNumber(callUri));
localIntent.putExtra("acc_id", this.accId);
return localIntent;
}
private void startIAService(boolean bool) {
Log.d(THIS_FILE, "Start Service");
Context ctx = (Context) myFragment.this.getActivity();
ctx.startService(prepareIntent(bool));
return;
}
and my intent serviceclass is :
public class StartIActivity extends IntentService {
public StartIActivity() {
super("StartIActivity");
}
protected void onHandleIntent(Intent it) {
Intent intent = new Intent(it);
intent.setClass(this, Activity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Log.d("IActivity", "Start Activity");
}
}
When run startIAservice the prepereIntent is run but it can't start the service. I need to use IntentService because i want to execute one task at a time but i can't understand how.
Any help here and what is the best code implemenattion to do this?
Declare service in manifest.xml