How to call public class in android java - java

this is my public class in android!
public class Logout {
public SharedPreferences pref;
public Logout(Context context){
pref = context.getSharedPreferences(LoginActivity.loginpreferences, context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.remove(LoginActivity.name_user);
editor.remove(LoginActivity.type_user);
editor.remove(LoginActivity.id_user);
editor.commit();
}
}
to call class when clicking button (logout) I wrote the code in the following way
private OnClickListener clickitempanel = new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int id = v.getId();
switch(id){
case 4:
Logout logout = new Logout(mContext);
// logout.notifyAll();
logout.getClass();
Intent in = new Intent();
in.setClass(mContext, FullscreenActivity.class);
mContext.startActivity(in);
break;
}
}
};
textViewItem.setOnClickListener(clickitempanel);
but doesn't running code remove keys from SharedPreferences !

Do you have a listener on that button? Are you sure it is working ?
Also, you people would normally put that logout code in a method instead of in the constructor.

Hint:
Remember to make as less as it is is possible in body of Constructor. Init your variables and avoid call any methods. Only methods which you could call in Constructor are final methods (private method also should be with final statement).

Related

Cannot be referenced from a static context

I have the following problem, I am trying to call InterstitialLaunch.java from MainActivity.java to display Interstitial, however, in my case it reports an error from MainActivity.java and says that 'inter_launched (android.content.Context)' cannot be referenced from a static context.
What can be done about this problem and how to solve the problem, some idea, thanks.
InterstitialLaunch.java
public class InterstitialLaunch extends Activity {
public void inter_launched(Context mContext) {
SharedPreferences prefs = mContext.getSharedPreferences("interlaunch", 0);
SharedPreferences.Editor editor = prefs.edit();
// Increment launch counter
long launch_count = prefs.getLong("launch_count", 0) + 1;
editor.putLong("launch_count", launch_count);
// Get date of first launch
Long date_firstLaunch = prefs.getLong("date_firstlaunch", 0);
if (date_firstLaunch == 0) {
date_firstLaunch = System.currentTimeMillis();
editor.putLong("date_firstlaunch", date_firstLaunch);
}
// Wait at least n days before opening
if (launch_count >= LAUNCHES_UNTIL_PROMPT) {
if (System.currentTimeMillis() >= date_firstLaunch +
(DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000)) {
interstitialLaunch(mContext, editor);
}
}
editor.apply();
}
public void interstitialLaunch(final Context mContext, final SharedPreferences.Editor editor) {
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
Map<String, AdapterStatus> statusMap = initializationStatus.getAdapterStatusMap();
for (String adapterClass : statusMap.keySet()) {
AdapterStatus status = statusMap.get(adapterClass);
Log.d("MyApp", String.format(
"Adapter name: %s, Description: %s, Latency: %d",
adapterClass, status.getDescription(), status.getLatency()));
}
InterstitialAd.load(getApplicationContext(),
getString(R.string.interstitial_id),
new AdRequest.Builder().build(),
new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
interstitialAd.show(InterstitialLaunch.this);
}
}
);
}
});
}
}
MainActivity.java
InterstitialLaunch.inter_launched(MainActivity.this);
Shows this error in MainActivity.java:
Non-static method 'inter_launched(android.content.Context)' cannot be referenced from a static context
In Java, something like ClassName.method() means invoking a static method.
Your inter_launched is not a static but a dynamic (instance) method because the method doesn't have static modifier.
If you would invoke an instance method, you must do something like instanceOfTheClass.method().
For example:
InterstitialLaunch interstitialLaunch = new InterstitialLaunch();
interstitialLaunch.inter_launched(MainActivity.this);
In order to call that inter_launched(Context) function from outside the class, you first need to instantiate the class.
This isn't a good example, because it isn't a good practice to create an instance of an activity, and then to call a function from it, from another class.
For your code to work, you can just override the onCreate function in the InterstitialLaunch Activity, and call the inter_launched(Context) inside it.
Now to create this activity, you just need to create an intent and start the activity. Here's an example:
Intent intent = new Intent(context, InterstitialLaunch.class)
startActivity(intent)
Let me know if it worked for you!

Using a global Variable inside a class

