What is wrong with this use of Application context in Android? - android

I abstract my model like this:first there is a class UserInfo which holds user information:
public class UserInfo extends Application{
private int userid;
public void setUserId(int id)
{
userid=id;
}
public int getUserId()
{
return userid;
}
}
Then in MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
userinfo=(UserInfo)getApplication();
userinfo.setUserId(1354);
....
Intent intent=new Intent(MainActivity.this,VoteActivity.class);
startActivity(intent);
}
public
#Override void onResume()
{
super.onResume();
TextView text=(TextView)MainActivity.this.findViewById(R.id.usernameText);
text.setText(userinfo.getUserId()+" ");
}
And in VoteActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vote);
userinfo=(UserInfo)getApplication();
Button back=(Button)findViewById(R.id.backButton);
back.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
userinfo.setUserId(-100);
Intent intent=new Intent(VoteActivity.this,MainActivity.class);
startActivity(intent);
}});
}
The result is: when MainActivity first run, userid in UserInfo is 1354 ; And when VoteActivity first run, userid in UserInfo is 1354 too.However when back to MainActivity from VoteAcitivy userid remains 1354 which should be -100.What is wrong with this use of Application context?

You're starting a new activity in your onClick method :
Intent intent=new Intent(VoteActivity.this,MainActivity.class);
startActivity(intent);
And you direct set your id in the MainActivity :
userinfo.setUserId(1354);
That's why you get (1354). You should call finish in your on click (instead of starting the MainActivity).
The activity's stack look like this : MainActivity - VoteActivity - MainActivity and I think you want it to look like this : MainActivity after pressed on your Button
#Override
public void onClick(View arg0) {
userinfo.setUserId(-100);
finish();
}});

How you do you get back for your MainActivity? Pressing the device's back button or clicking on your button? If you press the device's back button your onClickListener won't be called, so that's why id remains the same.

#Override
public void onClick(View arg0) {
userinfo.setUserId(-100);
Intent intent=new Intent(VoteActivity.this,MainActivity.class);
startActivity(intent);
}});
when you click on your back button you restart MainActivity. The MainActivity onCreate will be excuted again. Is MainActivity flagged as singleInstance?

Related

How to keep intent for second activity?

I have a MainActivity with some cards which have different names. onClick, the title is passed as an intent via the adapter to the secondActivity and displayed as the header. From there, I can go to other activities. If I come back from one of these other activities (via the back button created by establishing second activity as the parent activity) the header is gone. How do I keep the header that was originally passed on as an intent or should I go about this completely different?
I have tried using onResume() and onStart() in the secondActivity to reassign the intent from a global variable.
The adapter class, where the card onClick method is written:
#Override
public void onBindViewHolder(final TripHolder tripHolder, final int position) {
Trip trip = trips.get(position);
tripHolder.setDetails(trip);
tripHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, SecondActivity.class);
TextView card_title = v.findViewById(R.id.TripNamecl);
intent.putExtra("card_title", card_title.getText().toString());
context.startActivity(intent);
}
});
}
The secondActivity where the header should be displayed:
public class SecondActivity extends AppCompatActivity {
String name;
TextView header;
static final String STATE_HEADER = "header";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
name = getIntent().getStringExtra("card_title");
header = findViewById(R.id.TripsHeader);
header.setText(name);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(STATE_HEADER, name);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
name = savedInstanceState.getString(STATE_HEADER);
header.setText(name);
}
public void launchMapsActivity(View view) {
Uri gmmIntentUri = Uri.parse("geo:48.8566°,2.3522");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
if (mapIntent.resolveActivity(getPackageManager()) != null) {
startActivity(mapIntent);
}
}
public void launchTravelActivity(View view) {
Intent intent = new Intent(this, TravelActivity.class);
startActivity(intent);
}
public void launchPlansActivity(View view) {
Intent intent = new Intent(this, PlansActivity.class);
startActivity(intent);
}
}
SOLUTION:
The solution was to put android:launchMode="singleTop" into the manifest file for the secondactivity. It's described in more detail here: How can I return to a parent activity correctly?
In order to do it you should override onSavedInstanceState in your SecondActivity.
You can use something like that, obv adapt it to your needs:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
//here you can save your variables
savedInstanceState.putString("myHeader", name);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//here you can retrieve your variables
name = savedInstanceState.getString("myHeader");
}
Let me know if this worked! good luck
remove header.setText(name); from onResume and onStart methods
If you want to save data in first activity between lifecicle method calls you have to save your data in Bundle object.
Override method onSaveInstanceState(Bundle bundle) of your activity:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("AStringKey", variableData);
outState.putString("AStringKey2", variableData2);
}
And also override Activity method onRestoreInstanceState(Bundle savedInstanceState):
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
variableData = savedInstanceState.getInt("AStringKey");
variableData2 = savedInstanceState.getString("AStringKey2");
setYourHeaderMethodExample(variableData2)
}
When coming back from third activity to second activity onStart() and onResume() method call executes. Try not using onStart() and onResume() for setting the header and use onCreate method for setting the header.
onCreate() method executes only once in its lifetime, but onStart() and onResume() will execute whenever the activity comes to screen. So when coming back from third activity we don't have any values in the intent.
In your second activity's onCreate method add:
getSupportActionBar().setHomeButtonEnabled(true);
and override the onOptionsItemSelected() method in the class and add the following code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
You don't need to override the onStart() and onResume() methods.

