Select folder intent & Work out when intent complete? - java

So I'm making a wallpaper and I want the user to select a folder. So I
have a button in the preferences that launches an intent to open an
image, but what I want is actually just a directory (I guess in the
worst case i can strip the filename from the end). So that's my first
problem: what's the best way to select a folder only?
The second problem is how do I get notified of when the intent is
complete?
public class FilePreference extends DialogPreference implements
View.OnClickListener
{
public void onClick(View v)
{
// open up a gallery/file browser
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
getContext().startActivity(Intent.createChooser(intent, "Select Folder"));
}

use Activity.startActivityForResult and override Activity.onActivityResult

Okay that helped a bit, I managed to work out my wallpaper service was actually an activity. SO then I had to find my preference by name and add a pointer to it so the preference could use startActivityForResult and onActivityResult

Related

How to properly close login page?

For example, first activity of app is MainActiviy which is basically 2 text fields (login and password) with a button. Pressing a button tells the database these text fields' data so it can tell the program if the user is in database and password is correct.
What I'm used to is to create a bool flag field saved in SharedPreference so the program knows i already logged in my app recently so it can open my second activity, but it seems like wrong and weird solution.
So, how do I properly login into my app in theory?
Mikkel,
Your approach with storing data using shared preferences is perfect but I have some suggestions which can make this solution better and robust.
First of all, you should check the sharePreference value inside a splash screen. Which checks for the login flag and launch the LoginActivity if a user is not logged in and launch the HomeActivity if a user is logged in.
Second, I would suggest using Androidx DataStore, which is a better version of shared preference and it can be asynchronous API so you can use it safely on the UI thread.
Don't forget to close your main activity after user login using the below code.
Intent intent = new Intent(this,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
If you need an example to handle this stuff better here is the github-sample which can be very helpful.
This is wrong:
Intent intent = new Intent(this,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(intent);
You should use "startActivity" before "finish()"
Correctly:
Intent intent = new Intent(this,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();

How to maintain binding on Fragment -> Intent -> Back to Fragment

I am using a Fragment and within my Fragment, I am starting a new Intent to access the device's settings. When I select the 'Back' button from the Android device, my bindings do not reflect in my View. The ViewModel properties are correct when I debug but the View doesn't reflect live data updates anymore. This only happens when I open the Intent
I am opening the Intent here:
private View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
};
I am using the ObservableFields in my ViewModel so I think it's working correctly as I mentioned before - the data is correct on the debugger, just not reflected in the View if I go into the Intent. The View will reflect any changes if I do not go into the Intent. Do I need to Override the onResume method?
As the doc says,
the fields should be declared final in your data model because bindings only detect changes in the field's value, not of the field itself
Please check this statement. If if didn't fix your problem, can you post some additionnal code as your data model class, and how you use it in your fragment?
Hope it helps.

My app skips starting an intent and executes the next code lines?

So I have the following currently:
public void addProject(View v) {
String pn = "";
Bundle extras = new Bundle();
Intent i = new Intent(mMainContext, AddProject.class);
mMainContext.startActivity(i, extras);
if(extras.getString("projectName") != null) {
pn = extras.getString("projectName");
}
}
This is just an example, the first bit is correct though the if statement may not be but this isn't about that block.
What I have noticed is that if I place breakpoints on the new intent, start activity and then the if statement,
Android seems to skip past the startActivity and go onto the if statement.
If I then remove the if statement and run it again, it then launches the intent.
So what I've realised is that it runs to the end of the addProject block and then actually launches the intent...
Why is this? And more importantly, how I do stop it doing that?
Intended outcome is as follows:
1) user presses "Add Project" button
2) intent launched and user inputs project name and presses submit
3) calling intent then receives the p name for use later in the function.
Why is this?
startActivity() is asynchronous. When it returns, the activity is not yet started.
how I do stop it doing that?
You can't.
Intended outcome is as follows: 1) user presses "Add Project" button 2) intent launched and user inputs project name and presses submit 3) calling intent then receives the p name for use later in the function.
Having separate activities may not be the best plan for this (compared with using fragments).
If you wish to use activities, the most natural approach is:
Use startActivityForResult() instead of startActivity()
Have AddProject use setResult() to create a result Intent to deliver back to your first activity
Have your first activity override onActivityResult(), where it can receive a copy of that result Intent and get the results from it
Note that this still will all happen after addProject() returns. However, you will (eventually) get your results.
The Android documentation does not cover this very well, but this is what it has on the subject.
you must use onActivityResult for such task.
From your main Activity use: startActivityForResults(intent) in place
of startActivity();
In your AddProject Activity when user inputs project name and press the
button .
Intent i = new Intent();
i.putExtra("projectName",userInputTextFromEditText);
setResults(RESULT_OK,i)
In your MainActivity
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data){
pn = intent.getExtras.getStringExtra("projectName","");
}
this way you will find your result

