onactivityresult from non activity - android

I am working on an Android library and I am having an issue.
The main application calls an initialises a library. One of the parameters is the calling activity. This activity is then used as the context when needed.
When a certain event is triggered within the main application calls a method, which then calls a new activity. At the moment, the library class uses the activity that was passed into the initalise method to create the new activity (note that the passed in activity in the initialise may not be the activity that triggered the library as it only initialised once.
The activity that is started in the library, sets a result and finishes the activity. However, the onactivity result in the library class is not called (I presume because its not an activity and the result would go back to the activity that was passed in to the initialise.
What I need to be able to do is have the library class file to get the returned result from the libraries activity.

Android AccountManager does something like this. A request to AccountManager will invoke an authenticator plugin which can have an activity to get the user's username/password, etc.
AccountManager just uses a special Future called AccountManagerFuture to return the results asynchronously, and I would recommend you use a Future implementation as well to return your results asynchronously. Then you don't need to worry about how to make the two activities connect through the library.

Related

Execute code on every activity launch and result

In the past I used "startActivityForResult" and "onActivityResult". Those methods are now deprecated. Therefore I want to use the modern alternative "registerForActivityResult".
Unfortunately, however, I cannot figure out a way to achieve the old functionality with this new model. I used to override "startActivityForResult" and "onActivityResult" of "AppCompatActivity" to run specific code before any activity was started and whenever any activity finished with a result. This was very convenient, since I didn't have to write the code for every activity launch.
As I see it now, I register the activity for a result and pass a callback to get a launcher that I can use to launch the activity later. This part I could solve by creating a function to use the launcher that always executes certain code. But there's a problem with the callback. As I see it, I would have to write this specific code into the callback of every callback I write for any activity launch.
Am I correct or am I missing something?
Theres a couple ways to do this:
1)Put the common code in its own function and just call that function in every callback. Reduces the code needed to be written to 1 line
2)Write a callback class GenericCallback. Then write your specific callback MySpecificCallback extends GenericCallback. Put the common code in the GenericCallback class and you just have to call super in the specific callback. Reduces the code to just calling super.callbackFunction, but means you can't use a lambda- you have to use a named or anonymous class. This is probably more of a Java approach though
3)Create a wrapper function for registerForActivityResult that takes a callback, and calls the real registerForActivityResult who's callback calls the common code and your callback Example:
fun registerWrapper(callback: ()->Unit) {
registerForActivityResult(() ->{
doCommonCode()
callback()
}
}

Send additional data back to calling activity when a library calls setResult

I'm using this library based on Zxing to scan several barcodes and I need to pass which I'm currently scanning to the ScannerActivity and back to the calling activity.
Currently I call the ScannerActivity like this:
new IntentIntegrator(this)
.setOrientationLocked(false)
.addExtra(SCAN_TYPE_EXTRA, scanType.getValue())
.setCaptureActivity(ScannerActivity.class).initiateScan();
Then I'm able to get the SCAN_TYPE_EXTRA value like this:
this.getIntent().getIntExtra(MainActivity.SCAN_TYPE_EXTRA, 1)
I need to send this value back to the calling activity (MainActivity), however the zxing-android-embedded library calls the setResult and finish methods on its own.
How can I add my data to the library data when the ScannerActivity is being finished?

Android: Access method in an activity from another activity

My launch activity starts up another activity whose launch is set to single instance. In this 2nd activity, I have a public method. I then start up a 3rd activity and that activity needs to access the public method in the 2nd activity. I don't want to use startActivity and pass it extras because I assume the onCreate will get called (or am I wrong?) and I need to avoid the 2nd activity from reinitializing itself.
When an activity is started using startActivity, is it possible to gain access to the underlying class instance itself and simply call the method?
I actually came up with a simple solution. As a matter of fact you can access the underlying class of an activity. First, you create a class that is used to hold a public static reference to activity 2. When activity 2 is created, in its onCreate method you store "this" in the static reference. Activity 2 implements an interface with the methods that you want available to any other activity or object. The static reference you hold would be of a data type of this interface. When another activity wants to call a method in this activity, it simply accesses the public static reference and calls the method. This is no hack but is intrinsic to how Java operates and is totally legitimate.
It is not a good idea.
As I can understand method from second activity is actually not connected to particular activity while you want to call it from another one. So carry the method out to other (non-activity) class (maybe static method) and use it from both activities.
It's not directly possible to gain access to activity object started using startActivity (without using some hacks). And frankly you shouldn't even trying to accomplish this.
One Activity component can cycle through several Activity java object while its alive. For example, when user rotates the screen, old object is discarded and new activity object is created. But this is still one Activity component.
From my experience, when you need to do things you described, there is something wrong with your architecture. You either should move part of activity's responsibilities to Service or to ContentProvider, or use Intents, etc. Its hard to recommend anything more specific without knowing more details.
No there is no way to pass a reference via startActivity() however you can use some sort of shared memory to keep reference to your Activity. This is probably a bad design. However passing an extra with your Intent will not cause onCreate, that is completely related to the lifecycle.

Handling onActivityResult from outside the Activity

I'm trying to make a helper class to start an Activity and get the return result (startActivityForResult) to avoid developers writing their own onActivityResult code and encapsulate the complex internal details.
ie: the caller's code:
MyIntent i = new MyIntent();
i.getMyData(new OnData() { public void onData(Bundle data) {....} );
I tried creating a "dummy" Activity inside MyIntent just to be able to override onActivityResult, but the activity needs to be declared in the manifest, which is what the helper class tries to avoid. There is no "setOnActivityResult" which would be a good alternative.
So, how to create an Activity programmatically and "attach" it so it has valid state?
After creating new Activity() I'd like to call the Activity "attach" which is internal.
So, how to create an Activity programmatically and "attach" it so it has valid state?
That is not possible, sorry.
I'm trying to make a helper class to start an Activity and get the return result (startActivityForResult) to avoid developers writing their own onActivityResult code and encapsulate the complex internal details.
That is not possible, sorry. The closest you can get is how the Barcode Scanner integration JAR works -- you delegate onActivityResult() to them to decode the result obtained from the scanner activity.
Could a simple callback be an alternative? User places callback in static field of your library and your library will invoke this callback when required. The most straightforward implementation could be:
YourSdk.staticCallbackField=new OnData() { public void onData(Bundle data) {....});
MyIntent i = new MyIntent();
startActivity(i);
When you SDK completes it's job it invokes callback:
staticCallbackField.onData(data)
User activity will get Bundle data in callback instead of onActivityResult.
You should be aware of possible activity lifecycle issues. For example if android recreates user activity in the background callback should be recreated.

call the methods from one activite to other( java.lang.IllegalStateException: System services not available to Activities before onCreate())

I'm struck with some problem will calling the method from one activity to other......
I have a activity called Transaction2 in this activity,I have a method like getProposal().I need to call this method in to the other activity called PaymentDetails. I called the method like this : I import the activity(import com.Transaction2;) in to the paymentDetails and i create an object as
Transaction2 ts2 = new Transaction2();
and i call the method as ts2.getProposal();
when i called like this I am getting the exception like
java.lang.IllegalStateException: System services not available to Activities before onCreate()
Can anyone help me ?
Actually as i know, you cannot create a new activity by new. In android, Activity is suggest to designed as a standalone module, and the activity is created by android. If you want to communicate to other activities, you should use Intent to do this. And i strongly recommend you to put your application data out of your activity. Activity only take care of UI stuff.

Categories

Resources