I'm doing some dev for a Chromecast sender app, and I have this method in my MainActivity class:
public void sendMessage(String message) {
if (mApiClient != null && mHelloWorldChannel != null) {
try {
Cast.CastApi.sendMessage(mApiClient, mHelloWorldChannel.getNamespace(), message)
.setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status result) {
if (!result.isSuccess()) {
Log.e(TAG, "Sending message failed");
} else {
System.out.println("Message sent!");
}
}
});
} catch (Exception e) {
Log.e(TAG, "Exception while sending message", e);
}
} else {
if (mApiClient == null) {
System.out.println("apiClient null");
}
if (mHelloWorldChannel == null) {
System.out.println("mHello null");
}
}
}
Every works dandy and I can send messages to my Chromecast and do nifty things with them when they get there. However, I use a number of other Activities in my app, and I'd like to be able to send messages to the Chromecast from those as well.
That said, what is the best way to access this method from a second activity?
If you will define your method static one then you can call it like this:
ClassName.sendMessage(String message);
If it is not static one, you will need to create an object for it.
ClassName c= new ClassName(SomeconstructorParams);
c.sendMessage(String message);
Related
I have two different types of messages and I am handling these message by two different listener.
I am adding listener in one class
public DrawingXmppServices(SurfaceViewCanvas surfaceView) {
chat = chatManager.createChat(BUDDY, new MyChatListener());
chat.addMessageListener(new MyChatListener());
receiver = surfaceView;
}
public void sendDrawingData(String drawingData, String buddyId) {
try {
chat.sendMessage(drawingData);
} catch (XMPPException e) {
e.printStackTrace();
}
}
And On other class
public InstantMessageXmpp(CanvasActivity canvasActivity) {
receiver = (MessageReceiver) canvasActivity;
chat = chatManager.createChat(BUDDY, this);
chat.addMessageListener(this);
}
public void sendIM(String message, String buddyID) {
try {
chat.sendMessage(message);
} catch (XMPPException e) {
e.printStackTrace();
}
}
When I call InstantMessageXmpp to send its packet but the listener of DrawingXmppServices is called. What mistake is I am doing?
Please guide me. Any suggestion can help me. Thank you
I want to get the wi-fi direct name when I execute request peers, here is my code:
if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
Log.d(tag, "success discover the peers ");
if (mManager != null) {
mManager.requestPeers(mChannel, new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
// TODO Auto-generated method stub
if (peers != null) {
if (device.deviceName.equals("ABC")) {
Log.d(tag, "found device!!! ");
Toast.makeText(getApplicationContext(), "FOUND!!", Toast.LENGTH_SHORT).show();
}
}
}
});
} else {
Log.d(tag, "mMaganger == null");
}
}
I want to get the deviceName from the list of peers so that I can found that one named "ABC". Any idea?
If you want others device name:
wifiP2pManager.requestPeers(wifiChannel, new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList wifiP2pDeviceList) {
for (WifiP2pDevice device : wifiP2pDeviceList.getDeviceList())
{
if (device.deviceName.equals("ABC")) Log.d(tag, "found device!!! ");
// device.deviceName
}
}
});
If you want your device name get it in the receiver:
if (action.equals(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION))
{
WifiP2pDevice device = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
// device.deviceName
}
If you want to change device name:
try {
Method method = wifiP2pManager.getClass().getMethod("setDeviceName",
WifiP2pManager.Channel.class, String.class, WifiP2pManager.ActionListener.class);
method.invoke(wifiP2pManager, wifiChannel, "New Device Name", new WifiP2pManager.ActionListener() {
public void onSuccess() {}
public void onFailure(int reason) {}
});
} catch (Exception e) {}
You have the object for WifiP2pDeviceList(peers)
Call the method getDeviceList() on peers which returns a collection(list) of P2p devices Collection<WifiP2pDevice>
Then iterate through the collection element which is a WifiP2pDevice and it would contain the deviceName property which is what you need exactly.
Refer this training from android developers
Hope you are able to get it
I created a Websocket service class using KOUSH library https://github.com/koush/AndroidAsync#can-also-create-web-sockets
Now I want to check if the Websocket is connected to my server from my mainActivity. Do you know how I can check this?
thanks
AsyncHttpClient.getDefaultInstance().websocket(get, "my-protocol", new WebSocketConnectCallback() {
#Override
public void onCompleted(Exception ex, WebSocket webSocket) {
if (ex != null) {
ex.printStackTrace();
return;
}
webSocket.send("a string");
webSocket.send(new byte[10]);
webSocket.setStringCallback(new StringCallback() {
public void onStringAvailable(String s) {
System.out.println("I got a string: " + s);
}
});
webSocket.setDataCallback(new DataCallback() {
public void onDataAvailable(ByteBufferList byteBufferList) {
System.out.println("I got some bytes!");
// note that this data has been read
byteBufferList.recycle();
}
});
}
});
You can do something like this:
if (mWebSocketClient.isOpen) {
mWebSocketClient.send(jObj.toString())
} else {
try {
client.connectWebSocket(p0)
mWebSocketClient.send(jObj.toString())
} catch (e : Exception){
Toast.makeText(p0, "not connected $e", Toast.LENGTH_LONG).show()
}
}
The solution is to save the result of this Function to a local Websocket Variable , and then you check its status :
WebSocket webSocket=null;
try {
webSocket=AsyncHttpClient.getDefaultInstance().websocket(get, "my-protocol", new WebSocketConnectCallback() {
#Override
public void onCompleted(Exception ex, WebSocket webSocket) {
if (ex != null) {
ex.printStackTrace();
return;
}
webSocket.send("a string");
webSocket.send(new byte[10]);
webSocket.setStringCallback(new StringCallback() {
public void onStringAvailable(String s) {
System.out.println("I got a string: " + s);
}
});
webSocket.setDataCallback(new DataCallback() {
public void onDataAvailable(ByteBufferList byteBufferList) {
System.out.println("I got some bytes!");
// note that this data has been read
byteBufferList.recycle();
}
});
}
}).get();
}catch(InterruptedException e){
//handle exception
}catch(ExecutionException e){
//handle exception
}
if(websocket!=null && websocket.isOpen()){
//websocket is working fine
}
you can use other statements like websocket.isClosed();
I'm writing an Android messaging application, and 1 class is calling another class, and I wish for the calling class to wait for the callee class to complete before carrying on.
Caller Class (MessageManagement) code snippet is as follows:
private static Messenger myMessenger;
try {
Message msg = Message.obtain();
msg.arg1 = constructedMessage.length();
msg.arg2 = -1;
msg.obj = constructedMessage;
Log.d(TAG, "Calling myMessenger.send()");
myMessenger.send(msg);
Log.d(TAG, "Sent");
} catch (Exception e) {
e.printStackTrace();
}
// Wait here until myMessenger completes its task
doOtherStuff();
Right now, doOtherStuff() starts and finishes before myMessenger starts. I need myMessenger to complete before doOtherStuff() starts.
I've read about wait() and notify() but I'm not sure how to implement it here, or whether it's the right choice.
Some background about the flow of the program. It's basically a messaging app that I inherited, so I'm not exactly sure of its framework. From what I can tell tracing the flow of the code:
When an SMS message is received, the SMS receiver BroadcastReceiver(SmsReceiver) handles it, getting the sender address and message body, then calling a SMS handler service(HandleSmsService), which then calls the caller class in a runnable with the following code:
HandleSmsService
public class HandleSmsService extends Service {
private String message;
private MessageManagement messageManager;
private Handler timeoutHandler = new Handler();
#Override
public void onStart(Intent intent, intent startid) {
message = intent.getExtras().getString("message");
messageManager = new MessageManagement(this);
timeoutHandler.postDelayed(runnable, 10);
}
private Runnable runnable = new Runnable() {
#Override
public void run() {
try {
messageManager.handleMessage(message);
stopSelf();
} catch (Exception e) {
e.printStackTrace();
}
}
};
MessageManagement is my caller class, and MessageManagement.handleMessage() is the top most code snippet presented earlier.
The MessageManagement.handleMessage() apparently calls another Handler in the callee class when it calls myMessenger.send(msg). This Handler code is as follows:
private Handler smsHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// do some stuff
}
};
I'm assuming the posted code is running on the MainThread and the reason why you are using a handler is that something asynchronous is done on another thread when receiving that message.
In that case, you can't use wait on the thread, as it will lock up the UI and probably cause an application not responding error.
Without changing too much of your code, one way to do it is to nest a listener in your constructedMessage for e.g.
public class DoStuffRequest {
private OnFinishListener mOnFinishListener;
private boolean isCanceled;
private String mMessage;
public interface OnFinishListener {
public void onFinish();
}
public DoStuffRequest(String message) {
mMessage = message;
}
public OnFinishListener getOnFinishListener() {
return mOnFinishListener;
}
public void setOnFinishListener(OnFinishListener onFinishListener) {
mOnFinishListener = onFinishListener;
}
public void cancel() {
isCanceled = true;
}
public void notifyFinish() {
if (!isCanceled && mOnFinishListener != null) {
mOnFinishListener.onFinish();
}
}
public String getMessage() {
return mMessage;
}
}
then use some along the line of this to get the ball rolling:
private static Messenger myMessenger;
private DoStuffRequest mRequest;
...
private void send(String message) {
mRequest = new DoStuffRequest(message);
mRequest.setOnFinishListener(new ConstructedMessage.OnFinishListener() {
#Override
public void onFinish() {
doOtherStuff();
}
});
try {
Message msg = Message.obtain();
msg.arg1 = constructedMessage.length();
msg.arg2 = -1;
msg.obj = constructedMessage;
Log.d(TAG, "Calling myMessenger.send()");
myMessenger.send(msg);
Log.d(TAG, "Sent");
} catch (Exception e) {
e.printStackTrace();
}
}
private void doThisIfYouWantToCancel() {
if (mRequest != null) {
mRequest.cancel();
}
}
your Handler/Service code can now call constructedMessage.finish() when the async stuff is done. Depending on what doOtherStuff() does (e.g. when manipulating the UI), you might want to do this on the MainThread (the code i've written above is NOT thread safe and i assume you are calling the listener on the MainThread).
Also remember to call constructedMessage.cancel() in case you do not want to get notified any more (e.g. you are leaving the activity/fragment).
this is just one way to do it, depending on your needs, some other methods might be a better choice.
I guess it should look something like this:
try {
Message msg = Message.obtain(handler, new Runnable() {
#Override
public void run() {
doOtherStuff();
}
});
msg.arg1 = constructedMessage.length();
msg.arg2 = -1;
msg.obj = constructedMessage;
Log.d(TAG, "Calling myMessenger.send()");
msg.sendToTarget();
Log.d(TAG, "Sent");
} catch (Exception e) {
e.printStackTrace();
}
The other way to do this using native means:
private static Messenger myMessenger = new Messenger(new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
// do something what you need
if (msg.getTarget() != null) {
msg.sendToTarget();
}
return false;
}
}));
try {
final Message msg = Message.obtain();
msg.setTarget(new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
doOtherStuff();
return false;
}
}));
msg.arg1 = constructedMessage.length();
msg.arg2 = -1;
msg.obj = constructedMessage;
Log.d(TAG, "Calling myMessenger.send()");
myMessenger.send(msg);
Log.d(TAG, "Sent");
} catch (final Exception e) {
e.printStackTrace();
}
I am trying to make a plugin for Phonegap (Android) that allows my javascript to send and receive messages to / from a service.
My exact problem is, that because the messages return asynchronous, I cannot send the PluginResult to the execute function of the plugin.
This is the plugin code:
public class ServiceClient_plugin extends Plugin {
Messenger messenger_service=null;
boolean connected_to_service=false;
final Messenger messenger_receive = new Messenger(new IncomingHandler());
#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
PluginResult result = null;
try {
if (action.toUpperCase().equals("CONNECT")) {
result = ConnectService();
} else if (action.toUpperCase().equals("DISCONNECT")) {
result = DisconnectService();
} else if (action.toUpperCase().equals("IS_CONNECTED")) {
result = new PluginResult(Status.OK,connected_to_service);
} else if (action.toUpperCase().equals("COMMAND")) {
sendMSG (data.getString(0));
result = new PluginResult(Status.OK);
} else {
result = new PluginResult(Status.INVALID_ACTION);
}
} catch(JSONException e) {
result= new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
return result;
}
private PluginResult ConnectService() {
doBindService();
return new PluginResult(Status.OK);
}
private PluginResult DisconnectService() {
doUnbindService();
return new PluginResult(Status.OK);
}
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MoMe_Service.MSG_COMMAND:
Log.i("CLIENT","Received from service: " + msg.getData().getString("MSG"));
break;
default:
super.handleMessage(msg);
}
}
}
private ServiceConnection service_connection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
messenger_service = new Messenger(service);
connected_to_service=true;
try {
Message msg = Message.obtain(null, My_Service.MSG_REGISTERED);
msg.replyTo = messenger_receive;
messenger_service.send(msg);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
messenger_service = null;
connected_to_service=false;
}
};
private void doBindService() {
// Establish a connection with the service. We use an explicit
// class name because there is no reason to be able to let other
// applications replace our component.
this.ctx.bindService(new Intent(this.ctx, My_Service.class), service_connection, Context.BIND_AUTO_CREATE);
}
private void doUnbindService() {
if (connected_to_service) {
if (messenger_service != null) {
try {
Message msg = Message.obtain(null, My_Service.MSG_UNREGISTERED);
msg.replyTo = messenger_receive;
messenger_service.send(msg);
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
}
}
// Detach our existing connection.
this.ctx.unbindService(service_connection);
connected_to_service = false;
}
}
private void sendMSG (String message) {
try {
Message msg=Message.obtain(null, My_Service.MSG_COMMAND);
Bundle msg_bundle=new Bundle();
msg_bundle.putString("MSG", message);
msg.setData(msg_bundle);
messenger_service.send(msg);
} catch (RemoteException e) {
doUnbindService();
}
}
}
From this plugin the real trouble comes with this part of code, which handles the return messages and the plugin return (which goes to the javascript):
#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
PluginResult result = null;
try {
result = new PluginResult(Status.ok);
}
} catch(JSONException e) {
result= new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
return result;
}
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MoMe_Service.MSG_COMMAND:
msg.getData().getString("MSG")); // THIS IS THE DATA I NEED RETURNED
break;
default:
super.handleMessage(msg);
}
}
}
The only solution I can think of, is storing the response in either a database or a variable and have the javascript do a setInterval to keep checking for changes. However I am not very fond of this solution. I would like to use some sort of callback function to let the javascript know the message has returned but I have no idea how. I would greatly appreciate any help and ideas.
Thank you,
Vlad
This might be a late answer but I started to work with Cordova Plugin around 5 months ago and I just saw your question. Since you did not choose the correct answer I wanted to answer your question.
Assuming you have asynchronous process and you have a listener and methods, success and fail , lets call it onSuccess() and onFail(). As long as you send true with pluginResult.setKeepCallback(true), the process will remain as unfinished, so you can send your plugin result data later on when you are done with background process. Here is an example take a look.
#Override
public boolean execute(String action, JSONArray data, String callbackId) throws JSONException {
if (action.equals("start")) {
start();
} else {
PluginResult pluginResult = new PluginResult(PluginResult.Status.INVALID_ACTION);
callbackContext.sendPluginResult(pluginResult);
return false;
}
}
private boolean start() throws JSONException {
MyClass.startProcess(new MyInterface() {
#Override
public void onSuccess(String data) {
PluginResult result = new PluginResult(PluginResult.Status.OK, data);
result.setKeepCallback(false);
callbackContext.sendPluginResult(result);
}
#Override
public void onFail() {
PluginResult result = new PluginResult(PluginResult.Status.ERROR);
result.setKeepCallback(false);
callbackContext.sendPluginResult(result);
}
});
PluginResult.Status status = PluginResult.Status.NO_RESULT;
PluginResult pluginResult = new PluginResult(status);
pluginResult.setKeepCallback(true);
callbackContext.sendPluginResult(pluginResult);
return true;
}
The answer to my problem was actually in the the PluginResult object and success method.
I've found a plugin that had to face the same problem in order to work, and from this code i was able to figure out my answer.This is a onPhoneStatusChange plugin, which can be found here!
The mystery lies in these lines:
PluginResult res = new PluginResult(PluginResult.Status.OK, obj);
res.setKeepCallback(true);
success(res, callbackId);
The generic solution to this problem is to have the service store the response into persistent storage (like a database) and then fire off a broadcast intent. Then just have a BroadcastReciever in your ServiceClient_plugin class listening for the broadcast. This way you woun't have to keep polling to see if the data has arrived yet.
You can send PluginResult using success() function like this:
public PluginResult execute(String action, JSONArray data, String callbackId) {}
private BroadcastReceiver Wifi_Receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
MyClass.this.success(new PluginResult(PluginResult.Status.OK,"count"+count),callback);
}
}
here callback is callbackId of execute() function