Trying to exit in android. Stack is not correctly cleared

I have been spending lots of hours figuring the reason why top of the stack is not cleared yet.
Well I tried the following:
Intent intent = new Intent(ActionBarActivity.this, MainActivity.class);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
And it turned me to the MainActivity. Then when I try to press back button, the program does not exit, but instead it turns me to the first page of ActionBarActivity.
Let me be more specific:
In MainActivity I call ActionBarActivity. In the ActionBarActivity I have a search bar and I enter a query there and just print the value of the query.
If you think how it will work is a below:
MainActivity -> ActionBarActivity1 -> ActionBarActivity2 -> ActionBarActivity3 -> ..
In that ActionBarActivity I have also an option which brings me back to the MainActivity.
So as I said when I run application with the way above, it will bring me to the MainActivity.
Nice so far, but when I press the back button I expect it to exit, but instead it goes to ActionBarActivity1. I doubt the stack is not properly erased.
What should I do in this case. Thanks
I'm assuming you've seen this post: Android: Clear the back stack and it is not what you want
The FLAG_ACTIVITY_NEW_TASK is creating an new task stack. When you hit "back" that is the only activity in that stack, so Android goes to the previous task - which has the calling activity at the top.
If you remove that flag, then MainActivity is already in the task stack and is brought to the top. And "back" removes it and brings you back to the calling activity. So far, that is the expected Android behavior.
EDIT: Since you commented that you only have 2 activities, then one option is to "finish()" ActionBarActivity after it starts MainActivity like this:
startActivity(intentMainActivity);
finish();
To get the behavior you want with many activities or only in certain situations, you need to use SET_RESULT and finish the activities in the stack when you hit the button to go to the MainActivity. In other words, Android assumes you want to keep activities even when new ones start. But in this case you don't, so you have to tell the activity to destroy itself.
i.e. call setResult(DONE) and then use startActivityForResult and check for your "DONE" flag in the onActivityResult method.
then this:
MainActivity -> ActionBarActivity1 -> ActionBarActivity2 -> ActionBarActivity3
-> MainActivity
becomes:
MainActivity -> ActionBarActivity1 -> ActionBarActivity2 -> ActionBarActivity3
-> call "Done"
Destroy ActionBarActivity3
Destroy ActionBarActivity2
Destroy ActionBarActivity1
MainActivity remains
For example, in ActionBarActivity2:
startActivityForResult(intentActionBarActivity3, ActionBarActivity2_ID);
Then in ActionBarActivity3:
public void exitButton(View view) {
setResult(MY_DONE_FLAG);
finish();
}
And back in ActionBarActivity2:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ActionBarActivity2_ID && resultCode == MY_DONE_FLAG) {
setResult(MY_DONE_FLAG, data);
finish();
}
}
And so on with all activities that you want to "close" when that button is pressed.
try
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
insetead of
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
and you should also use it with every intent which leads you to ActionBarActivity.
i mean if you are going back to ActionBarActivity form ActionBarActivity1 then you use it with intent.
then create intent for MainActivity in your so called ActionBarActivity.
Intent intent = new Intent(ActionBarActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
Good luck !!!

Call other activities in an activity?

Say I have 2 activities (ActivityOne and ActivityTwo). How would I call ActivityTwo from ActivityOne? Then how would I return to ActivityOne from ActivityTwo? For example, I have a listview with all the contacts on the host phone. When I tap on a contact, another activity shows information and allows editing of that contact. Then I could hit the back button, and I would go back to the exact state that ActivityOne was in before I called ActivityTwo. I was thinking an Intent object, but I am not sure. Could someone post some code?
In your first activity (AcitvityOne) you could call
Intent intent = new Intent(this, ActivityTwo.class);
startActivityForResult(intent, CODE);
Then you can override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
to receive the result of this activity
In your example, it seems like you will want to pass data between Activity One and Activity Two (namely, the reference of the contact you want to edit), so you should use a Bundle with your intent in Activity One.
Intent myIntent = new Intent(this, ActivityTwo.class);
myIntent.putExtra("CONTACT", position);
this.startActivity(myIntent);
"CONTACT" is a key and position is a value (position would have been defined before, it could be whatever you want it to be, for example an integer. The way you retrieve it is slightly different based on what type it is, note the getInt() in Activity Two code below).
And in Activity Two, in onCreate()
Bundle extras = getIntent().getExtras();
if (extras != null) {
contact = extras.getInt("CONTACT");
/**Do what you want with the integer value you have retrieved**/
}
As for your other question, the back button removes the current Activity from the top of the tasks stack and therefore, you return to the previous Activity, normally in exactly the same state as you have left it.
However, if the phone is running low on memory, Android might kill off a process or Activity so it is possible in theory that your previous Activity will not show in exactly the same state as you have left it. If you have any important data, you should save it before launching Activity Two. If you just want to return to Activity One in the same state for user friendliness, then it's fine to rely on the back button.

Categories