My Activity Launches Twice - android

I have listview with setOnItemClickListener() method, when clicked I want it to open new activity and give it 2 extras, the number of the item and the user that logged in (back in home screen), the problem is that the activity starts twice, one with good extras and one with "0" in the position extra...
this code is supposed to check if Firebase server has place in it (no more than 5 players) and if so add the user to the server and join the room (launch ServerActivity).
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
myRef = database.getReference("Servers/S"+position);
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int i = 0;
while (dataSnapshot.child("player"+i).child("username").getValue() != null)
i++;
if (i < 5) {
Log.d("Implementing Child","player"+i);
CustomUser customUser = new CustomUser(false,currentUser.getUsername(),"",0,currentUser.getWins());
myRef.child("player" + i).setValue(customUser);
Intent intent = new Intent(GameActivity.this,ServerActivity.class);
intent.putExtra("serverNum",position);
intent.putExtra("currentUser",currentUser);
Log.d("position", position + "");
startActivity(intent);
finish();
}
else{
Toast.makeText(getApplicationContext(), "Server Full", Toast.LENGTH_SHORT).show();
myRef.child("isJoinable").setValue(false);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Toast.makeText(getApplicationContext(), "" +
"Internet Error", Toast.LENGTH_SHORT).show();
}
});
Intent intent = new Intent(GameActivity.this,ServerActivity.class);
intent.putExtra("currentUser",currentUser);
startActivity(intent);
finish();
//TODO FIX: activity probebly launches twice
}
});
I tried modifing LaunchMode in the manifest but it resulted with fail causing the "serverNum" extra to be 0 instead of the position.

Why have you added this code :
Intent intent = new Intent(GameActivity.this,ServerActivity.class);
intent.putExtra("currentUser",currentUser);
startActivity(intent);
finish();
This would cause your ServerActivity to launch as soon as the listener is added. Have you tried commenting this code and use only the code in onDataChange?

Related

Saving list data composed of individual buttons

I've made a list made of TextViews and Buttons, made that when a person clicks on a button, a fragment opens and there is a list of values he can select. The problem is when i press on another button to select a value again for a different field, the previous value disappears. So the question would be how to save the fragments values, and keep it saved until the app is closed ?
priceButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
PriceFragment priceFragment = new PriceFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer, priceFragment).commit();
setToHideElements();
}
});
yearButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
YearFragment yearFragment = new YearFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer, yearFragment).commit();
setToHideElements();
}
});
this is the year fragment
yearEndListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getActivity().getBaseContext(), MainMenuActivity.class);
String yearTo = yearList[i].toString();
int yearTint = Integer.valueOf(yearTo);
if (combinedYear != null) {
combinedYear = combinedYear + " " + yearTo;
intent.putExtra("Years", combinedYear);
getActivity().startActivity(intent);
} else {
combinedYear = null;
combinedYear = yearTo;
}
}
});
this is the method to retrive data
private void retriveDataFromFragment(){
Intent intent = getIntent();
String fragmentDataPrice = intent.getStringExtra("PriceData");
String fragmentDataYear = intent.getStringExtra("Years");
if(fragmentDataPrice != null){
priceButton.setText(fragmentDataPrice);
} else {}
if (fragmentDataYear != null){
yearButton.setText(fragmentDataYear);
} else {}
}
I use RetriveDataFromFragment method in OnResume method.
Thank you, for your time.
you are initiating every time a new fragment so it will never retain its state. you have to use listener while closing the fragment so you can get back your data.
I got the anwser if someone else needs a similar menu, all you have to do is create a class that extends Application, and include into your manifest (the part with application tags). From there you just use getters and setters and all is well.

How to show ad after user clicks on listview item but not for every item in Android?

