android passing parameter from a class to another - android

I have below snippet code to pass a parameter from a class (activity) to another class. To do so, used sharedPreferences, but i try to get in my secondclass the value that was saved in main activity , i am getting java.lang.Nullpointer exception. What I am doing wrong here?
public class Secondclass extends Activity {
//other functions....
private void get_file_name() {
final main m=new main();
String myvalue=m.set_paramater();
//I want to access FOLDER_NAME here
Log.e("TAG","the value "+myvalue);
}
}
public class main extends Activity{
String FOLDER_NAME;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FOLDER_NAME="a_name";
Save_file_name("APP_NAME",FOLDER_NAME);
}
private void Save_file_name(String key,String value){
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
public String set_paramater(){
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
String strSaveddata = sharedPreferences.getString("APP_NAME", "");
return strSaveddata;
}
}
}
Here is the trace file:
E/AndroidRuntime(10622): FATAL EXCEPTION: main
E/AndroidRuntime(10622): java.lang.NullPointerException
E/AndroidRuntime(10622): at android.content.ContextWrapper.getPackageName(ContextWrapper.java:120)
E/AndroidRuntime(10622): at android.app.Activity.getLocalClassName(Activity.java:3488)
E/AndroidRuntime(10622): at android.app.Activity.getPreferences(Activity.java:3522)

It is bad practice to instantiate an Activity from another Activity, in your case with the line:
final main m=new main();
Android handles the creation of all your activities and you shouldn't have to do it yourself. If you do it this way the Activity will not have a valid Application Context. Without a valid Application context getPreferences(MODE_PRIVATE) will return null.
Also, it is probably better to use:
PreferenceManager.getDefaultSharedPreferences(this)
Using getPreferences(...) will make the preferences private to your Activity. Using getDefaultSharedPreferences(this) will make your preferences available to other activities instead of just the Activity that created it. This allows you to share your data across your two activities.

Activity.getPreferences() retrieve a SharedPreferences object for accessing preferences that are private to this activity, which means in two activities you got different SharedPreferences.
You may use Context.getSharedPreferences() with same name to get same SharedPreferences

final main m=new main();
It is wrong!
as you are using
SharedPreferences sharedPreferences = gePreferences(MODE_PRIVATE);
which required Context. Which is null at the time when you call set_paramater()
Just make set_paramater() in Secondclass. It will solve your problem!
package com.example.test;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class main extends Activity {
String FOLDER_NAME;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FOLDER_NAME = "a_name";
Save_file_name("APP_NAME", FOLDER_NAME);
Button nextButton=(Button)findViewById(R.id.next_button);
nextButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(main.this,Secondclass.class));
}
});
}
private void Save_file_name(String key, String value) {
SharedPreferences sharedPreferences = getSharedPreferences(
"myPreffFile", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
}
and...
package com.example.test;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class Secondclass extends Activity {
// other functions....
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button nextButton = (Button) findViewById(R.id.next_button);
nextButton.setText("Show Value");
nextButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
get_file_name();
}
});
}
private void get_file_name() {
Toast.makeText(this, set_paramater(), Toast.LENGTH_SHORT).show();
}
public String set_paramater() {
SharedPreferences sharedPreferences = getSharedPreferences(
"myPreffFile", MODE_PRIVATE);
String strSaveddata = sharedPreferences.getString("APP_NAME", "");
return strSaveddata;
}
}
NOTE: it is fully test code. I run this..if still error came then the fault is in other place.

Not an answer to your problem but just some info. You can share data among activities of your application by extending the Android Application class.
Extend the Application class and create your own class.
package com.foo.bar;
import android.app.Application;
public class MyApplication extends Application {
private boolean foo;
#Override
public void onCreate() {
foo = false;
}
public void SetFoo(boolean fooValue) {
foo = fooValue;
}
public boolean GetFoo() {
return foo;
}
}
Your manifest must set the application class.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.foo.bar"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="16"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:name=".MyApplication">
<activity
android:label="#string/app_name"
android:name=".MyActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Your can access the application class instance within an activity like this.
MyApplication mApp = (MyApplication)getApplication();

Related

Shared Preference not holding session (Android K)

