I have an activity in android application and from that I am calling a method of an AsyncTask class which is calling a webservice. I want to reset/reload my activity on the basis of the result i get from that method. How can I reset my activity from that class?
You can try the following
Pass calling Activity context to your AsyncTask in constructor and save it in a variable Context context.
Then in your PostExecute method of AsyncTask, write following lines :
Intent targetIntent = new Intent(context, TargetActivity.class);
// Add your data to intent
targetIntent.putExtra("intent_extra_key", "intent_extra_value");
context.startActivity(targetIntent);
((Activity) context).finish();
Revert back for any issue.
Example:
Note: Remove the comment and delete or use comment for startActivity(i); in onPostExecute(Boolean aBoolean) if you want to test code example below without changing it.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new LoadFromWebAsyncTask(this).execute();
}
private class LoadFromWebAsyncTask extends AsyncTask<Void, Void, Boolean> {
MainActivity activity;
LoadFromWebAsyncTask(MainActivity activity) {
this.activity = activity;
}
#Override
protected Boolean doInBackground(Void... params) {
return true;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
activity.finish();
Intent i = new Intent(MainActivity.this, MainActivity.class);
startActivity(i);
/* final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
activity.finish();
Intent i = new Intent(MainActivity.this, MainActivity.class);
startActivity(i);
}
}, 5*1000);*/
}
}
}
Related
Im working on offline login based application using SQLite. For the purpose of security i need to move to login activity if the app has minimized. i tried this code in onPause function
#Override
protected void onPause() {
Intent intent = new Intent(dashboard.this, login.class);
startActivity(intent);
finish();
super.onPause();
}
when i try to move from that activity to another also it moves to the login activity. i hope when im moving to another activity current activity is set to paused. that's why it moves to login activity.
you must set a Boolean to handle loginActivity ;
boolean mustGoToLoginActivity=true;
when you want to go to another Activity first set this boolean to false for example :
public void goToAnotherActivity(){
mustGoToLoginActivity=false;
//...
startActivity(anotherActivity);
}
and in onResume() methode set taht to true .
then in onPause() method :
#Override
protected void onPause() {
if(mustGoToLoginActivity){
Intent intent = new Intent(dashboard.this, login.class);
startActivity(intent);
finish();
}
super.onPause();
}
You are right, this scenario will not work. What you can do is use a static boolean to achieve the behavior like this.
public class MainActivity extends AppCompatActivity {
static Boolean navigateToLogin =false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (navigateToLogin) {
move();
navigateToLogin =false;
}
}
private void move() {
Intent intent = new Intent(this, newActivity.class);
startActivity(intent);
}
#Override
protected void onPause() {
super.onPause();
navigateToLogin = true;
}
}
I need to make simple thing: from my app I have to make a photo, send it to server (in background) and show notification after sending. It all works, but now I have to wait for end of sending file - activity with camera is closing after that. I don't want to wait, I want to get back to my main activity right after taking picture (but upload would be still going in thread, and send notification when finishes).
The problem: I don't know how to let know to my main activity, that thread has finished uploading of photo.
Maybe passing context or handler to camera activity would help, but I can't do that by putExtra().
Any suggestions?
Some fragments of my code:
in MainActivity.java:
Intent intent = new Intent(this, Camera.class);
startActivityForResult(intent, Constants.REQUESTCODE_CAMERA);
in Camera.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
//(...)
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(intent,TAKE_PHOTO);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//(...)
new SendFileToServer().execute();
// finish(); // I would like to finish Camera.java here, and get back to MainActivity, while SendFileToServer uploads file and send some notification later
}
protected class SendFileToServer extends AsyncTask<Void, Void, String>{
#Override
protected String doInBackground(Void... params){
//(...) // here is sending of file to server, it works
}
#Override
protected void onPostExecute(String result) {
//(...) // code below doesn't work, because I didn't pass "context", I don't know how, or it's just impossible
MainActivity mainActivity = (MainActivity) context;
mainActivity.sendFileName(filename);
}
}
What you can do is send a broadcast on the end of the AsyncTask and register a receiver in the Activity where you want to do something (e.g. show notification).
To do that you will need to:
1) pass an Application Context to your AsyncTask (in Activity):
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//(...)
new SendFileToServer(getApplicationContext()).execute(); // pass application context to AsyncTask
finish();
}
2) Send a broadcast from onPostExecute():
protected class SendFileToServer extends AsyncTask<Void, Void, String>{
private Context context;
public SendFileToServer(Context context) {
this.context = context;
}
#Override
protected String doInBackground(Void... params){
//(...) // here is sending of file to server, it works
}
#Override
protected void onPostExecute(String result) {
Intent intent = new Intent("com.example.UPLOAD_FINISHED");
context.sendBroadcast(intent);
}
}
3) Register a BroadcastReceiver in MainActivity (don't forget to unregister receiver in onPause()):
MainActivity.class
private BroadcastReceiver broadcastReceiver;
#Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter(
"com.example.UPLOAD_FINISHED");
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// show notification
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
My app start with splash screen. Splash screen visible for 5 seconds then menu activity start. But when splash screen on display and I press back or home button app go in background but after few seconds its come on foreground automatically with menu activity. I want if user press home or back key app close permanently. Here is what I have tried so far.
Splash Screen Activity-
public class SplashScreen extends Activity
{
/** Called when the activity is first created. */
TimerTask task;
Intent objIntent, intent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
UtilClass.playing = true;
objIntent = new Intent(SplashScreen.this, PlayAudio.class);
startService(objIntent);
new Handler().postDelayed(csRunnable2, 5000);
}
Runnable csRunnable2=new Runnable()
{
#Override
public void run()
{
intent = new Intent(SplashScreen.this, MainActivity.class);
startActivity(intent);
finish();
}
};
public void onBackPressed()
{
objIntent = new Intent(this, PlayAudio.class);
stopService(objIntent);
finish();
return;
}
#Override
protected void onPause() {
super.onPause();
objIntent = new Intent(this, PlayAudio.class);
stopService(objIntent);
finish();
}
}
You can see in onPause and onBackPressed I am closing app. But its start with menu activity after few seconds.
what suitianshi suggests is
public class SplashScreen extends Activity
{
/** Called when the activity is first created. */
TimerTask task;
Intent objIntent, intent;
Handler handler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
UtilClass.playing = true;
objIntent = new Intent(SplashScreen.this, PlayAudio.class);
startService(objIntent);
handler = new Handler();
handler.postDelayed(csRunnable2, 5000);
}
Runnable csRunnable2 = new Runnable()
{
#Override
public void run()
{
intent = new Intent(SplashScreen.this, MainActivity.class);
startActivity(intent);
finish();
}
};
public void onBackPressed()
{
objIntent = new Intent(this, PlayAudio.class);
stopService(objIntent);
finish();
return;
}
#Override
protected void onPause() {
super.onPause();
objIntent = new Intent(this, PlayAudio.class);
stopService(objIntent);
finish();
}
#Override
protected void onStop() {
super.onStop();
handler.removeCallbacks(csRunnable2);
}
}
As, Chris mentioned, Declare your HANDLER globally as,
Handler handler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
UtilClass.playing = true;
objIntent = new Intent(SplashScreen.this, PlayAudio.class);
startService(objIntent);
handler = new Handler();
handler.postDelayed(csRunnable2, 5000);
}
Here in this Line,
handler.postDelayed(csRunnable2, 5000);
You are calling your "csRunnable2", after 5 seconds, So, it will come up after 5 seconds until unless,
=> You destroy your instance of handler class completely or ,
=> Make all the references Null.
So, When ever you are closing or pausing your activity(as in onBackPressed(), onPause(), onStop(), onDestroy() etc.,.) make sure to call :
handler.removeCallbacksAndMessages(null);
before you start next Activity.
This will makes null of all Handler instances.
For eg., in your code you can call,
public void onBackPressed()
{
handler.removeCallbacksAndMessages(null);
objIntent = new Intent(this, PlayAudio.class);
stopService(objIntent);
finish();
return;
}
#Override
protected void onPause() {
super.onPause();
handler.removeCallbacksAndMessages(null);
objIntent = new Intent(this, PlayAudio.class);
stopService(objIntent);
finish();
}
I've read many answers on the same question but still I do not understand why my code doesn't work properly. I have a problem with (as I think) exchanging data between two activities.
I have 2 activities - the first contains ListView and an Add button.
When user presses Add new activity starts with the form to fill. When user completes the form he/she presses OK and my first activity starts again (it really does) and it should contain new item (but it doesn't).
This is my first activity:
public class DatabaseActivity extends Activity implements OnClickListener {
ArrayList<Student> students;
StudentDatabaseAdapter adapter;
ListView lvStudentList;
ImageButton imgBtnAdd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.database);
students = new ArrayList<Student>();
fillArrayList();
adapter = new StudentDatabaseAdapter(this, students);
lvStudentList = (ListView)findViewById(R.id.lvStudentsList);
lvStudentList.setAdapter(adapter);
imgBtnAdd = (ImageButton)findViewById(R.id.imagBtnAddStudent);
imgBtnAdd.setOnClickListener(this);
}
public void fillArrayList() {
//code here
}
#Override
public void onClick(View v) {
Intent intent;
intent = new Intent(this, WizardActivity.class);
startActivity(intent);
}
public void addStudent(Student student) {
students.add(student);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if(resultCode==RESULT_OK)
{
if(requestCode==2)
{
if (intent == null) {return;}
Student newStudent = new Student(intent.getStringExtra("name"), intent.getStringExtra("surname"),
intent.getStringExtra("last_name"), Integer.parseInt(intent.getStringExtra("year_of_birth")), R.drawable.default_ava);
addStudent(newStudent);
adapter.notifyDataSetChanged();
}
}
}
}
And that's my second activity:
public class WizardActivity extends Activity implements OnClickListener {
EditText etName, etSurname, etLastName, etYearOfBirth;
ImageButton imgBtnOK;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.wizard);
etName = (EditText)findViewById(R.id.etName);
//initializing other edit texts
imgBtnOK = (ImageButton)findViewById(R.id.imgBtnOK);
imgBtnOK.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(this, DatabaseActivity.class);
intent.putExtra("name", etName.getText().toString());
intent.putExtra("surname", etSurname.getText().toString());
intent.putExtra("last_name", etLastName.getText().toString());
intent.putExtra("year_of_birth", etYearOfBirth.getText().toString());
setResult(RESULT_OK, intent);
startActivityForResult(intent, 2);
}
}
There is nothing wrong with your notifyDataSetChanged(). You seem to be missing the way a secondary activity communicates results back to its caller activity.
DatabaseActivity.onClick() should call startActivityForResult() instead of startActivity().
WizardActivity.onClick() should just call finish() after setResult() (remove the startActivityForResult() call, it doesn't make sense there). Also notice that the intent you provide to setResult() can be an empty intent, i.e. Intent intent = new Intent();
After the secondary activity finishes, DatabaseActivity will be back to foreground and the result will be processed by DatabaseActivity.onActivityResult().
I think you haven't to start new activity in WizardActivity
try this :
WizardActivity
......
#Override
public void onClick(View v) {
Intent intent = new Intent(this, DatabaseActivity.class);
intent.putExtra("name", etName.getText().toString());
intent.putExtra("surname", etSurname.getText().toString());
intent.putExtra("last_name", etLastName.getText().toString());
intent.putExtra("year_of_birth", etYearOfBirth.getText().toString());
setResult(RESULT_OK, intent);
finish();
}
and in
DatabaseActivity
add if you want
#Override
protected void onResume (){
......
adapter.notifyDataSetChanged();
}
The app I'm coding checks wether there is a special ZIP-File in a Directory under /sdcard and starts to download and unzip it if not. The download and unzip works finde, even with subdirectories. But I need to restart the App when it's done - and that does not work.
At first I have a special Activity "PreMainActivity.java" just for restart purposal:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class PreMainActivity extends Activity
{
/**
*
*/
public static Boolean ENABLE_RESTART = false;
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
PreMainActivity.ENABLE_RESTART = true;
restartMain();
}
#Override
public void onRestart()
{
super.onRestart();
restartMain();
}
/**
*
*/
public void restartMain()
{
if (PreMainActivity.ENABLE_RESTART == true)
{
final Intent mainIntent = new Intent(this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(mainIntent);
finish();
}
else
{
finish();
}
PreMainActivity.ENABLE_RESTART = false;
}
}
then I got some code within the DownloadFile.java
#Override
protected void onPostExecute(final String result)
{
MainActivity.mProgressDialogDownload.dismiss();
PreMainActivity.ENABLE_RESTART = true;
final Intent i = new Intent(MainActivity.this, PreMainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
}
As far as I have researched I need to pass the context of my MainActivity to the DownloadFile.java - but I still have no clue how. Can anyone gibe me a hint how to pass the context to a AsyncTask in a separate file within the same package? Or any other hint how to restart the whole app after a AsyncTask has finished ?
You will need to Create a constructor of the AsyncTask to pass Current Activity Context as:
public Context ctx;
public Your_AsyncTask_Class_Name (Context context){
super();
this.ctx=context;
}
......
#Override
protected void onPostExecute(final String result)
{
MainActivity.mProgressDialogDownload.dismiss();
PreMainActivity.ENABLE_RESTART = true;
final Intent i = new Intent(ctx, PreMainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
}
and from Activity you can pass context as:
AsyncTask_Class_Name asyktaskobj=new AsyncTask_Class_Name(this);
asyktaskobj.execute();
Just restart your main.activity like this:
Intent intent = getIntent();
finish();
startActivity(intent);
See question:
How do I restart an Android Activity