Do we need to override onBackPressed() method for every screen? I do not see any other ways to do so. Please let me know if there is a more simpler way to do so.
make a super class for all of your activities e.g.
class BaseActivity extends AppCompatActivity {
#Override
void onBackPressed() { }
}
and then make all of your activities inherit from this class
class MyActivity1 extends BaseActivity { ... }
class MyActivity2 extends BaseActivity { ... }
class MyActivity3 extends BaseActivity { ... }
And all of your activities now wouldn't react to any back press event!
Create a BaseActivity and override onBackPressed() method with required logic
And extend BaseActivity in all Activity
abstract class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onBackPressed() {
//super.onBackPressed()
}
}
extend this BaseActivity instead of AppCompatActivity
class MainActivity : BaseActivity() {
//Your code
}
If you want to handle back button manually for some Activity then just override it for those Activity.
If you are using FragmentActivity or AppCompatActivity you can do this with OnBackPressedDispatcher that controls dispatching system back presses.
public class App extends Application {
#Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
#Override
public void onActivityCreated(#NonNull Activity activity,
#Nullable Bundle savedInstanceState) {
if (activity instanceof FragmentActivity) {
((FragmentActivity) activity).getOnBackPressedDispatcher()
.addCallback(new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
// nothing to do
}
});
}
}
#Override
public void onActivityStarted(#NonNull Activity activity) {
}
#Override
public void onActivityResumed(#NonNull Activity activity) {
}
#Override
public void onActivityPaused(#NonNull Activity activity) {
}
#Override
public void onActivityStopped(#NonNull Activity activity) {
}
#Override
public void onActivitySaveInstanceState(#NonNull Activity activity,
#NonNull Bundle outState) {
}
#Override
public void onActivityDestroyed(#NonNull Activity activity) {
}
});
}
}
AndroidManifest.xml:
<application
android:name=".App"
...
/>
Related
I have a video player app where I need to access the lifecycle of an abstract activity from another class in Android. In my abstract activity, I've tried using LifecycleRegistry, but this is getting me the lifecycle owner not the actually lifecycle of the abstract class. How can I access the lifecycle of an abstract activity from another class?
Here is my abstract activity:
abstract public class MainActivity extends AppCompatActivity {
private LifecycleRegistry lifecycleRegistry;
VideoPlayer videoPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleRegistry = new LifecycleRegistry(this);
lifecycleRegistry.setCurrentState(Lifecycle.State.CREATED);
setContentView(R.layout.activity_main);
videoPlayer = new VideoPlayer();
playVideo();
}
public void playVideo(){
videoPlayer.init();
//calls function in VideoPlayer class
}
#Override
protected void onResume() {
super.onResume();
lifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED);
}
#Override
protected void onDestroy() {
super.onDestroy();
lifecycleRegistry.setCurrentState(Lifecycle.State.DESTROYED);
}
}
Here is the class where I need to get the lifecycle of my abstract MainActivity:
public class VideoPlayer {
public void init() {
playVideo();
}
public void playVideo() {
//async call happens here, I need getLifeCycle() from MainActivity
}
}
Don't know a know about the context of you feature, but you You can do smth
public class VideoPlayer {
private Lifecycle mLifecycle;
public VideoPlayer(Lifecycle lifecycle) {
mLifecycle = lifecycle;
}
public void init() {
playVideo();
}
public void playVideo() {
//you have mLifecycle now
}
}
In Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
videoPlayer = new VideoPlayer(getLifecycle());
}
I want to call method of Other activity. I searched alot and tried by myself but failed. It work when i call from class to class like classA m=new classA();
m.function();
But i want to call from another activity method. Please help
public void onNotificationPosted(StatusBarNotification sbn) {
ChatActivity ch=new ChatActivity();
ch.location();
}
public class ApplicationContext extends Application {
public ActivityMain activityMain;
public void setActivityMain(ActivityMain activityMain) {
this.activityMain = activityMain;
}
public ActivityMain getActivityMain() {
return activityMain;
}
In ActivityMain.class
public class ActivityMain extends BaseProject implements MainView {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ApplicationContext.getInstance().setActivityMain(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
ApplicationContext.getInstance().setActivityMain(null);
}
Use it anywhere like Activity, Fragments, Broadcast Receiver or Service like
if (ApplicationContext.getInstance().getActivityMain()!=null){
ApplicationContext.getInstance().getActivityMain().callAnyMethod();
}
Enjoy :)
I have an app with several activities and the action to perform on destruction is actually the same, no matter what the Activity is at that moment (deleting some data and performing a HTTP call).
Is there a way to have all activities share the onDestroy method?
Another solution would be to factorize a method in some other static class and have each Activity invoke it during destruction, but a trait-like behaviour would be actually nicer.
Create an abstract BaseActivity, override the onDestroy, and all your other activities should just extend the BaseActivity?
Why go with singletons, statics, factories etc if what you are describing is a classic OOP trait? :)
From you description, I understood that you want a common onDestroy() method which will be call by all the activities when calling onDestroy().
Here is the code:
package com.demo.application;
import android.app.Activity;
import android.app.Application;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
public class AppGlobal extends Application {
#Override
public void onCreate() {
super.onCreate();
// register to be informed of activities starting up
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
// new activity created; force its orientation to portrait
activity.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
#Override
public void onActivityStarted(Activity activity) {
}
#Override
public void onActivityResumed(Activity activity) {
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivityStopped(Activity activity) {
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
}
});
} //End of onCreate
}
You need to add a property within application tag of your manifest.xml file:
android:name="com.demo.application.AppGlobal"
Try and let me know your experience.
Use singleton class and create static method in which do what u want to do and in onDestroy call this method.
Easiest way for this is creating an Application class and registering for the life cycle callbacks.
public class MyApp extends Application {
#Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
#Override
public void onActivityStarted(Activity activity) {
}
#Override
public void onActivityResumed(Activity activity) {
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivityStopped(Activity activity) {
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
//Perform common action here
}
});
}
}
Add the Application class in the manifest.
<application
android:allowBackup="true"
android:name=".MyApp"
android:icon="#mipmap/ic_launcher"
I'm new to android and I'm trying to get a hang of creating and using Fragments.
I have a fragment that shows a simple list of multiple dates to choose from and implements an onClickListener. The idea is once a user chooses a date, the fragments sends the date back to the MainActivity which then runs a query in database and sends the database response to another fragment.
I'm stuck on the point of sending the date back to MainActivity, elegantly. I can't find much info. I found this:
Activity activity = getActivity();
if(activity instanceof MyActivity){
MyActivity myactivity = (MyActivity) activity;
myactivity.myMethod();
}
I'm very new to this but this seems hacky to me. Is this the right way or is there another way?
Any input is appreciated
I prefer the interface based approach because is very clean. You can declare a nested interface in your Fragment or an external one:
interface OnMyStuffListener {
void myMethod();
}
Make the Activity to implement that interface:
public class MainActivity extends Activity implements OnMyStuffListener {
#Override
public void myMethod() {
// Do whatever you want.
}
}
The Fragment will be attached to the Activity so you can check the instance of the Context and cast it to the Activity:
public class MyFragment extends Fragment implements View.OnClickListener {
private OnMyStuffListener mListener;
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnMyStuffListener) {
mListener = (OnMyStuffListener) context;
} else {
throw new IllegalArgumentException("The context " + context.getClass().getName() +
"must implement " + OnMyStuffListener.class.getName());
}
}
#Override
public void onDetach() {
super.onDetach();
// Release it avoiding memory leak.
mListener = null;
}
#Override
public void onClick(View v) {
mListener.myMethod();
}
}
YES this is absolutely right. You can use this, if you are not sure that your Fragment is attached to Activity
You can also achieve this by using Interface, using an EventBus like LocalBroadcastManager, or starting a new Activity with an Intent and some form of flag passed into its extras Bundle or something else.
Here is an example about using Interface:
1. Add function sendDataToActivity() into the interface (EventListener).
//EventListener.java
public interface EventListener {
public void sendDataToActivity(String data);
}
2. Implement this functions in your MainActivity.
// MainActivity.java
public class MainActivity extends AppCompatActivity implements EventListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void sendDataToActivity(String data) {
Log.i("MainActivity", "sendDataToActivity: " + data);
}
}
3. Create the listener in MyFragment and attach it to the Activity.
4. Finally, call function using listener.sendDataToActivity("Hello World!").
// MyFragment.java
public class MyFragment extends Fragment {
private EventListener listener;
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
if(activity instanceof EventListener) {
listener = (EventListener)activity;
} else {
// Throw an error!
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my, container, false);
// Send data
listener.sendDataToActivity("Hello World!");
return view;
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Hope this will help~
In MainActivity I have a TextView: textV1. I also have a method in MainActivity that updates that textview:
public void updateTheTextView(final String t) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
TextView textV1 = (TextView) findViewById(R.id.textV1);
textV1.setText(t);
}
});
}
In a BroadcasrReceiver I need to update the text in textV1 in MainActivity.
public class NotifAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// other things done here like notification
// NEED TO UPDATE TEXTV1 IN MAINACTIVITY HERE
}
}
How can this be done? The BroadcastReceiver is run from a service. This code I cannot change. Can I access and change textV1 in MainActivity from onReceive()? I've tried many things but all fail.
In your MainActivity initialize a variable of MainActivity class like below.
public class MainActivity extends Activity {
private static MainActivity ins;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ins = this;
}
public static MainActivity getInstace(){
return ins;
}
public void updateTheTextView(final String t) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
TextView textV1 = (TextView) findViewById(R.id.textV1);
textV1.setText(t);
}
});
}
}
public class NotifAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
MainActivity .getInstace().updateTheTextView("String");
} catch (Exception e) {
}
}
}
#Use Interface
Another way to deal with this situation is by using an Interface. I will describe the advantage of this approach but first, let's see how it's done.
Follow these steps:
1) Create an interface
public interface MyBroadcastListener{
public void doSomething(String result);
}
2) Initialize the listener in BroadCastReceiver
public class NotifAlarm extends BroadcastReceiver {
private MyBroadcastListener listener;
#Override
public void onReceive(Context context, Intent intent) {
listener = (MyBroadcastListener)context;
// other things done here like notification
// NUPDATE TEXTV1 IN MAINACTIVITY HERE
listener.doSomething("Some Result");
}
}
3) Implement the interface in Activity and override the method
public YourActivity extends AppCompatActivity implements MyBroadcastListener{
// Your Activity code
public void updateTheTextView(String t) {
TextView textV1 = (TextView) findViewById(R.id.textV1);
textV1.setText(t);
}
#Override
public void doSomething(String result){
updateTheTextView(result); // Calling method from Interface
}
}
##Advantages of using the interface?
When you have BroadcastReceiver in a different file
Decoupled BroadcastReceiver
Using an interface makes BroadcastReceiver independent of any
Activity. Let's say in future you want to use this BroadCastReceiver
with another Activity which takes the result from BroadcastReceiver
and start a DetailActivity. This is completely a
different task but you will use the same BroadcastReceiver without even
a single code change inside BroadcastReceiver.
How to do that?
Implement the interface in the Activity and Override the method. That's it!
public ListActivity extends AppCompatActivity implements MyBroadcastListener{
// Your Activity code
public void startDetailActivity(String title) {
Intent i = new Intent(ListActivity,this, DetailActivity.class);
i.putExtra("Title", title);
startActivity(i);
}
#Override
public void doSomething(String result){
startDetailActivity(String title); // Calling method from Interface
}
}
create an instance of the class and then pass the value to the function that changes TextView value follow these steps please :
in your BroadcastReceiver overRide onReceive method and paste These lines or changes theme as you wish
private Handler handler = new Handler(); // Handler used to execute code on the UI thread
// Post the UI updating code to our Handler
handler.post(new Runnable() {
#Override
public void run() {
//Toast.makeText(context, "Toast from broadcast receiver", Toast.LENGTH_SHORT).show();
YourActivityToUpdate.updateTheTextView(message);
YourActivityToUpdateinst = YourActivityToUpdate.instance();
if(inst != null) { // your activity can be seen, and you can update it's context
inst.updateTheTextView(message);
}
}
});
now we explain the updateTheTextView and inst
in YourActivityToUpdate class Paste these Lines please
private static SignUpVerify mInst;
public static SignUpVerify instance() {
return mInst;
}
#Override
public void onStart() {
super.onStart();
mInst = this;
}
#Override
public void onStop() {
super.onStop();
mInst = null;
}
and this is the updateTheTextView method that should be placed in YourActivityToUpdate class
public void updateTheTextView(final String verifyCodeValue) {
Log.i("verifyCodeValue", verifyCodeValue);
YourTextViewToUpdate.setText(verifyCodeValue);
}
i think this is a better way thanks to "kevin-lynx"
If someone is searching this exact solution, but in Kotlin, do the following:
class MainActivity : AppCompatActivity() {
companion object {
var ins: MainActivity? = null
fun getInstance(): MainActivity? {
return ins
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ins = this
}
fun updateTheTextView(t: String) {
this#MainActivity.runOnUiThread {
val textV1 = findViewById<TextView>(R.id.textV1)
textV1.text = t
}
}
}
class NotifAlarm : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
try {
MainActivity.getInstance()?.updateTheTextView("The String")
} catch (e: Exception) {
}
}
}
In your broadcastreceiver class send broadcast
public class mybroadcaster extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
context.sendBroadcast(new Intent("updatetext"));
}
}
In your activity register your broadcastreceiver and call it, do your work at onReceive and unregister the broadcaster in onDestroy()
public class MyActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(broadcastReceiver, new IntentFilter("updatetext"));
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do your work here
}
};
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
}