I am having a project which uses Shared Preferences for Session Management. Everything is fine with the code but what really annoying is that the app is holding the session in Android Lollipop and above but unfortunately it is not holding the same for Android Kitkat and below. The session is lost whenever the app is closed and you have to lo in again. Following are the codes, I am using:
Session.java
package com.saptak.disputesession;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.HashMap;
/**
* Created by Saptak Das on 27-02-2017.
*/
public class Session {
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
Context context;
public static String KEY_FNAME="namef";
public static String KEY_LNAME="namel";
public static String IS_LOGIN;
public Session(Context context) {
this.context = context;
sharedPreferences=context.getSharedPreferences("userdetails",0);
editor=sharedPreferences.edit();
}
public void CreateLoginSession(String fname,String lname)
{
editor.putString(KEY_FNAME,fname);
editor.putString(KEY_LNAME,lname);
editor.putString(IS_LOGIN,"logged");
editor.commit();
}
public HashMap<String,String> getdetails()
{
HashMap<String,String> details=new HashMap<>();
details.put(KEY_FNAME,sharedPreferences.getString(KEY_FNAME,null));
details.put(KEY_LNAME,sharedPreferences.getString(KEY_LNAME,null));
return details;
}
public boolean loginstatus()
{
if(sharedPreferences.getString(IS_LOGIN,"unlogged").equals("logged"))
{
return true;
}
else
{
return false;
}
}
public void logoutac()
{
editor.clear();
editor.commit();
}
}
Login.java
package com.saptak.disputesession;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
/**
* Created by Saptak Das on 27-02-2017.
*/
public class Login extends Activity {
Button login;
EditText first,last;
Session session;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
session=new Session(getApplicationContext());
login=(Button)findViewById(R.id.log);
first=(EditText)findViewById(R.id.fname);
last=(EditText)findViewById(R.id.lname);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
session.CreateLoginSession(first.getText().toString(),last.getText().toString());
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
}
});
}
}
MainActivity.java
package com.saptak.disputesession;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
Session session;
Boolean flag;
TextView tf,tl;
Button logout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
session=new Session(getApplicationContext());
tf=(TextView)findViewById(R.id.xfname);
tl=(TextView)findViewById(R.id.xlname);
logout=(Button)findViewById(R.id.xlogout);
flag=session.loginstatus();
if(flag==false)
{
startActivity(new Intent(getApplicationContext(),Login.class));
finish();
}
HashMap<String,String> details=session.getdetails();
tf.setText(details.get(Session.KEY_FNAME));
tl.setText(details.get(Session.KEY_LNAME));
logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
session.logoutac();
startActivity(new Intent(getApplicationContext(),Login.class));
finish();
}
});
}
}
This problem is getting on my nerves now as the app is perfectly coded, please help me out. Thanks in advance!
Update:
Please note, the problem is not about deleting the session, its completely opposite. The session is logging itself out everytime i am closing the app. and this problem is only in case of Android Kitkat and below, works fine for Android Lollipop and above
SharedPreferences allow you to save and retrieve data in the form of key,value pair.
Mistake
public static String IS_LOGIN="logged"; // Init here
FYI
Session are useful when you want to store user data globally through
out the application.
Rectify your method
public void CreateLoginSession(String fname,String lname)
{
editor.remove(KEY_FNAME); //Remove at first
editor.remove(KEY_LNAME);
editor.remove(IS_LOGIN);
editor.putString(KEY_FNAME,fname);
editor.putString(KEY_LNAME,lname);
editor.putString(IS_LOGIN,"logged");
editor.commit();
}

Continue from the last counter when reopen the android application

