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?
Related
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()
}
}
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.
I am using 3 classes A, B and C. In class A I created a method clickButton() and In class B I used onClick() for a button. while clicking on the button it has to call the method clickButton() in Class A, and inside the clickButton() i wrote intent for initiating the class C.
The problem is I couldn't able to call the Class A method in class B.
You generally don't want to touch another Activity directly. The Android design paradigm represents a largely separated viewpoint between different activities, and so instead of directly calling methods on a class A, you will send it an Intent or message or something. If you have a utility method, you should consider moving them into a shared class and making them static. If you have something that needs to be performed in the background or shared persistent store, you should consider moving to a service or content provider.
Let say that I have two Activity to develop in Android. Upon the end user click a button in Activity A, the application supposed to pull data off a JSON API and present that information on Activity B.
So my question is, what's the best practice or pattern? i.e.
Activity A will call an AsyncTask and perform JSON call. Pull the data, push it into the Intent via putExtra, and call Activity B?
Activity A will call Activity B, Activity B onCreate will call an AsyncTask and perform the JSON call?
Other suggestions?
Which one is the prefer pattern?
And which gives better user experience? (e.g. imagine where the error dialog will be if connection fail to the server.)
I think normally something of your #2 approach is done. In most cases, though, you need to tell Activity B what type of information to request from the JSON API. So say in Activity A you are choosing an item from a list, and Activity B will get more information about that item. In this example Activity A will simply pass a reference to which item was selected, and then Activity B can use that reference to make a JSON request for more information about that item. Does that make sense?
I usually try to pass as little information as I can in Intent extras so I would steer clear of your first solution.
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.