How to call MainActivity method in a java class? - java

I'm trying ways to call my MainActivity method into my doWork in java class in android studio. But I'm not getting it. Is there any way to call this method ?
Class in the MainActivity
public class MainActivity extends AppCompatActivity implements LocationListener {
protected double latitude, longitude;
TextView txtLat, txtLng;
LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void LocalizarUsuario(){
txtLat = (TextView) findViewById(R.id.txtLat);
txtLng = (TextView) findViewById(R.id.txtLng);
locationManager =(LocationManager)
getSystemService(Context.LOCATION_SERVICE);
if(ActivityCompat.checkSelfPermission(MainActivity .this,Manifest.permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,this);
}
}
Java class with the doWork
public class WorkerClass extends Worker {
public WorkerClass(
#NonNull Context context,
#NonNull WorkerParameters params) {
super(context, params);
}
#Override
public Result doWork() {
LocalizarUsuario();
// Indicate whether the work finished successfully with the Result
return Result.success();
}
}

Depending on what exactly you want to do, you could place the WorkerClass into the MainActivity (inner class) or if you want to use the WorkerClass only from the MainActivity, you could pass the instance of

Related

How can I do not use constructor in MainActivity in Android Studio?

I'm a beginner.
I'm trying to make Locale project with Android Studio.
So I made a class regard with Context.
In MainActivity required a constructor.
But, I'm heard that MainActivity do not need constructor but onCreate.
Here is my code.
BaseContextWrapper
public class BaseContextWrapper extends AppCompatActivity {
//AppCompatActivity-FragmentActivity-ComponentActivity-Activity-ContextThemeWrapper-ContextWrapper-Context
public BaseContextWrapper(Context base) {
super.attachBaseContext(base);
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
#NonNull
public static ContextWrapper wrap(Context context) {
Resources resources = context.getResources();
Configuration newConfig = new Configuration();
DisplayMetrics metrics = resources.getDisplayMetrics();
newConfig.setToDefaults();
newConfig.densityDpi = metrics.densityDpi;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
context = context.createConfigurationContext(newConfig);
} else {
resources.updateConfiguration(newConfig, resources.getDisplayMetrics());
}
return new BaseContextWrapper(context);
}
}
MainActivity
public class MainActivity extends BaseContextWrapper {
public MainActivity(Context base) {
super(base);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
It all depends on what you inherit from. If from "extends Base ContextWrapper", then the constructor is required, it is included in the class. But if from "extends AppCompatActivity" then nothing but the onCreate() method is needed
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
Rewrite your MainActivity as
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

how to use activity context from other activity?

I want to use activity context from another activity simple code example below Any idea ?
public class Activity_A extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_Activity_A);
}
}
public class Activity_B extends AppCompatActivity {
Dialog dialog1 ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_Activity_B);
dialog1 = new Dialog(I want Activity_A Context) ; // Is this possible ??
}
}
Thanks
Tamim you can definitely achieve this using a different class by making a public static function in that other class
public class Utils {
public static void showDialog(Context context){
//// your code here
}
now you use it wherever you want...
Utils.showDialog(this);

Updating the status in UI methods from a non-UI thread

I have an Activity that includes a TextView to display the current status of the app. Besides MainActivity there is another class that is used for checking for updates and then updating the app if appropriate.
This is the important part of the code.
public class MainActivity extends AppCompatActivity {
private TextView status;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
status = findViewById(R.id.status);
new Update().check();
}
public void setStatus(String status) {
this.status.setText(status);
}
}
How can I update the status TextView from within the Update class?
public class Update extends Activity {
public void check(final Context c) {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView status = findViewById(R.id.status);
status.setText("Checking for updates...");
}
});
// final TextView status = getApplicationContext().findViewById(R.id.status);
// status.setText("Checking for updates");
// Check for updates...
}
public class UpdateApp extends AsyncTask<String,Void,Void> {
private Context context;
public void setContext(Context contextf){
context = contextf;
}
#Override
protected Void doInBackground(String... arg0) {
// Update the app
}
}
}
Attempting to run getApplicationContext().findViewById(R.id.status) crashes the app. When I put it in a try block it still crashes the app - how can that be when I catch a Throwable object? ... that doesn't make sense!!!
Using runOnUiThread the app runs but the status is not updated.
Put the UpdateApp AsynTask in new file.
public class MainActivity extends AppCompatActivity {
private TextView status;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
status = findViewById(R.id.status);
new UpdateApp(status).execute();
}
}
UpdateApp.java
public class UpdateApp extends AsyncTask<String,Void,Void> {
private TextView status;
public UpdateApp(TextView status){
this.status = status;
}
#Override
protected void onPostExecute(String result) {
status.setText("Update complete");
}
#Override
protected void onPreExecute() {
status.setText("Checking for updates...");
}
#Override
protected Void doInBackground(String... arg0) {
// Update the app
}
}
You just don't need another class to make it works, just copy your UpdateApp class inside MainActivity to access your status view.
In case you want your UpdateApp class to be in a different file (witch I recommend, to separate classes responsibility) you'd need a callback: a reference to your activity to update the status view from the AsyncTask class. The way you can make it is using Interfaces. Take a look to this example
MainActivity.java
public class MainActivity extends AppCompatActivity implements CallbackInterface {
private TextView status;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
status = findViewById(R.id.status);
new LoaderClass(this).execute();
}
#Override
public void setStatusText(String text) {
status.setText(text);
}
}
CallbackInterface.java
public interface CallbackInterface {
void setStatusText(String text);
}
LoaderClass.java
public class LoaderClass extends AsyncTask<String, Void, Void> {
private CallbackInterface callbackInterface;
public LoaderClass(CallbackInterface callback) {
callbackInterface = callback;
}
#Override
protected Void doInBackground(String... arg0) {
callbackInterface.setStatusText("Loaded text");
return null;
}
}
If you are in any Activity you can use runonUIthread() like -
runOnUiThread(new Runnable() {
#Override
public void run () {
// do your magic here
}
});