I'm using android studio for a project api 21 minimum,
I have an activity with a textfield and a button, when click, I want the text of the textfield stored for the life of the application, I'm using a global variable for that.
I've got a class variable that extends Application:
package com.example.user.variableglobale;
import android.app.Application;
public class Variable extends Application {
private String chiffre;
public String getChiffre() {
return this.chiffre;
}
public void setChiffre(String chiffre) {
this.chiffre = chiffre;
}
inside my main :
final Variable VG = (Variable) getApplication();
final TestVar tV = new TestVar();
btnOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tV.testVar(MainActivity.this);
VG.setChiffre(String.valueOf(txt.getText()));
}
});
and here is the java class called with the button:
public class TestVar {
public void testVar(Context context) {
Variable VG = (Variable) context.getApplicationContext();
String temp = VG.getChiffre();
Toast.makeText(context.getApplicationContext(), "test java VG " + temp, Toast.LENGTH_SHORT).show();
}
}
Can anyone explain the way to use global variable inside java class?
When I click on the button, a toast appears with a "null" value for "temp" (seem to be not initialized).
In my example, I tried with "context", to no avail.
ok, finally it work,
inside my onclickListener i have to swap declaration of variable and calling of my class... everything ok
I think a better way to store that variable would be to store it in shared preferences. You can access it in any activity and it persists even if app is closed.
You can use it withoud needing a class for variable like this.
main:
static final String CHIFFRE_KEY = "chiffre_key";
final TestVar tV = new TestVar();
btnOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(CHIFFRE_KEY, String.valueOf(txt.getText()));
editor.commit();
tV.testVar(MainActivity.this);
}
});
and testVar method would look like this
public void testVar(Context context) {
String vg = getActivity().getPreferences(Context.MODE_PRIVATE).getString(CHIFFRE_KEY);
Toast.makeText(context.getApplicationContext(), "test java VG " + vg, Toast.LENGTH_SHORT).show();
}
You can read more about Shared Preferences here

onResume() getting called on pressing back arrow. Please see details

I have a method in onResume() which fetches user's data and should get called when user launch the app. This is working fine.
The problem is that for example after opening 'Settings' when I tap/click on the back arrow, the method in onResume() gets called again and user data starts getting fetched again.
What I want is, I want that method to get called only when user launches the app and not every time the user transition back from settings to main activity.
Here's the onResume() in MainActivity.java:
#Override
protected void onResume() {
super.onResume();
fetchUserData();
}
Here's how I transition to Settings.java:
Intent settingsIntent = new Intent(MainActivity.this, SettingsActivity.class);
startActivity(settingsIntent);
Please let me how can I restrict the fetchUserData() to get called only when user launches the app and not again when user transition back to main activity from any other activity by tapping/clicking on back arrow.
Sorry, if question seems to be badly formatted. I'm still a beginner here.
if you want the method to be called only once when the activity opens move it inside OnCreate() method.OnResume() can be called several times.You can see the documentation of acttivity lifecycle here
You could adapt the following code, by setting a flag/indicator so that only wanted returns are processed (eg set resume_state to RESUMESTATE_NOTHING except when starting an intent after which you want to fetchUserData:-
public class AisleListByCursorActivity extends AppCompatActivity {
public final static int RESUMESTATE_NOTHING = 0;
public final static int RESUMESTATE_AISLEADD = 1;
public final static int RESUMESTATE_AISLESTOCK = 2;
public final static int RESUMESTATE_AISLEDELETE =3;
public final static int RESUMESTATE_AISLEUPDATE = 4;
public int resume_state = RESUMESTATE_NOTHING;
public ShopsCursorAdapter currentsca;
public AislesCursorAdapter currentaca;
public ShopListSpinnerAdapter currentslspa;
public long currentshopid;
private final static String THIS_ACTIVITY = "AisleListByCursorActivity";
private final ShopperDBHelper shopperdb = new ShopperDBHelper(this,null, null, 1);
private ListView aisleslistview;
private Cursor csr;
private int shopid = 0;
protected void onResume() {
super.onResume();
switch (resume_state) {
case RESUMESTATE_AISLEADD:case RESUMESTATE_AISLEUPDATE: {
Cursor csr = shopperdb.getAislesPerShopAsCursor(currentshopid);
currentaca.swapCursor(csr);
resume_state = RESUMESTATE_NOTHING;
break;
}
default: {
resume_state = RESUMESTATE_NOTHING;
}
}
}
........
public void aalbcadd(View view) {
resume_state = RESUMESTATE_AISLEADD;
Intent intent = new Intent(this,AisleAddActivity.class);
intent.putExtra("Caller",THIS_ACTIVITY);
intent.putExtra("SHOPID", currentshopid);
startActivity(intent);
}
Create method in OnStart() or onCreate() rather than onResume(). for reference - please see this link for better understanding of Android LifeCycle http://developer.android.com/reference/android/app/Activity.html
If you want your method to be called only once you must put that method in onCreate method of Activity. Because onResume is always called you come back to the activity as per Android lifecycle. So just replace you method fetchUserData(); into onCreate like below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_list);
fetchUserData();
}
#Override
protected void onResume() {
super.onResume();
}