I have a listview populated with data from a remote database. When the user clicks on an item they are taken to a detail screen. My question is how do I show and ad when the user clicks on a list item but not everytime they click on a list item. I don't want to show an ad with every list item click just like after every 5 clicks or so. How would I go about doing that? I'm assuming some sort of logic within the listview onItemClickListener. I just have no idea what that logic would look like.
EDIT
Per user8's answer, I've added a counter and shared prefs to the onItemClickListener. Nothing happens when I click on an item though. Not even to see the DetailActivity. Here's my code:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Get item at position
RowData item = (RowData)parent.getItemAtPosition(position);
final Intent intent = new Intent(MainActivity.this, DetailActivity.class);
mInterstitialAd.setAdListener(new AdListener() {
#Override
public void onAdClosed() {
requestNewInterstitial();
startActivity(intent);
}
});
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
int clickCount = prefs.getInt(KEY_CLICK_COUNT, 1);
if (clickCount % 5 == 0) {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
} else {
startActivity(intent);
}
}
clickCount++;
prefs.edit().putInt(KEY_CLICK_COUNT, clickCount).apply();
//Start details activity
//startActivity(intent);
}
});
EDIT 2
Ok. I see what was going wrong. Per user8's answer, when the user clicks 5 times it shows an ad yet if the user clicks less than 5 times nothing happens. So I added an else statement so now the user can click a list item and go to the detail activity. An ad will still show after every 5 clicks but won't be "stale" in between ads. Here's the working code:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Get item at position
RowData item = (RowData)parent.getItemAtPosition(position);
final Intent intent = new Intent(MainActivity.this, DetailActivity.class);
mInterstitialAd.setAdListener(new AdListener() {
#Override
public void onAdClosed() {
requestNewInterstitial();
startActivity(intent);
}
});
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
int clickCount = prefs.getInt(KEY_CLICK_COUNT, 1);
if (clickCount % 5 == 0) {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
} else {
startActivity(intent);
}
}else{
startActivity(intent);
}
clickCount++;
prefs.edit().putInt(KEY_CLICK_COUNT, clickCount).apply();
//Start details activity
//startActivity(intent);
}
});
You could do something like this in your ListView's OnItemClickListener:
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
int clickCount = prefs.getInt(KEY_CLICK_COUNT, 0);
if (clickCount > 0 && clickCount % 5 == 0) {
showAd();
}
clickCount++;
prefs.edit().putInt(KEY_CLICK_COUNT, clickCount).apply();
There are many ways you could do that, it just depends on what is easiest for you.
1) As Daniel K mentioned in his comment, a counter variable, kept in the class itself, can just be incremented every time a click is registered
2) You can keep a slightly more persistent variable by using shared preferences (which will persist after the app is closed)
3) If you have a MyApplication class, you can use static variables there too which will serve the same function as option 1.
4) You could use a database (though that is likely too much work for that to be honest).
I personally would recommend shared preferences because it will keep track of the clicks even after a user closes and re-opens the app, that way, if a user clicks 4 times, closes the app, and comes back another day to click 4 more times (again and again), you will still get a result every 5 clicks as opposed to waiting for them to click 5 times in a single session.
-PGMac
I solved this issue with the following changes. I wanted to show it after every 3 clicks.
#Override
public void onClick(View view) {
int position = getAdapterPosition();
final Intent intent=new Intent(getActivity(),VideoPlayActivity.class);
intent.putExtra("data",childlistData.get(position).getData());
SharedPreferences prefs = getActivity().getPreferences(MODE_PRIVATE);
int clickCount = prefs.getInt(KEY_CLICK_COUNT, 1);
if (clickCount % 3 == 0) {
interstitial = new InterstitialAd(getActivity());
interstitial.setAdUnitId(getString(R.string.interstitial_full_screen));
AdRequest adRequest2 = new AdRequest.Builder().build();
interstitial.loadAd(adRequest2);
interstitial.setAdListener(new AdListener() {
public void onAdLoaded() {
interstitial.show();
}
#Override
public void onAdClosed() {
//Toast.makeText(getApplicationContext(), "Ad is closed!", Toast.LENGTH_SHORT).show();
startActivity(intent);
}
#Override
public void onAdFailedToLoad(int errorCode) {
//Toast.makeText(getApplicationContext(), "Ad failed to load! error code: " + errorCode, Toast.LENGTH_SHORT).show();
}
#Override
public void onAdLeftApplication() {
// Toast.makeText(getApplicationContext(), "Ad left application!", Toast.LENGTH_SHORT).show();
}
#Override
public void onAdOpened() {
//Toast.makeText(getApplicationContext(), "Ad is opened!", Toast.LENGTH_SHORT).show();
}
});
System.out.println(" divisible by 3 "+clickCount);
}else{
System.out.println("not divisible by 3 "+clickCount);
startActivity(intent);
}
clickCount++;
System.out.println("Counter Value"+clickCount);
prefs.edit().putInt(KEY_CLICK_COUNT, clickCount).apply();
}

get data from DialogFragment to the Fragment

