I am quite new to Java and would appreciate if someone could explain show me
how can I implement startActivityForResult(Intent, int) and
onActivityResult() in Bluetooth discoverability stated
here.
What I want to achieve is: on button Enable BTDisco click
(if(bttn.getId() == R.id.bt_disco) my program calls
BTDiscoverable() method:
public void BTDiscoverable() {
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
BT_ENABLE_TIME);
startActivityForResult(discoverableIntent, REQUEST_ENABLE_BT);
}
Now, the dialog pops up. If user clicks no, the program should not
continue. If user click yes, Enable BTDisco button should become
unavailable and another button, lets call it Start, becomes available. I
wrote onActivityResult which would make Start button available but I
doubt it is done right. Snippet here:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data)
{
if (requestCode == REQUEST_ENABLE_BT)
{
if(resultCode == RESULT_OK)
{
((Button) findViewById(R.id.bt_server_start)).setEnabled(true);
BTCountDown = new BTTimer(BT_TIME_BTTIME,BT_TIME_BTTIME);
BTCountDown.start();
}
}
}
startActivityForResult is called in BTDiscoverable method but it does
not provide what I wanted. I have followed this but as I am quite
new here, I have no idea how to implement this in such problem as mine.
The onActivityResult method is implemented class that extends Activity.
There are no errors while compiling. Long story, short: R.id.bt_server_start stays disabled as initially programmed.
Could really use some help.
Just put this
if(resultCode != RESULT_CANCELED)
Documentation says the following
Your activity will then receive a call to the onActivityResult()) callback, with the result code equal to the duration that the device is discoverable. If the user responded "No" or if an error occurred, the result code will be RESULT_CANCELED.
So if result code is not RESULT_CANCELED, then you are okay to enable your button.
Related
I use the library zxing-android-embedded in my Android App. Before calling initiateScan() method to start the scanner from my activity, I set a class variable scanedItemId to know on which item I clicked to scan.
My issue is that when the scanner activity finished, it goes back to my activity, but in a new instance and not the initial one (I checked with a break point in the onCreate method). So, my class variable is null. What can I do to keep my initial activity instance live and be sure the scanner goes back to it?
public class MyActivity
[...]
scanedItemId = currentItem.id // The current item where we clicked on.
IntentIntegrator qrCodeScanner = new IntentIntegrator(this);
qrCodeScanner.setOrientationLocked(false);
qrCodeScanner.initiateScan();
[...]
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case IntentIntegrator.REQUEST_CODE:
// Here the scanedItemId is always null.
[...]
```
You asked:
What can I do to keep my initial activity instance live and be sure
the scanner goes back to it?
You can't. When your app goes to the background and the scanner app needs resources, Android will kill your app to make the resources available to the scanner app. This is normal and your app needs to be made robust enough to deal with this. If you need to keep track of your app's state so that you can continue when your app returns to the foreground, then you need to save that information somewhere persistent. You have choices:
SharedPreferences
SQLite database
Use a file
Implement onSaveInstanceState()
Following what #David said, I implemented the "onSaveInstanceState()" solution which works fine: I just added this in my activity:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("scanedItemIdKey", scanedItemId);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
scanedItemId = savedInstanceState.getInt("scanedItemIdKey");
}
Thanks
For example I am starting a activity which finishes and returns a result, which is returned by the method onActivityResult. How can I wait before the result is provided by the onActivityResult and then continue my reactive stream?
public class TestActivity extends AppCompatActivity {
...
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// receiving result here
}
private Single<Data> loadData() {
return Remote.getInstance().getData()
.flatMap(data -> {
// do something
Intent intent = new Intent(TestActivity.this, OtherActivity.class);
startActivityForResult(intent, 0);
}) // how can I receive the result from the onActivityResult here?
}
}
It would be possible for example by using a PublishSubject that would notify in onActivityResult() and to which you'd flatMap() to in your original call, but I'd strongly advice against this. Here is why:
When your Activity receives an onActivityResult(), it might have been just recreated from scratch, because of a configuration change, memory pressure or anything else that happened in the meantime. This means that your Single subscription is either no longer active (if you properly unsubscribed from it onDestroy() or better in onStop()) or leaked the previous activity instance to what it is still attached to (in case you did not unsubscribe).
So, instead the stream (and the aforementioned PublishSubject) should probably live inside a component that survives activity recreation, like a retained fragment and you should call into that in onActivityResult() to notify your stream about the results. Here is some example how retained fragments and RxJava can work together.
I am calling Settings activity from another activity using the startActivityForResult method. When the back button is clicked, it goes back to the screen on my application. But this activity had already been loaded before calling the settings activity, so I want to be able to refresh the activity on back click on the settings activity. How do I do that?
You will want to implement the onActivityResult() method in your first activity. This method will be called any time an activity you've started with startActivityForResult() finishes.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == yourRequestCode) {
// your code here
}
}
In the case of the BACK button, the resultCode argument will be Activity.RESULT_CANCELED. This doesn't really change things, but lots of examples will include checking for resultCode == Activity.RESULT_OK and I just wanted to mention that it's perfectly fine to do things even when the result code is something else.
Just use
#Override
public void onResume(){
super.onResume();
// your code...
}
In the method implement what has to be needed to be updated.
I am developing an application in which login is not mandatory, but in side app there are some events where app asks user to login. I want to resume the process once login is done. For example if user is not logged in and clicks on "like" button, app redirects user to login activity. Now i want after login is done "like" click will also be performed. There are more such type buttons, apart from like. Please help...
There are several ways to do this (fragments, static fields to share status and perform action other where etc..) But in my opinion using a flag and startActivityForResult is the best thing to do in such a situation and to ensure re-usability, you can map a set of events with a number of keys and call those instead of separated flags once you receive the proper key associated with the event
HINT: send them through intents.
I'll use a flag here so for example if you want the like to be performed after the user is logged in.
In your CurrentActivity the one with the like button, set up an instance static boolean isValid=false; then use:
Intent i = new Intent(this, Login.class);
startActivityForResult(i, 1);
In Login.class:
//perform login
Intent i = new Intent();
//reset isValid to true
setResult(Activity.RESULT_OK,i);
finish();
In CurrentActivity.class:
//re-trigger the click event
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && isValid) {
if(resultCode == Activity.RESULT_OK){
//like
}
}
}
You can use Login screen as DialogFragment, so it will act as a Dialog by this way you can handle the previous click event by using a callback method in that Activity.
I need to have gridview scrolling to the first item onResume of my activity. It has only the vertical scrolling.
I have tried the following, but it didn't work...
gridView.setSelection(0);
gridView.scrollY(0);
Can someone help please...
I would try gridView.scrollTo(0,0) or gridVIew.smoothScrollTo(0,0), depending on your preference.
Edit: Updated with fixed code.
I have solved my problem!. I have implemented onActivityResult and called the activity for adding a new item, with a known request code. Then upon return, and the result was OK; I use gridView.smoothScrollTo(0), which worked like charm! See code below...
Intent intent = new Intent(this, AddNewActivity.class);
startActivityForResult(intent, REQUEST_ADD_NEW);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK)
{
if (requestCode == REQUEST_ADD_NEW_CLOTHING_ITEM)
{
gridView.smoothScrollToPosition(0);
}
}
}