Implement interface in a service and call it in another class -Android - android

I have a use case in which I need to update points(markers) on the map when a certain event occurs inside a service. For that am using an interface callback method.
public interface draw
{
void updatePoints(Context context) throws JSONException;
}
Now am using this interface in my Service like this :
draw dfc;
...............
//Inside a constructor of a class
dfc=new draw() {
#Override
public void updateFloatingPoints(Context context) throws JSONException {
System.out.println("Callback in Service");
CustomViewView.registerDPCListener(dfc);
}
};
Now within the same Service, under a certain function, am passing the interface as an input parameter i.e callback and inside that function am calling
callback.updateFloatingPoints(context);
Now when am running the service, I can see the callback in Service statement. Till here everything is okay.
Now problem is that, when the callback is received, I want to do some work another class. Let's call it CustomView. I implemented the interface in that class too but I am not able to receive the callbacks over there. Follow is the bare bone code of the class
public class CustomView extends ABCD implements draw {
private draw dfcListner=null;
public void registerDPCListener(drawPath listener) throws JSONException {
this.dfcListner = listener;
if(dfcListner!=null)
{
System.out.println("Listener initialized");
//dfcListner.updateFloatingPoints(mcontext);
}
else
{
System.out.println("Listener is not initialized");
}
}
//Another functions in between over here
#Override
public void updateFloatingPoints(Context context) throws JSONException {
System.out.println("Inside CustomView callback");
}
}
How do I go about it?

Related

Passing a notification from my object to a service