I have a Fragment in a Viewpager.
I am opening a DialogFragment from it which is taking the data from a ParseQuery. So far so good. Toast the clicked item also works.
I am trying to setText for a TextView in the Fragment that the dialog is called from without success... Anything i try just doesn't work - Intent, Bundle nothing... Going crazy with it already :)
I am not familiar with Interface and Callbacks, if that is needed. I don't know...
Thanks a lot in advance for any answer!!
Want to mention that i am not an advanced programmer, so any detailed explanation will be blessed :)
Here is the DialogFragment code - what i am trying to take from it and set to the TextView is pType.get(position).toString()
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ParseQuery<PropertyTypes> query = ParseQuery.getQuery(PropertyTypes.class);
query.whereExists("propertyType");
query.findInBackground(new FindCallback<PropertyTypes>() {
#Override
public void done(final List<PropertyTypes> pObjects, ParseException e) {
if (e == null) {
final ArrayList<String> pType = new ArrayList<String>();
for (PropertyTypes j : pObjects) {
pType.add(j.getTypeName());
}
ArrayAdapter arrayAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, pType);
mylist.setAdapter(arrayAdapter);
mylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
getDialog().dismiss();
Toast.makeText(getActivity(), pType.get(position).toString() + " was clicked", Toast.LENGTH_LONG).show();
// Intent...?
// Bundle...?
}
});
} else {
e.printStackTrace();
}
}
});
}
You can make use of setTargetFragment() method for this. For example, use setTargetFragment() while calling your Dialog Fragment
DialogFragment dialogFragment = new DialogFragment();
dialogFragment.setTargetFragment(this, REQUEST_CODE);
dialogFragment.show();
and on your onItemClick() inside DialogFragment do this
mylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dismiss();
Toast.makeText(getActivity(), pType.get(position).toString() + " was clicked", Toast.LENGTH_LONG).show();
Intent intent = new Intent();
intent.putStringExtra("yourKey", yourStringValue);
getTargetFragment().onActivityResult(
getTargetRequestCode(), Activity.RESULT_OK, intent);
}
});
and you can get that string value in your onActivityResult() of your calling/target Fragment
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case REQUEST_CODE:
if (resultCode == Activity.RESULT_OK) {
if(data!=null){
// set value to your TextView
textView.setText(data.getStringExtra("yourKey"));
}
}
break;
}
}
}
Hope this will help.

Android - Access ListView items when Activity is loaded

I have a listview populated with relativelayouts which have controls themselves. The problem is that I can't access these items before the activity UI is fully loaded (I get a null pointer exception. There's no OnActivityLoaded() method and here is what I tried to do:
Trying to access from OnStart() and OnResume();
I have a Custom Adapter but some of the functions I need to use
are in the main activity, so it's a no-go;
Using a Handler.postDelayed to access the elements after a given amount of
time. This works on high-end devices but on low-end ones the delay
time is not enough for loading (Even if I set it as high as 1000
ms) so I still get the null pointer exception.
So I need a better and proper way to access those widgets from the main activity.
Any thoughts? Is there a way to know when the UI is fully displayed?
Edit: here's my code that I need to access after the activity is loaded.
// These 4 widgets are ones from the relativelayout which is an item in the listview
homeSemester = (Spinner) findViewById(R.id.home_profile_semester);
homeSpecialty = (Spinner) findViewById(R.id.home_profile_specialty);
homefbPP = (ProfilePictureView) findViewById(R.id.home_profile_fbPP);
homefbName = (TextView) findViewById(R.id.home_profile_fbName);
// On click listeners
homeSemester.setOnItemSelectedListener(new OnItemSelectedListener()
{
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
// These functions need to be in the main activity (have access to widgets, savedInstance bundles and shared preferences
// Configure specialty
configSpecialty();
// Load Schedule
loadSchedule();
// Refresh contact list
loadContacts();
configurePush();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
Toast.makeText(getApplication(), "Please select your Semester!", Toast.LENGTH_SHORT).show();
Log.e("Initialization", "No semester selected! This should not happen!");
}
});
homeSpecialty.setOnItemSelectedListener(new OnItemSelectedListener()
{
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
// Load schedule
loadSchedule();
// Refresh contact list
loadContacts();
// Save Data
saveData();
configurePush();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
Log.e("Initialization", "No specialty selected! This should not happen!");
}
});
// All of these depend on homesemester and homespecialty
// Read data
readSemester();
readSpecialty();
// Show all button
contactAll.setOnClickListener(new OnClickListener()
{
public void onClick(View v) {
if(contactAll.isChecked())
loadAll();
else
loadContacts();
}
});
if(contactAll.isChecked())
loadAll();
else
loadContacts();
loadSchedule();
if (sharedPref.getInt("LoggedIn", 0) == 0)
{
// Actions taken on buttons click
fbLogin.setOnClickListener(new OnClickListener()
{
public void onClick(View v) {
if (fbLogin.getText().toString().equals("Log in with Facebook"))
{
// Welcome Message
ab.setSubtitle("Logging in...");
// Login to Facebook
NetAvailable = isNetworkAvailable();
if (NetAvailable)
{
logIn();
}
else
{
ab.setSubtitle("No Internet Connection!");
}
editor.putInt("LoggedIn", 1);
editor.commit();
}
else
{
// Log Out
AlertDialog.Builder builderfb = new AlertDialog.Builder(Launch.this);
builderfb.setTitle("Log Out")
.setMessage("Are you sure do you want to Log Out?\n\nNote: Logging out from Facebook will close the application. Next time you start ULFG2 App2Date, you will be prompted to Log in manually.")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
editor.putInt("LoggedIn", 0);
editor.commit();
finish();
}
});
AlertDialog welcomeMsg = builderfb.create();
welcomeMsg.show();
}
}
});
}
else
{
fbLogin.setOnClickListener(new OnClickListener()
{
public void onClick(View v) {
// Log Out only is needed
AlertDialog.Builder builderfb = new AlertDialog.Builder(Launch.this);
builderfb.setTitle("Log Out")
.setMessage("Are you sure do you want to Log Out?\n\nNote: Logging out from Facebook will close the application. Next time you start ULFG2 App2Date, you will be prompted to Log in manually.")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
editor.putInt("LoggedIn", 0);
editor.commit();
finish();
}
});
AlertDialog welcomeMsg = builderfb.create();
welcomeMsg.show();
}
});
}
homefbName.setText(sharedPref.getString("student_name", "Student"));
homefbPP.setProfileId(sharedPref.getString("student_id", ""));
}
In the onCreate():
ab = getSupportActionBar();
ab.setTitle("App2Date");
abDL = (DrawerLayout) findViewById(R.id.MainLayout);
abLV = (ListView) findViewById(R.id.list_slidermenu);
LayoutInflater mInflater = (LayoutInflater) getApplicationContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
navDrawerItems = new ArrayList<View>();
navDrawerItems.add(mInflater.inflate(R.layout.drawer_profile, null));
adapter = new NDListAdapter(getApplicationContext(), navDrawerItems);
abLV.setAdapter(adapter);
abLV.setDivider(null);
abLV.setDividerHeight(0);
// setting the nav drawer list adapter
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
abDT = new ActionBarDrawerToggle(this, abDL,
R.drawable.ic_navigation_drawer,
R.string.drawer_open,
R.string.drawer_close)
{
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(R.string.drawer_close);
}
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle(R.string.drawer_open);
}
};
abDL.setDrawerListener(abDT);
abDT.setDrawerIndicatorEnabled(true);
And I'm getting the null pointer exception in the onCreate() if I call the first lines of code (Under Edit:)

