I am still learning Android development and I am stuck at a point where I assume I am doing something wrong. Would appreciate your help.
I have my main class that extends AppCompatActivity like this, and inside it, I have a function that instantiates another class where I want to do some calculations based on the store sharedpreferences:
public class Level1_0 extends AppCompatActivity {
.....
public void isTwoUnlocked(){
CalculateAvg calc = new CalculateAvg();
boolean L = calc.level2();
if(L == true){
showPopup();
calc.finish();
}
}
.....
}
CalculateAvg is the class I am instantiating. That class has a method called level2(), this is where I do some checks and return True or False as boolean. When I run the code, init() never gets called by onCreate(). I also tried writing the entire code of init inside onCreate itself, still same problem, onCreate never gets triggered.
CalculateAvg class
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
public class CalculateAvg extends AppCompatActivity{
public static final String SHARED_PREFS = "sharedPrefs";
private static final String TAG = "Level1_0";
level10 = sharedPreferences.getBoolean(LEVEL10, false);
........
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
public void init(){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
........
// do my calculations here but init() never gets called by onCreate().
// I even tried writing entire code inside onCreate but it also didn't work
}
public boolean level2(){
boolean L = false;
if(level10 == null){
L = false;
}
else{
L = true;
}
return L;
}
}
Any idea why onCreate is not getting triggered when I instantiate it in my main class?
According your requirements there is no need to use AppCompatActivity. You can simply use like class and pass context to access SharedPreferences.
public class CalculateAvg {
private Context mContext;
....
public CalculateAvg(Context context) {
mContext = context;
init();
}
public void init(){
SharedPreferences sharedPreferences = mContext.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE);
....
}
public boolean level2(){
boolean L = false;
if(level10 == null){
L = false;
}
else{
L = true;
}
return L;
}
}
And instantiate CalculateAvg with your activity's context like below:
CalculateAvg calc = new CalculateAvg(Level1_0.this);
This Android not a java you can not call activity with creating new instance to call CalculateAvg from Level1_0 do below code in Level1_0 onCreate().
public class Level1_0 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent =new Intent(this,CalculateAvg.class);
startActivity(intent);
}
}
Related
I am an android beginner and tried almost every method to use Shared Preferences but when I try to get value in nonactivity class method doesn't work ONLY IF APP REMOVED FROM RECENT APPS.
My Scenario is like:
Class LocationRequestHelper.java
import android.content.Context;
import android.preference.PreferenceManager;
public class LocationRequestHelper {
...
...
public static String getUserId() {
return MainActivity.preferences.getString("userId","");
}
public static void setUserId(String userId) {
MainActivity.preferences.edit().putString("userId", userId ).commit();
}
}
MainActivity
public class MainActivity extends FragmentActivity implements
SharedPreferences.OnSharedPreferenceChangeListener {
public static SharedPreferences preferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
preferences = PreferenceManager.getDefaultSharedPreferences(this);
LocationRequestHelper.setUserId("1");
....
....
Utils
public class Utils {
public static void getLocationUpdates(final Context context, final Intent intent, String broadcastevent){
LocationResult result = LocationResult.extractResult(intent);
if (result != null) {
List<Location> locations = result.getLocations();
Location firstLocation = locations.get(0);
accuracy = firstLocation.getAccuracy();
LocationData data = new LocationData();
// MY FUNCTION DOESN'T WORK HERE
data.setUsrid(LocationRequestHelper.getUserId());
updateServer(data);
}
}
getLocationUpdates is called from BroadcastReceiver
Now problems appears after I try to get userID using
LocationRequestHelper.getUserId();
EDITED : Added Broadcast code
LocationUpdatesBroadcastReceiver
public class LocationUpdatesBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "LUBroadcastReceiver";
public static final String ACTION_PROCESS_UPDATES ="PROCESS_UPDATES";
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_PROCESS_UPDATES.equals(action)) {
Utils.getLocationUpdates(context,intent,"PROCESS_UPDATES");
}
}
}
}
NOTE:: THIS WORKS FINE IF APP IS IN BACKGROUND. BUT CRASHES AFTER I KILL FROM RECENT APPS.
Please tell me how I can send saved user id in my api call?
sorry for caps but this is main problem :P
The reason the app is crashing is that when it is killed any static variables become null. However you are still trying to access the SharedPreferences from the broadcast receiver and as such are getting a NPE.
The first thing you can do is update your LocationRequestHelper class to accept a context in the method rather than using the static SharedPreferences:
public class LocationRequestHelper {
//...
public static String getUserId(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getString("userId","");
}
public static void setUserId(Context context, String userId) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putString("userId", userId ).commit();
}
}
Then update you MainActivity to get rid of the SharedPrefs business and change the call to:
LocationRequestHelper.setUserId(this, "1");
And the Utils class to:
data.setUsrid(context, LocationRequestHelper.getUserId());
I created Service class.
I can run it anywhere where I want, but I always need Context from MainMenuActivity.class.
I tried use getApplicationContext and getBaseContext but they show another class.
Thanks for answer
public class MainActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(this, MyService.class));
}
}
public class MyService extends Service {
private Handler handler = new Handler();
private MyLocationListener mylistener;
public void onCreate() {
handler.postDelayed(new runnable(), 10000);
}
private class runnable implements Runnable {
#Override
public void run() {
mylistener = new MyLocationListener();
}
}
}
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
}
}
[EDIT]
When I used getApplicationContext() or getBaseContext or MainActivity.this to getDefaultSharedPreferences, always it will be the same?
Solution: 1
In that case you have to use, defaultSharedPreferences. You can access the default shared preferences instance by:
PreferenceManager.getDefaultSharedPreferences(Context context):
Example:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
This preference is shared across all your Activity and Service classes.
Solution: 2
You can create sharedPreference instance in your application class like:
public class MyApplication extends Application {
public static SharedPreferences preferences;
#Override
public void onCreate() {
super.onCreate();
preferences = getSharedPreferences("Preferences", MODE_PRIVATE);
}
}
And then you can manage your preferences as:
MyApplication.preferences.getString("key", "default");
add context parameter to your service class methods
public void myMethodInsideServiceClass(Context context){
//bluh bluh
}
so that you can call from Activity Class like this
myMethodInsideServiceClass(this);
you can also try
public class MyActivity extends Activity {
public static myActivity;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myActivity=this;
}
}
so that you can use myActivity across the application
(i was not using editor to type code, sorry for syntax error)
I have an Activity and non Activity class. How to call a method in Activity class from non Activity class
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
DataClass dc = new DataClass();
dc.show();
}
public void call(ArrayList<String> arr) {
// Some code...
}
}
public class DataClass {
public void show(ArrayList<String> array) {
// Here I want to send this ArrayList values into the call
// method in activity class.
MainActivity act = new MainActivity();
act.call(array);
}
}
Just create a callback interface inside the DateClass.
public DateClass {
public interface IDateCallback {
void call(ArrayList<String> arr);
}
private IDateCallback callerActivity;
public DateClass(Activity activity) {
callerActivity = (IDateCallback)activity;
}
...
}
public void show(ArrayList<String> array) {
callerActivity.Call(array);
...
}
//And implements it inside your activity.
public class MainActivity extends Activity
implements IDateCallback {
public void call(ArrayList<String> arr) {
}
}
Well there are several things you could do. I think the easiest for you would be to send the Context into DataClass like so:
DataClass dc =new DataClass();
dc.show(this);
And in your DataClass save the context into a global var Context context. Then use it like so:
((MainActivity)context).call(array);
((MainActivity)getContext).array();
Just make a singleton like:
TeacherDashboardSingleton:
public class TeacherDashboardSingleton {
public Teacher_Dashboard aa;
private static final TeacherDashboardSingleton ourInstance = new TeacherDashboardSingleton();
public static TeacherDashboardSingleton getInstance() {
return ourInstance;
}
}
myActivity class:
onCreate(....){
....
TeacherDashboardSingleton.getInstance().aa = this;
....
}
this will create an object of same instance as in activity
now you can use it from anywhere
I have a class PreferenceClass which extends PreferenceActivity. The code for this class is as follows:
public class Preferenceclass extends PreferenceActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main2);
addPreferencesFromResource(R.layout.preferences);
}}
I also have a non activity class Shakelistener which implements SensorListener. The code for this class is as follows:
public class Shakelistener implements SensorListener {
public void onSensorChanged(int sensor, float[] values) {
// Some code
}}
I need to be able to access the preferences from in this non-activity class, but I'm not sure how to do this.
EDIT
This is the code I use to access the shared preferences:
String PREF_FILE_NAME = "preferences";
SharedPreferences pref = mContext.getSharedPreferences(PREF_FILE_NAME , Context.MODE_PRIVATE);
String myListPreference = pref.getString("listpref", "default choice");
boolean cb = pref.getBoolean("checkBox", false);
Toast.makeText(mContext, myListPreference+"-"+cb, Toast.LENGTH_LONG).show();
This code is giving no errors, but it always evaluates the toast to "default choice-false".
Which PREF_FILE_NAME should I be using in this case?
Take an instance of Context in the constructor of your non-activity class and use that to call all such methods.
Something like this:
public class NonActivityClass implements SensorListener{
Context mContext;
public NonActivtiyClass(Context context) {
this.mContext = context;
}
//Rest of your code
}
Then do this to create an object of that class in your Activtiy's onCreate():
NonActivityClass nac = new NonActivityClass(this);
I have an activity which creates an object instance of my class:
file MyActivity.java:
public class MyActivity extends Activity {
TextView myView = (TextView)findViewById(R.id.myView);
...
Points myPoints new Points();
...
}
--------------------------------------------------------------
file Points.java:
private class Points {
...
HOW TO USE myView HERE ???
...
}
--------------------------------------------------------------
How do I use the UI objects in my class (which does not extend an
Activity)? Should I pass some context to my Points class? How do I do, exactly?
see you post, i've edited it , to fix the problem
hope it helps :=)
here is the Edit :
file MyActivity.java:
public class MyActivity extends Activity {
TextView myView ;
protected void onCreate(android.os.Bundle savedInstanceState) {
myView = (TextView)findViewById(R.id.myView);
Points myPoints = new Points(this);
myPoints.displayMsg("Hello World !!!");
}
}
--------------------------------------------------------------
file Points.java:
private class Points {
protected MyActivity context;
//add a constructor with the Context of your activity
public Points(MyActivity _context){
context = _context;
}
public void displayMsg( final String msg){
context.runOnUiThread(new Runnable() {
#Override
public void run() {
context.myView.setText(msg);
}
});
}
}
Your Points can't be a private class without being an inner class. So your code doesn't even compile...
Pass the view as parameter to the constructor of your Points class:
public class MyActivity extends Activity {
TextView myView = (TextView)findViewById(R.id.myView);
Points myPoints new Points(myView);
private class Points {
public Points(TextView view) {
// todo
}
}
}
You should do everything and pass back the value to the activity to handle UI instead of doing any UI related stuff in the point stuff.
You can pass the main Activity's context (using Points(getApplicationContext());) to the class as a constructor parameter. You could also pass the specific UI elements you want to manipulate.
A better way to do it, however, may be to have Points not know about the Activity. Have your Activity call Points methods and take the necessary actions based on the method output.
You could just pass the view to your class.
Points myPoints = new Points(myView);
private class Points
{
private TextView mTextView;
Points(TextView textView)
{
this.mTextView = textView;
}
}
i was in same trouble..
i found the simple way..
make a static variable and function ...
call from other class..
TestActivity.java
public class TestActivity extends Activity {
static EditText edit_text1;
public void onCreate(Bundle savedInstanceState)
{
.....
edit_text1 = (EditText) findViewById(R.id.edit_text1);
.....
}
public static void setMSG(String str)
{
edit_text1.setText(str);
}
}
Test2.java
TestActivity.setMSG("this is text");
Could work using an interface
file MyActivity.java:
public class MyActivity extends Activity implements Points.MyListener {
TextView myView;
... onCreate(...){
myView = (TextView)findViewById(R.id.myView);
Points myPoints = new Points();
//pass in MyActivity's instance of the listener
myPoints.addListener(this);
}
#Override
public void updateTextView(String message){
myView.setMessage(message);
}
}
file Points.java:
public class Points {
public Points(){
}
public interface MyListener{
void updateTextView(String message);
}
MyListener myListener;
public void addListener(MyListener listener){
myListener = listener;
}
public void updatePoints(){
//do some operations in calculatePoints()
String points = calculatePoints();
//update views using MyActivity's implementation of updateTextView()
myListener.updateTextView(points);
}
}
Doing it this way, events can be fired / messages sent, for lack of better terms, from the external class to update the Activity UI. This might be overkill if all sb need is to call a method in the Points class that returns something