Android how to pass an Activity.class as an argument for a function

I recently moved to Android from Python and am stuck here.
This is my class declaration to create a common function for an Alert Dialog which accepts necessary parameters:
public static AlertDialog.Builder getAlertDialog(String strArray[],
String strTitle, Activity v) {
return new AlertDialog.Builder(v)
.setTitle(strTitle).setItems(strArray,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
}
But I cannot call this function via this piece of code which gives me an error:
getAlertDialog(strArray, strTitle, MakeCall.class).show();
The error is:
the method getAlertDialog(String[], String, Activity) in the type MakeCallAlertDialog is not applicable for the arguments (String[], String, Class<TestActivity>)
How can I get this correctly?
call like this:
ButtonClickBySani(R.id.btnsehrabandi, sehrabandiActivity.class);
Definition:
private void ButtonClickBySani(int ButtonId, final Class<? extends Activity> ActivityToOpen)
{
Button btn;
// Locate the button in activity_main.xml
btn = (Button) findViewById(ButtonId);
// Capture button clicks
btn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
startActivity(new Intent(getBaseContext(), ActivityToOpen));
// Start NewActivity.class
//Intent myIntent = new Intent(getBaseContext(), ActivityToOpen);
// startActivity(myIntent);
}
});
}
If you just want to pass a reference to your Activity use: MakeCall.this (or maybe just this.)
Just create an activity object/instance like new YourActivity().
public static void Redirect(Context context,Activity page) {
..... //code
context.startActivity(new Intent(context,page.getClass()));
((Activity) context).finish();
}
and use this method as
Redirect(Registration.this, new YourActivity());
I think you want to pass this. If this doesn't work, use MakeCall.this.
getAlertDialog(strArray, strTitle, this).show();
You need the instance. Use this or SampleActivity.this.
This works for me:
private void switchActivity(Class cls){
Intent intent = new Intent(HomeActivity.this, cls);
startActivity(intent);
}
Call the function like this: switchActivity(DestinationActivity.class)
In Java, each class you write will also have a Class class attached to it. The Class class will be used by the classloader etc.
As others have said you should use MakeCall.this instead of MakeCall.class because MakeCall.this will point to itself which is an Activity whilst MakeCall.class will point to MakeCall's attached Class class.

Does this snippet cause an infinite loop or other?