I'm working in an app for android. I have a Service to manage the background process of streamming. Then I have an object AudioPlayer that manages the MediaPlayer instance and it get called from the service. But the problem I have is with the listener onPrepared, because it's within my AudioPlayer but I need that when it gets trigger send a message from my object AudioPlayer to my Service. Is it that possible?
I can try to put the logic of my MediaPlayer within Service, but I want to keep things decouple.
Yes It is possible.For communication between service and fragment you can use
1.BroadCast Receiver or 2.Messenger
Using messengers refer this link Communication between an Application class and Service in Android
Create a public interface that allows you to communicate between your service and object.
public interface MyListener {
public void receiveNotification();
}
After that, you have to make your object implements that interface.
public class MediaObject implements MyListener {
public void init () {
InitService.getService.addListener(this);
}
#Override
public void receiveNotification () {
//what you want to do
}
//rest of your class
To make it work you should have in your service class sth like:
public class YourService extends Service {
MyListener listener;
public YourService static getService () {
return YourService.this;
}
public void addListener (MyListener listener) {
this.listener = listener;
}
public void methodYouWantToCommunicateWithObject () {
//your code
if (listener!= null) {
listener.receiveNotification();
}
}

How to notify an activity when GlobalVariables are changed

I have an android application that is connected to the computer via USB cable. I use a TCPServer Class to send messages and listen. For example:
When I send a message like: request:x
I get the response: response:x:55
I need to make changes on my activity according to the response I get. At the moment I temporarily solved the problem by passing activity and activity class object to the TCPServer's constructor
public TCPServer(int portNum, Activity activity, IntroActivity ia) {
super();
port = portNum;
this.activity = activity;
this.ia = ia;
}
Then after I receive the response:
void updateButton(final int color, final String txt) {
activity.runOnUiThread(new Runnable() {
public void run() {
ia.getConnectionButton().setBackgroundColor(color);
ia.getConnectionButton().setText(txt);
}
});
}
As you see, this is not effective at all. I need to somehow notify the activity whenever a relevant variable is received. I use a Class for GlobalVariables and change those static variables after listen(), however I am having troubles notifying the activity.
First of all, it is almost always bad practice to pass Activity instances around. This is a time when it's bad.
Define an interface and use a callback to let the activity know that a response has been received.
public interface ResponseReceivedListener {
void onResponseReceived(int arg1, string arg2); // <- add arguments you want to pass back
}
In your TCPServer class:
ArrayList<ResponseReceivedListener> listeners = new ArrayList<>();
// ...
public void setResponseReceivedListener(ResponseReceivedListener listener) {
if (!listeners.contains(listener) {
listeners.add(listener);
}
}
public void removeResponseReceivedListener(ResponseReceivedListener listener) {
if (listeners.contains(listener) {
listeners.remove(listener);
}
}
When you receive a response:
for (ResponseReceivedListener listener : listeners) {
listener.onResponseReceived(arg1, arg2);
}
In your Activity:
public class MainActivity extends Activity implements ResponseReceivedListener {
// ...
#Override
public void onCreate(Bundle savedInstanceState) {
// ...
tcpServer.setResponseReceivedListener(this);
// ...
}
public void onResponseReceived(int arg1, string arg2) {
// do whatever you need to do
}
// ...
}
All from memory so please excuse typos.
This approach decouples the classes. The TCP Server has no knowledge of the activities. It simply calls back to any listeners registered. Those listeners might be Activities, they might be services. They might be instances of MySparklyUnicorn. The server neither knows nor cares. It simply says "if anyone's interested, I've received a response and here are the details".

Android - event listener

I hope this will be simple question.
I have main activity, on this activity I create an instance of some class. How to send some event form one class to main one? How to setup some kind a listener to send notifications between classes. Only option what I know/use right now is to keep reference to parent class and call directly some function from child class.
I'm wonder if it possible to create something like is in ActionScript, where I can call to dispatchEvent(new Event("name")) and later setup addEventlistener("name" function) ??
If "I implement some class" means that you have declared a nested class inside your Activity class than nested non-static class will have a reference to parent class object.
In general, you can always create dispatcher/listener pattern your self. Create listener interface and add either addListener or setListener method to class that will dispatch event.
Example of listener:
public interface IAsyncFetchListener extends EventListener {
void onComplete(String item);
void onError(Throwable error);
}
Example of event dispatcher:
public class FileDownloader {
IAsyncFetchListener fetchListener = null;
...
private void doInBackground(URL url) {
...
if (this.fetchListener != null)
this.fetchListener.onComplete(result);
}
public void setListener(IAsyncFetchListener listener) {
this.fetchListener = listener
}
}
Example of class with event listener:
public class MyClass {
public void doSomething() {
FileDownloader downloader = new FileDownloader();
downloader.setListener(new IAsyncFetchListener() {
public void onComplete(String item) {
// do something with item
}
public void onError(Throwable error) {
// report error
}
});
downloader.start();
}
}
Just implement a listener(or a list of listeners) on the class that generates the events.
When an event is generated iterate over this list and call a method that all the listeners must implement (via an interface maybe?)
Hope it helped,
JQCorreia

Callback routine in Android

I ran into a piece of Android code. I don't quite understand the purpose of the callback because it's empty.
In Animation.java
private AnimationCallback callback = null;
public Animation(final AnimationCallback animationCallBack) {
this();
callback = animationCallBack;
}
public void stop() {
if (callback != null) {
callback.onAnimationFinished(this);
}
active = false;
}
public interface AnimationCallback { void onAnimationFinished(final Animation animation); }
but in AnimationCallback there's only
public interface AnimationCallback {
void onAnimationFinished(final Animation animation);
}
I guess my question is what does callback.onAnimationFinished(this) do? There doesn't seem to have anything inside the routine.
The constructor is declared to take anything that implements the AnimationCallback interface. In Java, an interface defines the behavior of an object without specifying any of its behavior.
The actual object that gets passed to the constructor is some concrete class that implements the AnimationCallback interface. You'd have to know the actual class of the object being used to know what it does.
Per request, here's a simple (and fairly useless) class that just logs the fact that an animation has finished:
public AnimationFinishedLogger implements AnimationCallback {
public void onAnimationFinished(final Animation animation) {
Log.i("AnimationLogger", "Animation finished");
}
}

How to Define Callbacks in Android?

During the most recent Google IO, there was a presentation about implementing restful client applications. Unfortunately, it was only a high level discussion with no source code of the implementation.
In this diagram, on the return path there are various different callbacks to other methods.
How do I declare what these methods are?
I understand the idea of a callback - a piece of code that gets called after a certain event has happened, but I don't know how to implement it. The only way I've implemented callbacks so far have been overriding various methods (onActivityResult for example).
I feel like I have a basic understanding of the design pattern, but I keep on getting tripped up on how to handle the return path.
In many cases, you have an interface and pass along an object that implements it. Dialogs for example have the OnClickListener.
Just as a random example:
// The callback interface
interface MyCallback {
void callbackCall();
}
// The class that takes the callback
class Worker {
MyCallback callback;
void onEvent() {
callback.callbackCall();
}
}
// Option 1:
class Callback implements MyCallback {
void callbackCall() {
// callback code goes here
}
}
worker.callback = new Callback();
// Option 2:
worker.callback = new MyCallback() {
void callbackCall() {
// callback code goes here
}
};
I probably messed up the syntax in option 2. It's early.
When something happens in my view I fire off an event that my activity is listening for:
// DECLARED IN (CUSTOM) VIEW
private OnScoreSavedListener onScoreSavedListener;
public interface OnScoreSavedListener {
public void onScoreSaved();
}
// ALLOWS YOU TO SET LISTENER && INVOKE THE OVERIDING METHOD
// FROM WITHIN ACTIVITY
public void setOnScoreSavedListener(OnScoreSavedListener listener) {
onScoreSavedListener = listener;
}
// DECLARED IN ACTIVITY
MyCustomView slider = (MyCustomView) view.findViewById(R.id.slider)
slider.setOnScoreSavedListener(new OnScoreSavedListener() {
#Override
public void onScoreSaved() {
Log.v("","EVENT FIRED");
}
});
If you want to know more about communication (callbacks) between fragments see here:
http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
No need to define a new interface when you can use an existing one: android.os.Handler.Callback. Pass an object of type Callback, and invoke callback's handleMessage(Message msg).
Example to implement callback method using interface.
Define the interface, NewInterface.java.
package javaapplication1;
public interface NewInterface {
void callback();
}
Create a new class, NewClass.java. It will call the callback method in main class.
package javaapplication1;
public class NewClass {
private NewInterface mainClass;
public NewClass(NewInterface mClass){
mainClass = mClass;
}
public void calledFromMain(){
//Do somthing...
//call back main
mainClass.callback();
}
}
The main class, JavaApplication1.java, to implement the interface NewInterface - callback() method. It will create and call NewClass object. Then, the NewClass object will callback it's callback() method in turn.
package javaapplication1;
public class JavaApplication1 implements NewInterface{
NewClass newClass;
public static void main(String[] args) {
System.out.println("test...");
JavaApplication1 myApplication = new JavaApplication1();
myApplication.doSomething();
}
private void doSomething(){
newClass = new NewClass(this);
newClass.calledFromMain();
}
#Override
public void callback() {
System.out.println("callback");
}
}
to clarify a bit on dragon's answer (since it took me a while to figure out what to do with Handler.Callback):
Handler can be used to execute callbacks in the current or another thread, by passing it Messages. the Message holds data to be used from the callback. a Handler.Callback can be passed to the constructor of Handler in order to avoid extending Handler directly. thus, to execute some code via callback from the current thread:
Message message = new Message();
<set data to be passed to callback - eg message.obj, message.arg1 etc - here>
Callback callback = new Callback() {
public boolean handleMessage(Message msg) {
<code to be executed during callback>
}
};
Handler handler = new Handler(callback);
handler.sendMessage(message);
EDIT: just realized there's a better way to get the same result (minus control of exactly when to execute the callback):
post(new Runnable() {
#Override
public void run() {
<code to be executed during callback>
}
});
You can also use LocalBroadcast for this purpose. Here is a quick guide
Create a broadcast receiver:
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter("speedExceeded"));
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Double currentSpeed = intent.getDoubleExtra("currentSpeed", 20);
Double currentLatitude = intent.getDoubleExtra("latitude", 0);
Double currentLongitude = intent.getDoubleExtra("longitude", 0);
// ... react to local broadcast message
}
This is how you can trigger it
Intent intent = new Intent("speedExceeded");
intent.putExtra("currentSpeed", currentSpeed);
intent.putExtra("latitude", latitude);
intent.putExtra("longitude", longitude);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
unRegister receiver in onPause:
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}
asume the main function is the activity that is triggering the event:
fun main() {
val worker = Worker()
worker.setOnCallListener(
object: OnCallListener {
override fun onCall() {
// here we define what should happen
// when the event accures
print("event happend")
}
}
)
// most events will be called from Android system itself
// but in our case we have to call it manually
worker.listener.onCall()
}
the Worker class has an instance of Type OnCallListener interface
and a method to set its value:
class Worker() {
lateinit var listener: OnCallListener
fun setOnCallListener(listener: OnCallListener) {
this.listener = listener
}
}
and the OnCallListener interface looks like this:
interface OnCallListener {
fun onCall()
}

Categories

Resources