I am new in Android programing. I want to make an application. The button text increase whenever the user click on it. My counter is reseted when the application is closed. How can I store the last counter value and call it again when the application is reopened?
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
private int c;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.buttonClick);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
c++;
button.setText(Integer.toString(c));
}
});
}
}
EDIT:
I try to use this Shared Preferences but I got eror about "setSilent" and "mSilentMode". Help please
My new code
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
private int c;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
final Button button = (Button) findViewById(R.id.buttonClick);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
c++;
button.setText(Integer.toString(c));
}
});
}
#Override
protected void onStop(){
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
// Commit the edits!
editor.commit();
}
}
It depends, are you asking how to preserve a variable across an app's lifespan or between different lifespans?
If it's across different lifespans, you can write it to disk and then read it onCreate.
If you need to do it across one lifespan, it depends on your use case, but generally putting it in a global, static variable would do the trick!
If this is unclear and you'd like some sample code, please, don't be afraid to ask! : )
You can save your c value in the Preference when your activity is going to be closed, and when you rise up your activity you set your c variabile to the previous value
Use this snippet out of your onClickListener: To get the int if there is any
SharedPreferences hhii = getSharedPreferences("c_value", MODE_PRIVATE);
int ca = hhii.getInt("c_value2", 0);
button.setText(ca+"");
Use this in your onClickListener: To save the int as the user clicks the button-much better than saving it in onBackPressed or OnDestroy or whatever
c++;
button.setText(Integer.toString(c));
SharedPreferences hhii = getSharedPreferences("c_value", MODE_PRIVATE);
hhii.edit().putInt("c_value2",c).commit();
Regards from Iran,
Gabriel

Update widget when preferences changed using custom broadcast

I need to update my app's widget every time the settings are changed by the user.
I have a settings activity:
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
public class SettingsActivity extends Activity implements SharedPreferences.OnSharedPreferenceChangeListener {
public static final String customIntent = "CUSTOM_SETTINGS_CHANGED";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new MainActivity.SettingsFragment())
.commit();
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
Intent intent = new Intent();
intent.setAction(customIntent);
this.sendBroadcast(intent);
}
}
I've added that custom intent to the manifest:
<action android:name="CUSTOM_SETTINGS_CHANGED" />
But the widget is not updated immediately after the settings are changed. So my custom broadcast either is not sent or not received. What's wrong with my code?
// this part important in manifest declaration
package com.xmpls.onetwothree.abc;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
public class SettingsActivity {
public class SettingsActivity extends Activity implements
SharedPreferences.OnSharedPreferenceChangeListener {
// Change like this
public static final String CUSTOM_SETTINGS_CHANGED = "com.xmpls.onetwothree.abc.custompls";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction();
/* More code here. . .*/
}
/* And some here. . .*/
}
================================================================================
and in manifest U must registred ACTION like this:
<action android:name="com.xmpls.onetwothree.abc.CUSTOM_SETTINGS_CHANGED" />
I've used a different approach.
In my main activity I've added this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
<...>
SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
Intent intent = new Intent();
intent.setAction(customIntent);
sendBroadcast(intent);
}
};
<...>
}
It seems that onSharedPreferenceChanged was never called for some reason. I don't know why but at least I've found a way to make this work.

Access defaultSharedPreferences in class from service

Long story short, I have a class that handles my app shared preferences.
I call it from various other classes without issues, but when I try to call it from my service (from the same APK) I get a null exception. I am guessing that it's getting called from the wrong context or something like that. Here is the relevant code.
MainActivity.java
package com.deskwizard.audiomanager;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import com.deskwizard.audiomanager.DataSaveRestore;
public class MainActivity extends FragmentActivity {
public static Context contextOfApplication;
final FragmentManager fm = getFragmentManager();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contextOfApplication = getApplicationContext();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_settings, new FadeBalanceFragment());
ft.commit();
// TODO: Load previously saved settings for all values
DataSaveRestore.restore_all();
// TODO: init I2C
}
public static Context getContextOfApplication() {
return contextOfApplication;
}
}
DataSaveRestore.java (defaultpreferences class)
package com.deskwizard.audiomanager;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
public class DataSaveRestore extends Application {
// Data variables
public static int Bass_level, Bass_CFreq, Bass_Qfact, Sub_level,
Sub_Lowpass, Treble_level, Treble_CFreq, Mid_level, Mid_CFreq,
Mid_Qfact, Fade, Balance, Loudness_level, Loudness_freq,
Loudness_boost;
static boolean Bass_DCMode, Loudness_state;
static Context applicationContext = MainActivity.getContextOfApplication();
public static void restore_all() {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(applicationContext);
if (prefs.getInt("data_saved", 0) == 0) {
set_defaults();
load_defaults();
} else {
load_defaults();
}
//TODO: send settings to TDA7418
DS3903.set_lowpass(DataSaveRestore.Sub_Lowpass);
};
Service code snippet:
public class AudioManagerService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO do something useful
Log.d("com.deskwizard.audiomanager", "starting service...");
DataSaveRestore.restore_all(); // restore settings to TDA7418/DS3903
start();
return Service.START_STICKY;
}
The Null Exception error refers to this line, only when called from the service, it works properly from the main application and other classes:
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(applicationContext);
Let me know if any further code can help narrow it down.
Thanks,
DW
Because, In your service when you call, DataSaveRestore.restore_all(); It make reference on, (As there is no MainActivity context available from Servce)
static Context applicationContext = MainActivity.getContextOfApplication();
on this line, applicationContext will be null as it can't find MainActivity initialization
Simply, Just change your restore_all() method from Application class.
First remove static and and use getApplicationContext() of Android application class method to get application context as in Service,
public void restore_all() {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
if (prefs.getInt("data_saved", 0) == 0) {
set_defaults();
load_defaults();
} else {
load_defaults();
}
//TODO: send settings to TDA7418
DS3903.set_lowpass(DataSaveRestore.Sub_Lowpass);
};
Now call, restore_all(); by initializing object of Application class not a static way.
Like,
DataSaveRestore dataSaveRestore = (DataSaveRestore) getApplicationContext();
dataSaveRestore.restore_all();