Disable a button when an event occure in main activity

I have two activities named Main activity and Second Activity. Main activity has an event handler. I need to disable a button in second activity when an event occurs.
Main activity
public void myEventListener(int eventID){
switch (eventID) {
case : 0
// disable button of second activity here
break;
}
}
This is an easy one.
Use SharedPreference of changing data(boolean maybe) in MainAcitivity
Use SharedPreference.OnSharedPreferenceChangeListener in SecondActivity for listening to that specific data and changing button state at runtime in.
MainActivity.java
public class MainActivity extends AppCompatActivity {
SharedPreferences.Editor editor;
public void myEventListener(int eventID){
switch (eventID) {
case 0:
editor = getSharedPreferences("pref",MODE_PRIVATE).edit();
editor.putBoolean("event",true);
break;
}
}
}
SecondActivity
public class SecondActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
SharedPreferences sharedPreferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
}
#Override
protected void onStart() {
super.onStart();
sharedPreferences=getSharedPreferences("pref",MODE_PRIVATE);
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onStop() {
super.onStop();
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals("event") && sharedPreferences.getBoolean(key,false))
{
//add your code to disable your button or any action you want
}
}
}
It's very simple to disable a button. Follow the below steps to achieve your problem.
Define a global boolean value as "false"
In onClickEvent override, the boolean value as "true".
Then check with the boolean value as follows
private boolean isClicked = false;
if(isClicked){
button.disabled(true);
} else {
button.disabled(false);
}
Please let me know if you have any issues while applying.
In you First Activity make Boolean static variable.
Example:
FirstActivity
create a Boolean static global variable
public static Boolean clicked = false;
onFirstActivity if Event occurs.
event occurred => clicked = true; otherwise it is false
SecondActivity
in second activity get the value to static boolean from FirstActivity
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (FirstActivity.clicked){
//Do Nothing
}else{
//Perform action
}
}
});
first make reference of second activity and set button visibility GONE or INVISIBLE It's Work
SeconActivity sa; //reference of second activity
public void myEventListener(int eventID){
switch (eventID) {
case : 0
sa.btnofsecondactivity.setVisibilty(View.GONE);
break;
}
}
You can go with LocalBroadCastManager.
in MainActivity wherever you want to trigger the method
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("event-occured"));
in SecondActivity register the LocalBroadcastManager and receive it.
public class SecondActivity extends AppCompatActivity {
private BroadcastReceiver mainActivityReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mainActivityReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do whatever you want to do
Log.d("TAG", "broadcast received");
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(mainActivityReceiver, new IntentFilter("main-activity-initialized"));
}
#Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mainActivityReceiver);
}
Don't forget to unregister the listener in SecondActivity's onDestroy method. Taken reference from here.

Sending integer with intent (android studio)

ANSWERED
I am trying to send and int to another activity.There is a button in first act. and it opens second act. and takes int from here to other page.But i cant start two of them at one time.
Here is my first activity :
public class ana_ekran extends AppCompatActivity {
public TextView ana_ekran_kule;
public TextView ana_ekran_can;
public int ana_ekran_can_int=30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ana_ekran);
ana_ekran_kule=(TextView) findViewById(R.id.textView);
ana_ekran_can=(TextView) findViewById(R.id.textView2);
ana_ekran_can.setText(ana_ekran_can_int+" CAN");
}
public void devam (View v){
Intent i = new Intent(getApplicationContext(),fight_1.class);
i.putExtra("deger", ana_ekran_can_int);
startActivity(i);
startActivity(new Intent(this,fight_1.class));
}
}
and this is second:
public class fight_1 extends AppCompatActivity {
public TextView fight_1_can;
public int fight_1_can_int;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fight_1);
fight_1_can=(TextView) findViewById(R.id.textView3);
int i = getIntent().getIntExtra("deger",-1);
fight_1_can_int=i;
fight_1_can.setText(fight_1_can_int+"");
}
}
This startActivity(i); will do the same thing as next line but it will carry the data as well whereas startActivity(new Intent(this,fight_1.class)); will only start the other instance of fight_1 activity so
public void devam (View v){
Intent i = new Intent(getApplicationContext(),fight_1.class);
i.putExtra("deger", ana_ekran_can_int);
startActivity(i);
// start fight_1 again without any data so not required
//startActivity(new Intent(this,fight_1.class));
}

Multiple Instances and Multiple Activities calling the same Activity