Only on old android devices (2.x) I've a crash caused by stackoverflow everytime I rotate emulator. If I comment "preferenze()" emulator does not crash but app does not keep new settings. Can this code create an infinite loop? Is a incorrect code? What should be to runs correctly? Thanks!
private boolean preferencesChanged;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
private void preferenze() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
CheckboxPreference = prefs.getBoolean("checkboxPref", true);
ListPreference = prefs.getString("listpref", "");
numeronotifiche = prefs.getString("notify", "");
Sound = prefs.getString("sound", "");
barranotifiche = prefs.getBoolean("keep", false);
natura = prefs.getBoolean("suoninaturasino", false);
snatura = prefs.getString("suoninaturascelta", "");
snaturaold = prefs.getString("snaturaoldvalue", "");
if (snaturaold != snatura){
stopService(new Intent(this, UnUsedService.class));
}
SharedPreferences prefs2 = getSharedPreferences(PRIVATE_PREF, 0);
Editor editor10 = prefs2.edit();
editor10.putString("snaturaoldvalue", snatura);
editor10.commit();
// suoni attivati (o no)
if (natura){
startService(new Intent(this, UnUsedService.class));
}
else {
stopService(new Intent(this, UnUsedService.class));
}
if (barranotifiche){
showNotification();
}
else {
cancelNotification();
}
GestioneAllarme alarm = new GestioneAllarme();
if (CheckboxPreference){
if (numeronotifiche.equals("3")){
alarm.CancelAlarm(this);
alarm.SetAlarm3(this);
}
else if (numeronotifiche.equals("1")){
alarm.CancelAlarm(this);
alarm.SetAlarm1(this);
}
else if (numeronotifiche.equals("2")){
alarm.CancelAlarm(this);
alarm.SetAlarm2(this);
}
else {
//
}
}
else {
//
GestioneAllarme alarm2 = new GestioneAllarme();
alarm2.CancelAlarm(this);
}
//
if (Sound.equals("")){
Sound = "2";
Editor editor = prefs.edit();
editor.putString("sound", "2");
editor.commit();
}
if (ListPreference.equals("")){
ListPreference = "1500";
Editor editor = prefs.edit();
editor.putString("listpref", "1500");
editor.putInt("indexfade", 1500);
editor.commit();
}
if (numeronotifiche.equals("")){
numeronotifiche = "2";
Editor editor = prefs.edit();
editor.putString("numeronotifiche", "2");
editor.commit();
}
fade = Integer.parseInt(ListPreference);
notify = Integer.parseInt(numeronotifiche);
if (fade == 500){
animazione = R.style.MyCustomTheme1;
fadein = R.anim.fadein500;
fadeout = R.anim.fadeout500;
}
else if (fade == 1000){
animazione = R.style.MyCustomTheme2;
fadein = R.anim.fadein1000;
fadeout = R.anim.fadeout1000;
}
else if (fade == 1500){
animazione = R.style.MyCustomTheme3;
fadein = R.anim.fadein1500;
fadeout = R.anim.fadeout1500;
}
else if (fade == 2000){
animazione = R.style.MyCustomTheme4;
fadein = R.anim.fadein2000;
fadeout = R.anim.fadeout2000;
#Override
protected void onResume() {
super.onResume();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
preferencesChanged = true;
}
};
sp.registerOnSharedPreferenceChangeListener(listener);
protected void onStop(){
super.onStop();
if(preferencesChanged){
//Update the app
preferenze();
}
}
public class Preferences extends PreferenceActivity implements OnSharedPreferenceChangeListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.preferences);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String listpref) {
It seems that as soon as preferenze() always modify the shared preferences you will have an infinite loop.
Since you didn't post the complete code it's difficult to say. But I guess that your code is such that it always modify prefs only on android 2.x
you can try something like this to avoid infinite loop.
private boolean isPreferenzeRunning = false;
...
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String listpref) {
if(!isPreferenzeRunning)preferenze();
}
};
...
private void preferenze()
isPreferenzeRunning = true;
try{
...
}finally{isPreferenzeRunning = false;}
}
That code wouldn't even compile.
The code in preferenze() will return the preference values (boolean, String, int, etc), not the Preference objects. By changing the values in that method, you will also cause a StackOverflowError.
What is the need for a OnSharedPreferenceChangeListener?
// here several if/if else to change value
Those sentences probably change the Shared Preferences, that in turn will fire your listener, which in turn will call preferenze, ..., and so on. If this continues for ever, a S.O will be thrown. Now depending on the conditions it could happen that the preferenze method only reads but does not modify anything. In this case the loop will end.
And about the error being observed in 2.X devices only, it could be due to 4.x devices being more recent and probably having more RAM memory.
UPDATE:
The code is still incomplete. Looks like there are two activities: the one you posted first and the new one. I guess (that's all I can do with the code you posted) you have a PreferenceActivity to show the settings and allow the user to change them, and the listener is there to update other parts of the application according to the new settings. The problem is that when the listener is called, it itself modifies the settings, and this in turn will call the listener again, which will modify the preferences again, and so on. This will throw an SOException once the heap runs out of memory.
A way of rearranging the code to solve this would be:
Register the OnSharedPreferenceChangeListener in your activity's onResume instead of onCreate, and deregister it in the onPause method (calling unregisterOnSharedPreferenceChangeListener). Deregistering is very important because we don't want to listen for changes once the user leaves the screen, or the activity is recreated by the system (for instance when the device rotates):
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//We have removed the listener registration from here
}
#Override
protected void onResume() {
super.onResume();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String listpref) {
//I'll show what to do here in point 2.
}
};
sp.registerOnSharedPreferenceChangeListener(listener);
}
#Override
protected void onPause() {
super.onPause();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.unregisterOnSharedPreferenceChangeListener(listener);
}
With your current code, each time the user changes a single setting, the preferenze method is called to update the app. So if it changes 5 fields, the method is called 5 times. What we could do now is to check for changes just once. I assume you don't care how many fields the user has changed, since all you need is to know if there are changes or not. So in the listener, instead of calling preferenze, you could set a boolean flag to true:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
preferencesChanged = true;
}
Ok, so now we have a way of telling whether the settings have changed or not. When the user is done and the activity is about to be closed, the methods onPause, onStop and onDestroy will be called in this order. You can use one of these methods to check the boolean flag and only if there are changes, update the app. This way, if the user changes 1, 3 or 20 fields, we will update the app just once at the end. You can do this in any of the 3 thethods, but it's very important to do this AFTER deregistering the listener (onPause), or else you'll run into problems again. Example:
protected void onStop(){
super.onStop();
...
if(preferencesChanged){
//Update the app
preferenze();
}
}
You might need to change some things but overall you get the idea.

Categories