I'm new to android and I need little help please. I want to pass data from an activity to a framelayout class, so I've implement a callback. On my activity I use an interface and setting the listener like this:
private OnCallStateListener onCallStateListener;
public interface OnCallStateListener{
int Data = 1;
void OnCallState(int wichAction)
}
public void setOnCallStateListener(OnCallStateListener listener){
onCallStateListener = listener;
}
private void dispatchTriggerEvent(int whichHandle){
if(onCallStateListener != null){
onCallStateListener.OnCallState(whichHandle);
}
}
And I use it like:
private onCallDisconnect(){
dispatchTriggerEvent(OnCallStateListener.DATA);
The dispatchTriggerEvent is executed but the problem is that the listener onCallStateListener is always null. what am I missing here?
Thanks!
It is null because you did not create an instance of the class. From what you have here you only have an interface. You would first need to create a class that implements that interface, and then say something like:
OnCallStateListener myVar = new OnCallStateListenerImpl();
Related
i have an activity where i have a text view. I am also using an sdk which has some events.
Within on of these events i need to display some data at the TextView.
The events are in an external class and i got them via some interfaces.
The interfaces iam implementing within the Activity.
I am using Handler and Message to set the text into the TextView within the implementation of the interface.
I would like to know if there is another way to set the text within the the interfaces except Handler and Message.
Here is that code:
public class MyActivity extends AppCompatActivity {
private TextView nameTextView;
// some code
// implementing interfaces of external class
Service.ServiceEvents events = new Service.ServiceEvents() {
#Override
public void onSomeEvent(String name) {
nameTextView.setText(name); // not working
Message m = myHandler.obtainMessage(0, nameTextView);
m.sendToTarget();
}
Handler myHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message message) {
String s = message.obj.toString();
nameTextView.setText(s);
}
};
}
} // end of activity
Is there another way to set the text in the TextView?
Please Help.
What to use
You can do it by using an interface.
How to implement
Create a new interface and give it a name whatever u like.(Here it is SampleInterface).
Add some void methods to like this
void onSomeEvent(String name);
Create a object of it in the class where you get the data from the sdk and add this listener in its constructor. Something like this
public YourJavaClassName(SampleInterface sampleInterface) {
this.sampleInterface= sampleInterface;
}
When you receive an update in the sdk, you can call it like this
void onDataReceived(String name){// I don't know how you get the value from the sdk so I wrote this
sampleInterface.onSomeEvent(name);
}
You are done with implementing it in the sdk receiver class. Now you need to add to the main activity to receive and update data.
Create the object of the class where you receive the data from the sdk.Like this
MySDKReceiverClass mysdkreceiverclass;
mysdkreceiverclass = new MySDKReceiverClass(this);
Implement the interface in the activity and there you ge the values and you can set it in the textview.
Note: You need not add any runnable or handler or anything.Whenever there is a value change, the listener is called and the value is set.
I have a method name checkForUpdate() in UpdateActivity.java. It looks like this:
#NonNull
#SuppressWarnings("deprecation")
protected String checkForUpdate(int curVersionCode) {
HttpClient httpclient = new DefaultHttpClient();
...
}
I am trying to call it from anotherActivity. So I'm trying to use code like this:
private void callFromAnotherActivity() {
UpdateActivity updateApp = new UpdateActivity();
String result = updateApp.checkForUpdate(...);
}
so when I type updateApp. then a list of the methods of UpdateActivity.java appears but there is no checkForUpdate() method. Why?
so when I type updateApp. then a list of the methods of UpdateActivity.java appears but there is no checkForUpdate() method. Why?
This is because your method is not public and probably you haven't import the UpdateActivity.
Please be noted that you can't create an Activity by calling the following:
UpdateActivity updateApp = new UpdateActivity();
You need to use something like this:
// context is your activity context.
Intent updateApp = new Intent(context, UpdateActivity.class);
context.startActivity(updateApp);
My suggestion:
You need to move the checkForUpdate method from UpdateActivity and make it as an util. So, other activity using the method won't be dependent and coupled with UpdateActivity. Localize the method to an utility class something like this:
public class UpdateUtil {
...
#NonNull
#SuppressWarnings("deprecation")
public static String checkForUpdate(int curVersionCode) {
HttpClient httpclient = new DefaultHttpClient();
...
}
}
and then use the method with:
UpdateUtil.checkForUpdate(1);
If you can't move the code (e.g, you don't have ownership of the code), you can do these things:
Make the checkForUpdate as static method
Use EventBus to tell the UpdateActivity to do the update.
You should not create an instance of the activity class. It is wrong. Activity has ui and lifecycle and activity is started by startActivity(intent)
Check here : call a method in another Activity
public boolean getFavourite(Winkel winkel){
boolean isFavourite = false;
MyDBHandler dbHandler = new MyDBHandler(context,null,null,1);
User user = dbHandler.loggedIn(); //This method isn't usable anymore
isFavourite = dbHandler.isFavourite(user,winkel);
return isFavourite;
}
I want to change this code to:
public boolean getFavourite(Winkel winkel){
boolean isFavourite = false;
MyDBHandler dbHandler = new MyDBHandler(context,null,null,1);
isFavourite = dbHandler.isFavourite(user,winkel);
return isFavourite;
}
I was using my database to keep track of which user was logged in at first, but it was really easy to change this by simply sending the data from my first activity to my second.
#Override
public void login(User user){
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("Username",user.getUserName());
startActivity(intent);
}
Then, in my second activity, I could call all the database functions by using this:
user.setUserName(intent.getStringExtra("Username"));
(Because I need the username as a key for my database.
However, my activity has three fragments, two of which use my adaptor for a recyclerview. These fragments implement the interface that is provided in my adaptor class, which is this one (just showing this to be complete, what the interface is is irrelevant, fact is that my fragments have to implement this interface).
public interface ItemCLickCallback {
void onItemClick(int p);
void onSecItemClick(int p);
}
Now, I need the username in my adaptor class. It has to come from my activity (because thats where its stored), and I can't use an interface because I'm already using one and I would have to override the methods in every fragment.
I could pass the data from my activity to all the fragments using a Bundle, then pass that along to the adaptor when creating it in my fragments. But that seems like a lot of excessive code. Any simpler way to do this? Thank you
EDIT:
In Adaptor class:
private CheckFavourite checkFavourite;
public void setCheckFavourite(final CheckFavourite checkFavourite){
this.checkFavourite = checkFavourite;
}
boolean isFavourite = checkFavourite.getFavourite(winkel);
public interface CheckFavourite{
boolean getFavourite(Winkel winkel);
}
Fragment:
public class Overview extends Fragment implements Adaptor.ItemCLickCallback
Activity:
public class SecondActivity extends AppCompatActivity implements Adaptor.CheckFavourite
Activity has to implement the seconde interface, fragment implements the second. But both of them are on the same adaptor instance.
What I need to do (in my activity basically):
adaptor.setCheckFavourite(this);
But I can't because I don't have the adaptor there, it gets created in my fragment.
I tried:
adaptor.setCheckFavourite(this.getActivity());
in my fragment, but that gives me an an error:
Error:(60, 51) error: incompatible types: FragmentActivity cannot be converted to CheckFavourite.
However
adaptor.setItemCLickCallback(this);
is working perfectly fine in my fragment (the other interface). How do I fix this?
:) You can use multiple inheritance. To be able to make a class implement multiple interfaces we need can have something like this:
public class MyClass extends MyOtherClass implements MyInterface1, MyInterface2, ... , MyInterfaceN {
// Need to implement all interface methods here
}
I have a set of instances of a class named Marker that has a Marker#setDelay(double) method. This method is called based on mouse drags (you can drag around the markers). Every marker has a corresponding double variable in a config class.
I want to synchronize the config class with the marker instances. So whenever the Marker#setDelay(double) method is called, the corresponding variable in the config class should change too. How can I do that?
I tried using Runnables that I can apply to the markers, so the runnable would be called from within the Marker#setDelay(double) method, but this Runnable does not have access to the delay value. Is there some sort of method pointer workarround?
My last resort would be a interface and anonymous instances for every marker. But that seems kind of ugly...
The general off-the-shelf pattern here is straightforward: Introduce an interface like MarkerListener. Then you can create a (possibly anonymous) MarkerListener implementation that updates your config, and add it to the respective `MarkerĀ“.
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
interface MarkerListener
{
void delayChanged(double oldDelay, double newDelay);
}
class Marker
{
private double delay;
private final List<MarkerListener> markerListeners =
new CopyOnWriteArrayList<MarkerListener>();
void addMarkerListener(MarkerListener markerListener)
{
markerListeners.add(markerListener);
}
void removeMarkerListener(MarkerListener markerListener)
{
markerListeners.add(markerListener);
}
void setDelay(double newDelay)
{
if (newDelay != this.delay)
{
double oldDelay = this.delay;
this.delay = newDelay;
fireDelayChanged(oldDelay, newDelay);
}
}
private void fireDelayChanged(double oldDelay, double newDelay)
{
for (MarkerListener markerListener : markerListeners)
{
markerListener.delayChanged(oldDelay, newDelay);
}
}
}
Of course, this involves some code bloat. It is basically a minimalistic implementation of something that could also be achieved when using the DoubleProperty from JavaFX that Joop Eggen referred to in his answer. So you might want to consider using the DoubleProperty. (One could also solve this with PropertyChangeListeners, but these are probably not so appropriate here)
Since you referred to "function pointers": You could also use DoubleConsumer instances instead of introducing an own interface. But it's impossible to tell from the question whether this is the best solution here.
JavaFX has ...Property classes, which you can bind to receive change notifications. That is a much underestimated/overseen UI functionality.
So use a DoubleProperty. (A warning: the javadoc does not easily suffice for usage.)
See for a usage here.
Have a DoubleProperty
addListener new ChangeListener with as ObservableValue the DoubleProperty
I didn't fully understand the problem.
Here is my solution anyway
Create a Listener
public interface MarkerChangeListener{
void markerChanged(double value);
}
Implement the Config Class with listener
public class Config implements MarkerChangeListener{
private double delay;
#override
public void markerChanged(double value){
this.delay = value;
}
....
}
Add a method to your Marker class to add listener and fire the listener when the value updated
public class Marker{
private MarkerChangeListener listener;
public void addListener(MarkerChangerListener listener){
this.listener = listener;
}
public void setDelay(double delay){
this.delay = delay;
listener.markerChanged(delay)
}
}
Add the listener to the Marker class from where you create markers.
marker.addListener(config);
I am trying to initialize a class that calls another class that uses AsyncTask. I am using GetDataFromDB gDataFromDB = new GetDataFromDB() but that does not initialize the class, it just gives me access to any static methods in the class. So what do I do to get the onCreate method to run? I have tried using intent but keep getting an error because this is a static class
public class FacadeDataFromDB extends Activity {
static ArrayList<HashMap<String, String>> visitorsList;
private static FacadeDataFromDB dataFromDB;
static boolean accessDB = false;
private FacadeDataFromDB() {
}
public static void initInstance() {
}
public static FacadeDataFromDB getInstance() {
if (dataFromDB == null) {
// Create the instance
dataFromDB = new FacadeDataFromDB();
}
return dataFromDB;
}
public static void setData() {
if (!accessDB) {
GetDataFromDB gDataFromDB = new GetDataFromDB();
accessDB = true;
}
// visitorsList = gDataFromDB.returnInfoFromDB();
}
public static ArrayList<HashMap<String, String>> getVisitorForDay() {
// TODO Auto-generated method stub
setData();
return visitorsList;
}
}
GetDataFromDB is the other class that I am calling. The current class is a static class and uses a singleton because I only want one initialization of the class the gets data from the db. If you have more questions or want me to post code let me know. Thanks
It seems to me that your two classes FacadeDataFromDB GetDataFromDB should not inherit Activity
Activities are made for GUI and user-interaction (I don't see any in your example) and their life-cycle is managed by the framework : you never create them manually with new.
See the android tutorial : https://developer.android.com/guide/components/activities.html and Activity javadoc : https://developer.android.com/reference/android/app/Activity.html.
I'm not sure that you completely understand the Android runtime. You should start Activities using Intent objects, not by creating them with the new keyword as you are. To ensure that your onCreate() method is called within your Activity, you could launch an explicit Intent from some other Activity/Context: Intent intent = new Intent(currentContext, FacadeDataFromDB.class);.
Also, when it comes to Activities, you shouldn't use private constructors. See this post for reasons why.