Calling a method of MainActivity from other class

I am developing an Android app and thus, I have a MainActivity class. Inside of that MainActivity class, I have a method, let's call it doSomething():
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void doSomething(){
// bla bla bla
}
}
I also have a different class (with different layout) that is called OtherActivity. I want to use the doSomething method inside it:
public class OtherActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_activity_layout);
// Let's use doSomething()
}
}
I tried this:
public class OtherActivity extends AppCompatActivity {
MainActivity main;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_activity_layout);
// Let's use doSomething()
MainActivity main = new MainActivity();
main.doSomething();
}
}
But it does not work. I also tried to make OtherActivity to extend the MainActivity, doing the following:
public class OtherActivity extends MainActivity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_activity_layout);
// Let's use doSomething()
super.doSomething();
}
}
But it does not allow me to initialize the layout...
How can I do?
Thanks in advance.
To communicate between to Activity Broadcast is the best way, and for the same application, we can use local broadcast using LocalBroadcastManager.
First, we should register one broadcast in MainActivity,
public class MainActivity1 extends AppCompatActivity {
public static final String INTENT_FILTER = "do_some_action";
public static final String INTENT_BUNDLE_VALUE = "value1";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
LocalBroadcastManager.getInstance(this).registerReceiver(
mChangeListener, new IntentFilter(INTENT_FILTER));
}
#Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mChangeListener);
}
private BroadcastReceiver mChangeListener = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intentData) {
// you can do anything here
if (intentData != null && intentData.hasExtra(INTENT_BUNDLE_VALUE)) {
String value = intentData.getStringExtra(INTENT_BUNDLE_VALUE);
doSomeAction(value);
}
}
};
private void doSomeAction(String value) {
}
}
Then to do some action in MainActivity from OtherActivity, we can send Local broadcast from OtherActivity it will reach the receiver of Which we register in MainActivity,
public class OtherActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
// You can call MainActivity to do some actions
Intent intent = new Intent(MainActivity1.INTENT_FILTER);
intent.putExtra(MainActivity1.INTENT_BUNDLE_VALUE, "Any string or any value");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
Done!!!.
Something like this should do the trick, I'm going to make a static navigator to handle your navigation logic. If you are opposed to static methods you could also make them on your Application object to make it easier to manage dependencies, I'm just making it static for simplicity.
//Making this fully static for simplicity, this is fine for a small app
//you can make it a singleton on the application class for more flexibility
public class Navigator {
//static member vars that determine navigation
// pass in Context if needed for navigation purposes
public static void doSomething(Context context){
// bla bla bla
}
}
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity_layout);
}
private void doSomething() {
Navigator.doSomething(this);
}
}
public class OtherActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_activity_layout);
}
private void doSomething() {
Navigator.doSomething(this);
}
}

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View .MainActivity.findViewById(int)' on a null object reference

