I am launching the android setting activity, from an android service.
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.android.settings");
startActivity(LaunchIntent);
I am searching, how I can detect if the setting activity is closed,As I need some callback method.
If there is a callback method to know the settings or any other app like browsers,if launched in this method to know if the launched activity is exit its own.
Since settings and browsers are general code we can't put broadcast code in these activities.
Use startActivityForResult to launch the settings activity like so:
Intent LaunchIntent =
getPackageManager().getLaunchIntentForPackage("com.android.settings");
startActivityForResult(LaunchIntent, 42);
Usually, you would use a specific request code as the second argument, but in this case, you have no control over what the settings Activity could return as a result, and you only want to know when it finishes, so you can essentially make up a request code. It must be greater than 0, however. The docs state this here:
requestCode If >= 0, this code will be returned in onActivityResult() when the activity exits.
Then, you can override the onActivityResult method to handle what happens when the settings activity closes:
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data){
// Do whatever you would like to do
}
If you had used a specific request code when you started the Activity, this is where you would check if the result code exists, but since we aren't expecting any real result, the result code will likely be equal to RESULT_CANCELLED, but that's okay since you at least know that the Activity was cancelled.
Related
I´ve an app (APP1) which should open other app (APP2) and wait for the result. I´m doing it this way.
private fun startBridgeActivity(fileName: String, isProduction: Boolean) {
val intent = Intent(Intent.ACTION_MAIN)
when (isProduction) {
true -> {
intent.component = ComponentName(
"com.myapp",
"com.myapp.view.ui.ItemSelectionActivity"
)
}
else -> {
intent.component = ComponentName(
"com.myapp.dev",
"com.myapp.view.ui.ItemSelectionActivity"
)
}
}
try {
startActivityForResult(intent, REQUEST_CODE)
} catch (e: Exception) {
e.printStackTrace()
Toast.makeText(this#MainActivity, "This activity does not exist", Toast.LENGTH_LONG).show()
}
}
Then APP2 receives this intent and opens itself. The launch method on this APP2 it´s just the standard.
The navigation inside APP2 is as follows:
ReceiverActivity - Step1Activity - Step2Activity - LastActivity
I´ve tried setting the result and finishing LastActivity, but it doens't work. Also tried with finishAffinity and finishAndRemoveTasks but they also didn't work.
Then what I did was calling ReceiverActivity from LastActivity and setting there the result and finishing it. But that leaves me on the homescreen and the result wont get to APP1.
val receiverActivityIntent = Intent(this#LastActivity, ReceiverActivity::class.java)
receiverActivityIntent.putExtra("end", true)
TaskStackBuilder.create(this#ReceiverActivity)
.addParentStack(ReceiverActivity::class.java)
.addNextIntent(receiverActivityIntent)
.startActivities()
finish()
I readed some other SO answers where someone wrote that the Activity from APP1 would be added to the stack of APP2 and that might be why the app goes to the homescreen.
Any help will be appreciated.
Thanks.
Your app launches ItemSelectionActivity using startActivityForResult(). Your app will get the callback onActivityResult() when ItemSelectionActivity finishes. It will receive the results that ItemSelectionActivity sets when it calls setResult().
If ItemSelectionActivity needs to launch other activities before it can get the results to send back to your app, you can do this in a few possible ways:
Use FLAG_ACTIVITY_FORWARD_RESULT
When ItemSelectionActivity launches another Activity, it should set the flag Intent.FLAG_ACTIVITY_FORWARD_RESULT in the Intent and call startActvity() (do NOT call startActivityForResult(). The Activity that is being launched must then call setResult() with the results and that data will be passed back to your app. You are basically "forwarding" the request for a result from one Activity to the next. Since you seem to have several activities to go through before you get a result, you can continue to forward the responsibility from one Activity to the next Activity. The last one in the chain should then call setResult() and those results will be passed back to your app in onActivityResult().
Chain startActivityForResult() calls:
When ItemSelectionActivity launches another Activity, it should call startActvityForResult(). The Activity that is being launched must then call setResult() with the results and that data will be passed back to ItemSelefctionActivity in onActivityResult(). ItemSelectionActivity should then itself call setResult() with the data and finish(). The results will be passed back to your app. Since you seem to have several activities to go through before you get a result, you can continue to chain these calls so that each Activity launches the next Activity using starActivityForResult() and the called Activity needs to pass the results back usingsetResult()`.
Have LastActivity deliver the result to ItemSelectionActivity:
This is the solution that you have already tried to implement. LastActivity returns the result directly to ItemSelectionActivity. However, your implementation is broken. DO NOT USE TaskStackBuilder to accomplish this! TaskStackBuilder has a lot of side effects that destroy the Activity stack within the task. What you want to do instead is this:
val receiverActivityIntent = Intent(this#LastActivity, ReceiverActivity::class.java)
receiverActivityIntent.putExtra("end", true)
// add the results to the Intent
receiverActivityIntent.putExtra("results", results)
// Set the CLEAR_TOP and SINGLE_TOP flags (if necessary) to remove any
// activities that are on the stack between ReceiverActivity and LastActivity
receiverActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(receiverActivityIntent)
// Calling finish() here isn't necessary if you set the Intent flags
finish()
NOTE: My Kotlin syntax may not be 100% correct, but hopefully you get the idea.
With this solution, the results will be delivered to ReceiverActivity in onNewIntent(). You will need to override onNewIntent(), get the results from the passed Intent and then call setResult() with the results to pass them back to your app.
I am trying to develop an android app which supports from 2.3 and above to the latest version.
and it is session based.
Scenario:
My app as a login activity and on successful login it starts the A activity and further activities can be started like A activity->B activity->C activity.
My question is:
when I am in C-activity and if session expires(Session expiry is from the server side),I need to close all the activities in the task and start a new Login activity.
I tried using FLAG_ACTIVITY_CLEAR_TASK (but this flags supports from 3.0).please help me with a solution.
You could create a BroadcastReceiver listening for the "expiration" action, create the class that extends from BroadcastReceiver in your activity, register the broadcast to listen for the "expiration" action and onReceive method finish the activity, that would do the trick...
Remember to properly manage the register/unregister actions of the broadcast so you dont leak registered broadcast by unregistering already destroyed activities...
Hope it Helps.
Regards!
I am doing something similar and what I did was started each activity after the login for a a result. When the expiration happens, just set the activity result to anything you decide and use finish(); It'll look something like this:
Login:
getInfo(){
yourCode;
if(correct)
startActivityForResult(yourIntent);
}
onActivityResult(int requestCode, int resultCode, Intent data){
if(resultCode == 0)
yourCode;
}
Activity A:
expiration(){
setResult(0);
finish();
}
Just set up each activity's expiration method to finish the activity and set the result code so that the activity before it knows that it should be finishing.
i open Third-party software from my program like:
Intent i2 = new Intent();
PackageManager manager = getPackageManager();
i2 = manager.getLaunchIntentForPackage("com.3rd.program");
i2.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(i2);
when this program close i need to do something in my program.
How to identify that program close and return to my program ?
You're not looking for startActivityForResult are you?
https://developer.android.com/reference/android/app/Activity.html#StartingActivities
public void startActivityForResult (Intent intent, int requestCode, Bundle options)
Added in API level 16
Launch an activity for which you would like a result when it finished. When this activity exits, your onActivityResult() method will be called with the given requestCode
How to identify that program close
You don't, any more than when your Web page links to another Web site, that you find out where the user goes after that.
and return to my program
Your activity that called startActivity() will go through normal lifecycle methods (e.g., onResume()) when it returns to the foreground. However, bear in mind that the user can leave the other app and not return to yours, such as by pressing the HOME button.
I am launching a media intent to take a photo. After the user took a picture and gets back to the previous activity the whole application has restarted.
As this doesn't happen all the time, I think my application goes to the background and android kills it when the device has low memory.
Is there any way to keep my application from going to the background?
Thanks!
This is normal behavior in Android, all activities currently not visible on screen (after onStop) can be killed without notice (i.e. onDestory) if the system has low memory.
This usually happens to our app on one of our test devices which has memory issues regardless of our app.
You can usually recreate this behavior when you open the camera via the intent, and then rotate the device (portrait to landscape), this will also kill and re-create your app.
To solve this you need to extend onSaveInstanceState and use the savedInstanceState parameter in your onCreate to pass from your killed instance to your new instance some important information (like "we're in the middle of getting a pic from the camera").
I can think of two possibilities...
It's not killing the activity, but the intent launches a new activity. You can stop this by putting a tag in your manifest.xml as an attribute in the activity tag like this:
<activity
android:name=".nameOfActivity"
android:launchMode="singleTop" />
Make sure that the media intent is under the activity to handle the photo, and not a main/launcher activity.
IMO two options:
Implement onSaveInstanceState/onRestoreInstanceState
or
Make your activity a service.
I faced this issue and got a solution after R&D for it.
Set Target Android 4.0 and then add this line in AndroidManifest.xml of activity:
android:configChanges="screenLayout|uiMode|orientation|screenSize|smallestScreenSize"
It works for me.
When you start media intent use following method instead of startActivity(intent)
startActivityForResult(intent, REQUEST_CODE); //private int REQUEST_CODE = 232
When the started activity finishes, your calling activity will be started. You need to handle this using following function
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
//Perform your task
}
}
The activity started need to override follwoing method
#Override
public void onBackPressed() {
Intent intent = new Intent();
setResult(REQUEST_CODE, intent);
super.onBackPressed();
}
startActivityForResult() is an special way for starting activity for a specific task and get the desired result. The called activity will send the data back.
You can use the method putExtra() & getExtra in intent to send and receive data between two activity.
This will solve your problem hopefully.
If you have doubts comment. And if possible share your code so it can be more clear.
I am facing with a problem related startActivityForResult()
To start SecondActivity from FirstActivity :
Intent intent = new Intent();
intent.setClass(FirstActivity.this, SecondActivity.class);
intent.putExtra("key1", "12345");
startActivityForResult(intent, 0);
And handles result :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//TODO handle here.
}
To send the message to FirstActivity from SecondActivity :
in SecondActivity :
setResult(0);
I can't handle the result on onActivityResult in FirstActivity.
It never works for my application.
My OS is : 1.5
What is wrong here?
startActivityForResult is meant to be used for situations where you want to select a piece of data, or perform some sort of action that your Activity or application cannot do.
For example, you want to pick a contact, so you launch the contacts application, the user chooses the person they want, and you get sent the result. Or you want to take a photo, so you launch the camera application and ask it to send you the photo once it's done. This action is completely separate from your first activity that calls startActivityForResult.
The Activity you're launching will not send you the result until that Activity has completed, i.e. finish() has been called.
So in your case, you need to call this in SecondActivity:
setResult(...);
finish();
before FirstActivity will receive the result in its onActivityResult method. Of course, this means that SecondActivity is now gone and FirstActivity is top of the stack again.
It's not possible to send the result to FirstActivity then close it while keeping SecondActivity still active. In this case you should just handle whatever this 'result' is in SecondActivity, or send it off to a Service you define to do whatever processing it is you want.
I was stuck here for a while. Adding my problem here to make sure that you don't scratch your head as well.
The second parameter of this function has to be 0 or higher.
startActivityForResult(intent, 0); // <- this is OK
I was setting the second parameter to RESULT_OK, which is -1, and my onActivityResult callback was never getting called. So if you get stuck like me, you can also check if your second parameter is correct.
startActivityForResult(intent, RESULT_OK); // <- this is wrong
The above line will fail to call onActivityResult.
I was also stuck on the same problem - but due to a different reason as matangs. Apparently startActivityForResult only works if you have android:launchMode set to standard for main activity (in manifest). Hope it helps someone.
Your code seems ok, but do you stop your second activity ?
Try this in it :
setResult(0);
finish();
If you are doing actions on onPause (like unbinding a service) try to comment it and see if onActivityResult is called (I wasted few good hours on this..)
Thanks to #johndodo (that point to the manifiest) - I find my solution for the same problem.
removing android:noHistory=true at the manifiest" solved this problem for me.