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
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)
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.
Here is the code for back button. I want to kill other activities by back button but its not working in one activity, but I have other activities and without one activity its working fine. Please help me out.
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),
SomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
Might be this code will help you:
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), SomeActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
}
You have to set Flags according to API level :
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
if(Build.VERSION.SDK_INT >= 11)
{
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_CLEAR_TASK);
}
else
{
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
startActivity(intent);
Hope it helps ツ
You can set android:noHistory="true" in activities tag in AndroidManifest.xml which you don't want to save in stack.
Try to define one local broadcast receiver on top most parent activity or base activity :
private final class KillReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
}
Intialize and register broadcast receiver in onCreate() and unregister in onDestroy() on top most parent activity or base activity :
private KillReceiver clearActivityStack;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
clearActivityStack = new KillReceiver();
registerReceiver(clearActivityStack, IntentFilter.create("clearStackActivity", "text/plain"));
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(clearActivityStack);
}
Now call broadcast receiver when wan to clear all previous activity :
public void onClick(View v) {
Intent clearIntent = new Intent("clearStackActivity");
clearIntent.setType("text/plain");
sendBroadcast(clearIntent);
Intent intent = new Intent(getApplicationContext(),SomeActivity.class);
startActivity(intent);
}
I have a question, how to finish activity in brodcastreceiver onCallEnded (SIP) . There is a brodcastreceiver like this:
public class IncomingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
...
#Override
public void onCallEnded(SipAudioCall call) {
// IncomingCallActivity.finish();
}
};
Main mainActivity = (Main) context;
incomingCall = mainActivity.manager.takeAudioCall(intent, listener);
mainActivity.call = incomingCall;
Intent i = new Intent(context, IncomingCallActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Then start new activity to answer or reject call, but how to close it when call is finished? Cant use IncomingCallActivity.finish() in onCallEnded.
First why can you add the listener in IncomingCallActivity itself. I dont think that will make any difference.
Second for your solution,
start your activity with a FLAG_ACTIVITY_SINGLE_TOP so that you receive the new Intent in onNewIntent(Intent intent) of the activity.
Then onCallEnded start the activity once again.
Intent i = new Intent(context, IncomingCallActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
i.putExtra("Close", true); // an extra which says to finish the activity.
context.startActivity(i);
Now in onNewIntent(Intent intent)
if(intent.getBooleanExtra("Close", false))
finish();
You can do it like this:
#Override
public void onCallEnded(SipAudioCall call) {
// IncomingCallActivity.finish();
//Here set any value like an int
intToClose = 1;
}
then in your activity check for the intToClose, if its 1 then just call fnish();
UPDATE: This code is from my mind, so it can have some errors. Add this to your current activity, or something like this:
scheduler = Executors.newSingleThreadScheduledExecutor ( );
scheduler.scheduleAtFixedRate ( new Runnable ( ) {
public void run ( )
{
runOnUiThread ( new Runnable ( ) {
public void run ( ) {
closeInt = IncomingCallReceiver.intToClose;
if ( closeInt == 1 ) {
scheduler.shutdown ( );
finish ( );
}
}
} );
}
}, 750, 750, TimeUnit.MILLISECONDS );
I used this code my problem solved.
Try this your problem will be solve. there is no endcall in broadcast so finish() on Idle state.
Happy coding!!
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
((Activity)context).finish();
}
I'm new to Android and I'm stuck on a conception problem.
I have an application with several activities, some of those activities are critical and require the user to be logged in a webApp.
When the user clicks a button to reach one of those critical activities, I call a background Service which ask if the user is still connected to the webApp (not timeout). If the user is logged in, the activity is started, otherwise a dialog pops up and ask for username and password. The problem is that there is several protected activities, and I want to use the same service to do the verification. The way I do it for the moment works but it's kind of kludgy.
public class A_Activity extends Activity {
Context context;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = getApplicationContext();
setButtonClickListener();
}
private void setButtonClickListener() {
button_1 = (Button)findViewById(R.id.button1);
button_1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intentCall = new Intent(context,com.them.cp.ConnexionManagerService.class);
intentCall.putExtra("WHO_IS_CALLED","FIRST_ACTIVITY");
context.startService(intentCall);
}
});
button_2 = (Button)findViewById(R.id.button2);
button_2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intentCall = new Intent(context,com.them.cp.ConnexionManagerService.class);
intentCall.putExtra("WHO_IS_CALLED","SECOND_ACTIVITY");
context.startService(intentCall);
}
});
}
}
And my service
public class ConnexionManagerService extends Service{
public class IsConnectedAsync extends AsyncTask<String , Void, Void>{
protected Void doInBackground(String... whoIsCalled) {
String redirectedURL = getRedirectedURL();
if(redirectedURL.equalsIgnoreCase(IF_NOT_CONNECTED_URL)){
if(whoIsCalled[0].equalsIgnoreCase("FIRST_ACTIVITY")){
Intent trueIntent = new Intent(getBaseContext(), FirstActivity.class);
trueIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(trueIntent);
}
else if(whoIsCalled[0].equalsIgnoreCase("SECOND_ACTIVITY")){
Intent trueIntent = new Intent(getBaseContext(), SecondActivity.class);
trueIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(trueIntent);
}
}
else{
Intent falseIntent = new Intent(getBaseContext(), PopUpLoginActivity.class);
falseIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(falseIntent);
}
}
return null;
}
}
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d("service onCreate", "onCreate");
}
public int onStartCommand(Intent intent, int flags, int startId){
String whoIsCalled = intent.getStringExtra("WHO_IS_CALLED");
new IsConnectedAsync().execute(whoIsCalled);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
with my little knowledge I wish i could just send an intent, but it seems that it's not possible as it's not the UI thread.
My question is: What can I do to make this service more generic ?
I want to use the same service to do the verification.
If you don't destroy the service it will be the same service object. If an activity which started your service finishes or stops the service it could be destroyed if it was the unique activity that started the service. If you want to ensure that the service reminds on background start it on you application class (extending Application) and in each activity you need. When an activity stops the service or finishes the service will not be destroyed because your application class is still connected.
EDIT:
To avoid write putExtra again and again:
public class StartOrder1 extends Intent {
public StartOrder(Context ctx, String activity_name){
super(ctx, ServiceName.class);
if(activity_name != null)
super.putExtra("WHO", activity_name);
else
super.putExtra("WHO", "UNKNOWN");
}
public String getWho(){
reurn.getIntExtra("WHO");
}
}
To start it:
this.startService(new StartOrder1(this, "My activity name"));
The best solution:
public class StartOrder2 extends Intent {
public StartOrder(Activity a){
super(a, ServiceName.class);
super.putExtra("WHO", a.toString());
}
public String getWho(){
reurn.getIntExtra("WHO");
}
}
And you can override toString method in each Activity passing the activity name, class name, whatever you want. Then when you start an intent:
this.startService(new StartOrder2(this));
Or extends Activity with this utility:
public class EnhancedActivity extends Activity{
protected startMyService(String name){
Intent i = new Intent(this, MyService.class);
i.putExtra("who", name);
startService(i);
}
}
And call it on your final activity
[...]
super.startMyService("activity_name");
[...]