Cannot access SharedPreferences in constructor

I use SharedPreferences for storing data. When I try to call the data-storing function from the constructor of my class, it shows a Runtime error. However, when I call the function from onCreate() it works fine.
Is there any way I can call my data-storing function from the constructor?
package com.examples.storedata;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Activity1 extends Activity
{
EditText editText1, editText2;
TextView textSavedMem1, textSavedMem2;
Button buttonSaveMem1, buttonSaveMem2;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textSavedMem1 = (TextView)findViewById(R.id.savedmem1);
textSavedMem2 = (TextView)findViewById(R.id.savedmem2);
editText1 = (EditText)findViewById(R.id.edittext1);
editText2 = (EditText)findViewById(R.id.edittext2);
buttonSaveMem1 = (Button)findViewById(R.id.save_mem1);
buttonSaveMem2 = (Button)findViewById(R.id.save_mem2);
buttonSaveMem1.setOnClickListener(buttonSaveMem1OnClickListener);
buttonSaveMem2.setOnClickListener(buttonSaveMem2OnClickListener);
}
public Activity1()
{
LoadPreferences(); //show error while calling from here
}
Button.OnClickListener buttonSaveMem1OnClickListener
= new Button.OnClickListener(){
public void onClick(View arg0) {
SavePreferences("MEM1", editText1.getText().toString());
LoadPreferences();
}
};
Button.OnClickListener buttonSaveMem2OnClickListener
= new Button.OnClickListener(){
public void onClick(View arg0) {
SavePreferences("MEM2", editText2.getText().toString());
LoadPreferences();
}
};
private void SavePreferences(String key, String value)
{
SharedPreferences sharedPreferences = getPreferences(MODE_APPEND);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.putInt("1",5);
editor.commit();
}
private void LoadPreferences()
{
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
String strSavedMem1 = sharedPreferences.getString("MEM1", "");
String strSavedMem2 = sharedPreferences.getString("MEM2", "");
textSavedMem1.setText(strSavedMem1);
textSavedMem2.setText(strSavedMem2);
}
}
You are attempting to access your text views before you have initialised the view or the variables:
textSavedMem1.setText(strSavedMem1);
textSavedMem2.setText(strSavedMem2);
When you call LoadPreferences from the Activity constructor, onCreate hasn't yet been called, which means textSavedMem1 and textSavedMem2 have not been initialised and are null.
When you call it from onCreate, so long as it is after the following, then these variable are initialised and everything works as expected.
setContentView(R.layout.main);
textSavedMem1 = (TextView)findViewById(R.id.savedmem1);
textSavedMem2 = (TextView)findViewById(R.id.savedmem2);
This is normal. By the time your activity is created e.g when the constructor is called SharePreferences object is not yet accessible. It's not good practice to use/override activity's constructor. Read about activity lifecycle to get the idea how to use activity.
Its not possible since u can get SharedPreference in activity which has already been created.. here u r trying to get SharedPreference even before activity is under construction (Constructor).. for getting shared preference u need activity..
U can store the values in some Instance variables inside constructor then put them in SharedPreference...

Categories

Resources