I have three Activities. MainActivity,ActivityB and ActivityC. In activity A and B there are two buttons source and destination in both activities. in Activity C there is a list of data. when button is clicked (either Source or destination) from activity A and B. both Activities are calling Activity C
code for Activity A is following
public class MainActivity extends Activity {
TextView source,destination;
Button sendSource,sendDestination,btnTob;
String src,des,activity,checksrc,checkdes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
source=(TextView)findViewById(R.id.tv_rcvDataA);
destination=(TextView)findViewById(R.id.tv_rcvDataAa);
sendSource=(Button)findViewById(R.id.btn_sendA);
sendDestination=(Button)findViewById(R.id.btn_sendAa);
btnTob=(Button)findViewById(R.id.btn_toB);
sendSource.setText("source");
sendDestination.setText("destination");
src=sendSource.getText().toString();
des=sendDestination.getText().toString();
activity=getClass().getSimpleName();
sendSource.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent send= new Intent(MainActivity.this,ActivityC.class);
send.putExtra("source",src);
send.putExtra("Activity",activity);
startActivity(send);
}
});
sendDestination.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent senda= new Intent(MainActivity.this,ActivityC.class);
senda.putExtra("destination",des);
senda.putExtra("Activity",activity);
startActivity(senda);
}
});
btnTob.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent movetoB= new Intent(MainActivity.this,ActivityB.class);
startActivity(movetoB);
finish();
}
}); }}
and code for Activity B is
public class ActivityB extends Activity {
TextView sourceB,destinationB;
Button sendSourceB,sendDestinationB;
String src,des,activity,checksrc,checkdes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
sourceB=(TextView)findViewById(R.id.tv_rcvDataB);
destinationB=(TextView)findViewById(R.id.tv_rcvDataBa);
sendSourceB=(Button)findViewById(R.id.btn_sendB);
sendDestinationB=(Button)findViewById(R.id.btn_sendDataBa);
activity=getClass().getSimpleName();
sendDestinationB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent senda= new Intent(ActivityB.this,ActivityC.class);
senda.putExtra("destination",src);
senda.putExtra("Activity",activity);
startActivity(senda);
}
});
sendSourceB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent send= new Intent(ActivityB.this,ActivityC.class);
send.putExtra("source",src);
send.putExtra("Activity",activity);
startActivity(send);
}
});}}
now how to check in activityC which activity is calling this activity and which buttonclicklistener is calling the intent
You need to send the value for determine what value and what activity via Intent.putExtra(). Please be remember that you need to set the key as the first parameter for Intent.putExtra(), like
intent.putExtra(THIS_IS_THE_KEY, THIS_IS_YOUR_VALUE);
You need to create something like this:
// This is the key for your putExtra
// you need to create this as global variable.
public static final String FROM_KEY = "FROM";
public static final String ACTIVITY_KEY = "ACTIVITY";
public static final boolean IS_FROM_SOURCE = true;
// This is a sample to send data to Activity C
// where the activity caller is B and from source
Intent senda= new Intent(ActivityB.this,ActivityC.class);
senda.putExtra(FROM_KEY, IS_FROM_SOURCE);
senda.putExtra(ACTIVITY_KEY,"activity_a");
Then in your Activity C, you need to receive the Intent Extra.
You can get the value in Activity onCreate(), something like this:
Bundle extras = getIntent().getExtras();
boolean from = extras.getBoolean(FROM_KEY);
String act = extras.getString(ACTIVITY_KEY);
// do something here if from activity a
if(act.equals("activity_a")) {
if(IS_FROM_SOURCE) {
// do something if from source
} else {
// do something if from destination.
}
} else { // if from activity a
if(IS_FROM_SOURCE) {
// do something if from source
} else {
// do something if from destination.
}
}
In onCreate or anytime after that method is called in Activity-C, you should do the following:
Intent intent = getIntent();
if (intent != null) {
String activity = intent.getStringExtra("Activity");
String src = intent.getStringExtra("source");
// Do something with those values
}

How can I activity close in Android?

I have three classActivity created. One is super class and other sub class and third is HomeActivity.
Code for super class is :
public class MyActivity extends Activity {
Button btnHome = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onHomeClick(View view) {
String LOG_TAG = "Akshar";
System.out.println("Hello11111");
btnHome = (Button) view;
Log.v(LOG_TAG, "index=" + btnHome);
}
}
and my subclass code is :
public class ChooseIsland extends MyActivity {
Button btn_home = null;
MyActivity ob1 = new MyActivity();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chooseiland);
addListenerOnButton();
}
private void addListenerOnButton() {
// TODO Auto-generated method stub
ob1.onHomeClick(btn_home);
}
}
Now I want to go on Home page when click so when I write ?
Intent intent = new Intent(this, HomeActivity.class);
There is no close operation as such in android. You should make sure you do not save anything in stack so whenever you are traversing from one activity to other, make sure you use intent flags to clear history or top of stack and then call finish.
finish() will close the current activity and the previous activity will come to foreground.
Generally to we write finish() method to close activity.

Categories

Resources