Android finishing activity not working

Once the user chooses a product from my ListView, it then puts the selected text from that ListView into an EditText. The problem I am having is when the user selects a product from the list, and then presses back, it comes up with the list again instead of returning to the EditText activity.
I have tried using "finish();" after the activity starts but nothing seems to be working.
Activity that holds the EditText that launches the List activity:
EditText CPU = (EditText) findViewById(R.id.autoCompleteTextView4);
CPU.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent CPUList = new Intent(getApplicationContext(),
CPUList.class);
startActivityForResult(CPUList, 1);
Intent i = getIntent();
String product = i.getStringExtra("key");
EditText CPU = ((EditText) findViewById(R.id.autoCompleteTextView4));
CPU.setText(product);
}
});
List view class
#Override
public void onCreate(Bundle OnsaveInstanceState) {
super.onCreate(OnsaveInstanceState);
setContentView(R.layout.activity_cpulist);
ListView listViewCPU = (ListView) findViewById(R.id.listViewCPU);
listViewCPU.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
String CPUList[] = {
"CPU's go here", "CPU's go here", "CPU's go here", "CPU's go here" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, CPUList);
listViewCPU.setAdapter(adapter);
listViewCPU.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listview, View myView,
int pos, long mylng) {
String CPU = (String) listview.getAdapter().getItem(pos);
Intent i = new Intent();
i.putExtra("key", CPU);
setResult(1, i);
finish();
}
});
You need to launch your activity in a way that it doesn't get added to back stack.
Here's how you do that: https://stackoverflow.com/a/12358563/375929
If I understand you correctly, you are calling finish() on the wrong Activity. If you want the list Activity to finish then that's where you need to call finish()
#Override
public void onItemClick(AdapterView<?> listview, View myView,
int pos, long mylng) {
String CPU = (String) listview.getAdapter().getItem(pos);
Intent i = new Intent(getApplicationContext(),
ListmenuActivity.class);
i.putExtra("key", CPU);
startActivity(getIntent());
startActivity(i);
finish(); // finish here
}
and remove finish() from your EditText Activity
Another issue I see is it looks like you are starting that second bit of code with the first using startActivityForResult() but you aren't sending back a result in your second code. Instead, you seem to be starting another Activity. It seems that second bit should be more like
#Override
public void onItemClick(AdapterView<?> listview, View myView,
int pos, long mylng) {
String CPU = (String) listview.getAdapter().getItem(pos);
Intent i = new Intent();
i.putExtra("key", CPU);
setResult(1, i);
finish(); // finish here
}

Categories

Resources