I have a class called MainActivity.java that call an AsyncTask class. The last class have a findViewById() that in execution return this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View <mypackage>.MainActivity.findViewById(int)' on a null object reference
I don't understand how can I edit an ImageView positioned in R.layout.activity_main after that an AsyncTask finish to work.
MainActivity.java
public class MainActivity extends Activity {
public MainActivity() {}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Connection().execute();
}
}
Connection.java
public class Connection extends AsyncTask<String, Void, String> {
public String result;
//I know, this isn't correct, how can i do?
public MainActivity MainActivity;
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
//...
return "a string";
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
//...
// Where the error is generated
ImageView image = (ImageView) MainActivity.findViewById(R.id.image);
//...
}
}
The error is that
public MainActivity MainActivity;
is never initialized, thus pointing to null.
To make your code work the minimum step is
in MainActivity
new Connection(this).execute();
In Connection
public class Connection extends AsyncTask<String, Void, String> {
public MainActivity MainActivity;
public Connection(MainActivity activity) {
MainActivity = activity;
}
But creating a task in onCreate and passing an Activity is not the best idea anyway.
Also, field names should always start with a lowercase letter.
The best way is passing an ImageView to the AsyncTask.
Don't start a task until the Activity is started and also, don't forget to cancel the task when the Activity is stopped.
public final class MainActivity extends Activity {
public MainActivity() {}
private Connection connection;
private ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.image);
}
#Override
protected void onStart() {
super.onStart();
if (connection == null || connection.getStatus() != AsyncTask.Status.RUNNING) {
connection = new Connection(imageView);
connection.execute();
}
}
#Override
protected void onStop() {
super.onStop();
if (connection != null && connection.getStatus() == AsyncTask.Status.RUNNING) {
connection.cancel(true);
}
}
}
In Connection.java, store an ImageView as a WeakReference to avoid leaks.
public final class Connection extends AsyncTask<String, Void, String> {
private final WeakReference<ImageView> imageViewRef;
public Connection(ImageView view) {
imageViewRef = new WeakReference<ImageView>(view);
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
//...
return "a string";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//...
final ImageView imageView = imageViewRef.get();
// if the Activity is still alive, the ImageView will not be null
if (imageView != null) {
// set an image or whatever you need
image.setImageResource(666);
}
}
put imageview as a variable of your class
private ImageView image;
on your onCreate initialize
image = (ImageView) findViewById(R.id.image);
public class Connection extends AsyncTask<String, Void, String> {
public String result;
//I know, this isn't correct, how can i do?
public MainActivity MainActivity;
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
//...
return "a string";
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
//...
// Where the error is generated
//do other stuff with your imageview
//...
}
}
You did not specify what parameter you pass to Connection.java AsyncTask.
One of my student is also having same problem.
Although he is using Volley Library for HttpConnection (posting data) and main issue was:
he is writing URL directly without the http protocol prefix i.e.
String post_url ="api/do_post";
Simply add http/https at front of your post url:
String post_url ="http://api/do_post";
actually i was working an activity and service application. same problem i also got,
in that in bindservice i have used the BIND_IMPORTANT flag instead of using BIND_AUTO_CREATE.
once i changed the flag it was worked successfully for me.

Categories