There is a problem when receiving the response,
response.body().success
it returns 0 but I expect 1
it shows a toast shows Failed! As the code below which means the response doesn't succeed
mService = Common.getFCMService();
private void sendNotificationOrder(String order_number) {
DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Tokens");
Query data = tokens.orderByChild("isServerToken").equalTo(true);
data.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapShot:dataSnapshot.getChildren()) {
Token serverToken = postSnapShot.getValue(Token.class);
Notification notification = new Notification("Ziead's Company", "You have New Order" + order_number);
Sender content = new Sender(serverToken.getToken(), notification);
mService.sendNotification(content)
.enqueue(new Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
try {
//Here It is Returning "0" not 1 System.out.println(response.body().success);
if (response.code() == 200) {
if (response.body().success == 1) {
System.out.println("Succeedd");
Toast.makeText(Cart.this, "Thank you , Order Place", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(Cart.this, "Failed !!!", Toast.LENGTH_SHORT).show();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
Log.e("ERROR", t.getMessage());
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
Token.java:
public class Token {
private String token;
private boolean isServerToken;
public Token() {
}
public Token(String token, boolean isServerToken)
{
this.token = token;
this.isServerToken = isServerToken;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public boolean isServerToken() {
return isServerToken;
}
public void setServerToken(boolean serverToken) {
isServerToken = serverToken;
}
}
Notification.java:
public class Notification {
public String body;
public String title;
public Notification(String body, String title) {
this.body = body;
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Sender.java:
public class Sender {
public String to;
public Notification notification;
public Sender(String to, Notification notification) {
this.to = to;
this.notification = notification;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public Notification getNotification() {
return notification;
}
public void setNotification(Notification notification) {
this.notification = notification;
}
}
Common.java:
public class Common {
public static APIService getFCMService(){
return RetrofitClient.getClient(BASE_URL).create(APIService.class);
}
}
APIService Interface:
public interface APIService {
#Headers(
{
"Content-Type:application/json",
"Authorization:key=AAAA0EXeo9E:APA91bGeAWN69zVVIKh9ib_XA6OkMnEA1S0_sZILrJ1civQVF-eelOAF4o3qCOTZpRgSwb9bySoU92ypchs5BqOE2P1Y_FPlvUanIrV2g7RPCY7IpGjYqSK1rlKVxODm6v8R"
}
)
#POST("fcm/send")
Call<MyResponse> sendNotification(#Body Sender body);
}
RetrofitClient.java:
This is all the code related to the main code
Related
Cannot get sinch call when app is clear from recent in android
public class SinchService extends Service {
private static final String APP_KEY = "";
private static final String APP_SECRET = "";
private static final String ENVIRONMENT = "clientapi.sinch.com";
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchService.class.getSimpleName();
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient;
private String mUserId;
private StartFailedListener mListener;
#Override
public void onCreate() {
super.onCreate();
}
private void start(String userName) {
Log.d("start123", "start");
if (mSinchClient == null) {
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(userName)
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT).build();
mSinchClient.setSupportManagedPush(true);
mSinchClient.setSupportCalling(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.setSupportActiveConnectionInBackground(true);
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.start();
}
}
private void stop() {
if (mSinchClient != null) {
mSinchClient.terminate();
mSinchClient = null;
}
}
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
#Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public Call callUserVideo(String userId) {
return mSinchClient.getCallClient().callUser(userId);
}
public Call callUser(String userId) {
return mSinchClient.getCallClient().callUserVideo(userId);
}
public String getUserName() {
return mUserId;
}
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName) {
start(userName);
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
public VideoController getVideoController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getVideoController();
}
public AudioController getAudioController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getAudioController();
}
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client,
ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
FirebaseAuth auth = FirebaseAuth.getInstance();
DatabaseReference cal = FirebaseDatabase.getInstance().getReference().child("call_detail").child(auth.getCurrentUser().getUid()).child(call.getCallId());
cal.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
String cl = dataSnapshot.child("callType").getValue(String.class);
if( cl.equals("audio") ){
Intent intent = new Intent(SinchService.this, IncomingVoiceCallActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.putExtra("callerUserId", call.getRemoteUserId());
Log.d("ABCD", call.getRemoteUserId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}if (cl.equals("video")){
Intent intent = new Intent(SinchService.this, IncomingVideoCallActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.putExtra("callerUserId", call.getRemoteUserId());
Log.d("ABCD", call.getRemoteUserId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
}
I received call when app is in recent tray. but when i clear app from recent i cannot get call. this is my SinchService class. i also used forground service, with foreground service i get call on some devices on app close but not get call on some oppo and samsung mobiles.
I am trying to use Google Nearby Connections API to connect two Android devices to exchange data but no success.
The devices can found eachother none of them can connect to the other. It always fails at onConnectionInitiated() with
STATUS_ENDPOINT_UNKNOWN when I try to accept the connection.
I tried it with Strategy.P2P_POINT_TO_POINT Strategy.CLUSTER and Strategy.STAR but I get the same result.
Anyone can help me what do I miss?
Both devices are physical and running on Android 9.0
This is the code:
public static ConnectionLifecycleCallback connectionLifecycleCallback;
public static EndpointDiscoveryCallback endpointDiscoveryCallback;
public static PayloadCallback payloadCallback;
public static String SERVICE_ID;
public Context ctx;
public static Strategy STRATEGY;
public NearbyHandler(Context ctx,Strategy STRATEGY){
this.ctx = ctx;
this.STRATEGY = STRATEGY;
SERVICE_ID = ctx.getPackageName();
payloadCallback = new PayloadCallback() {
#Override
public void onPayloadReceived(#NonNull String s, #NonNull Payload payload) {
Log.d("NEARBY_", "PAYLOAD RECEIVED " + s);
}
#Override
public void onPayloadTransferUpdate(#NonNull String s, #NonNull PayloadTransferUpdate payloadTransferUpdate) {
Log.d("NEARBY_", "PAYLOAD TRANSFER UPDATE " + s);
}
};
connectionLifecycleCallback = new ConnectionLifecycleCallback() {
#Override
public void onConnectionInitiated(#NonNull String s, #NonNull ConnectionInfo connectionInfo) {
Nearby.getConnectionsClient(ctx)
.acceptConnection(s, payloadCallback)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("NEARBY_", "SUCCESSFULLY CONNECTED");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
e.printStackTrace();
}
});
}
#Override
public void onConnectionResult(#NonNull String s, #NonNull ConnectionResolution connectionResolution) {
switch (connectionResolution.getStatus().getStatusCode()) {
case ConnectionsStatusCodes.STATUS_OK:
Nearby.getConnectionsClient(ctx).stopAdvertising();
Nearby.getConnectionsClient(ctx).stopDiscovery();
break;
case ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED:
break;
case ConnectionsStatusCodes.STATUS_ERROR:
break;
}
}
#Override
public void onDisconnected(#NonNull String s) {
Log.d("NEARBY_", "DISCONNECTED " + s);
}
};
endpointDiscoveryCallback = new EndpointDiscoveryCallback() {
#Override
public void onEndpointFound(#NonNull String s, #NonNull DiscoveredEndpointInfo discoveredEndpointInfo) {
Nearby.getConnectionsClient(ctx)
.requestConnection(
s,
ctx.getPackageName(),
connectionLifecycleCallback)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("NEARBY_", "ENDPOINT CONNECTED");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("NEARBY_", "FAILED TO CONNECT ENDPOINT " + e.getMessage());
e.printStackTrace();
}
});
}
#Override
public void onEndpointLost(#NonNull String s) {
Log.d("NEARBY_", "ENDPOINT LOST: " + s);
}
};
}
public void startDiscovering() {
Nearby.getConnectionsClient(ctx)
.startDiscovery(
SERVICE_ID,
endpointDiscoveryCallback,
new DiscoveryOptions.Builder()
.setStrategy(CONSTANTS.PEERTOPEER_STRATEGY).build())
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("NEARBY_DISCOVERER_", "onSuccess");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
e.printStackTrace();
}
});
}
public void startAdvertising() {
Nearby.getConnectionsClient(ctx)
.startAdvertising(
Build.MODEL,
SERVICE_ID,
connectionLifecycleCallback,
new AdvertisingOptions.Builder()
.setStrategy(CONSTANTS.PEERTOPEER_STRATEGY).build())
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
e.printStackTrace();
}
});
}
}
NearbyHandler nearby = new NearbyHandler(getApplicationContext(), Strategy.P2P_POINT_TO_POINT);
if (IS_DEVICE_A) {
nearby.startAdvertising();
} else {
nearby.startDiscovering();
}
Update: Google's walkietalkie demo app works fine on both phones.
Finally I've managed to get it working but not sure about the problem.
I managed the connection lifecycle a bit different way than in the API Docs.
So I created a private helper class
class Endpoint {
#NonNull
private final String id;
#NonNull
private final String name;
public Endpoint(#NonNull String id, #NonNull String name) {
this.id = id;
this.name = name;
}
#NonNull
public String getId() {
return id;
}
#NonNull
public String getName() {
return name;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Endpoint) {
Endpoint other = (Endpoint) obj;
return id.equals(other.id);
}
return false;
}
#Override
public int hashCode() {
return id.hashCode();
}
#Override
public String toString() {
return String.format("Endpoint{id=%s, name=%s}", id, name);
}
}
The ConnectionLifecycleCallback() and EndpointDiscoveryCallback() should look like this:
endpointDiscoveryCallback = new EndpointDiscoveryCallback() {
#Override
public void onEndpointFound(#NonNull String s, #NonNull DiscoveredEndpointInfo discoveredEndpointInfo) {
Endpoint endpoint = new Endpoint(s, discoveredEndpointInfo.getEndpointName());
ConnectionsClient c = Nearby.getConnectionsClient(ctx);
c.requestConnection(endpoint.getName(), endpoint.getId(), connectionLifecycleCallback).addOnSuccessListener(new OnSuccessListener < Void > () {
#Override
public void onSuccess(Void aVoid) {}
});
}
#Override
public void onEndpointLost(#NonNull String s) {}
};
connectionLifecycleCallback = new ConnectionLifecycleCallback() {
#Override
public void onConnectionInitiated(#NonNull String s, #NonNull ConnectionInfo connectionInfo) {
Nearby.getConnectionsClient(ctx).stopAdvertising();
Nearby.getConnectionsClient(ctx).stopDiscovery();
Endpoint endpoint = new Endpoint(s, connectionInfo.getEndpointName());
ConnectionsClient c = Nearby.getConnectionsClient(ctx);
c.acceptConnection(endpoint.getId(), payloadCallback).addOnSuccessListener(new OnSuccessListener < Void > () {
#Override
public void onSuccess(Void aVoid) {}
});
}
#Override
public void onConnectionResult(#NonNull String s, #NonNull ConnectionResolution connectionResolution) {
switch (connectionResolution.getStatus().getStatusCode()) {
case ConnectionsStatusCodes.STATUS_OK:
Nearby.getConnectionsClient(ctx).stopAdvertising();
Nearby.getConnectionsClient(ctx).stopDiscovery();
break;
case ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED:
// The connection was rejected by one or both sides.
break;
case ConnectionsStatusCodes.STATUS_ERROR:
// The connection broke before it was able to be accepted.
break;
}
}
#Override
public void onDisconnected(#NonNull String s) {}
};
Android Studio shows this warning:
Unchecked call to List as a member of raw type 'ConnectionSuccess
How can I skip this warning should I check for the type or what?
Please help.
public class RequestTask {
private Context mContext;
ConnectionSuccess connectionSuccess;
RequestHandler requestHandler;
ProgressDialog progressDialog;
public RequestTask(Context context, ConnectionSuccess connectionSuccess) {
this.mContext = context;
this.connectionSuccess = connectionSuccess;
progressDialog = new ProgressDialog(mContext);
progressDialog.setMessage(mContext.getResources().getString(R.string.loading));
}
// Request a string response
public void MakeRequest() {
String URL = mContext.getResources().getString(R.string.menu_url);
if (ConnectionTracker.isNetworkAvailable(mContext)) {
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();
Response response1 = gson.fromJson(response, Response.class);
response1.setItemsList(response1.getItemsList());
//the warning shows here
connectionSuccess.onResponse(response1.getItemsList());
} catch (Exception e) {
e.printStackTrace();
}
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Error handling
progressDialog.dismiss();
Toast.makeText(mContext, mContext.getResources().getString(R.string.error_message), Toast.LENGTH_LONG).show();
error.printStackTrace();
}
});
// Add a request to RequestQueue.
MySingleton.getInstance(mContext).addToRequestQueue(stringRequest);
} else if (!ConnectionTracker.isNetworkAvailable(mContext)) {
Toast.makeText(mContext, mContext.getResources().getString(R.string.no_internet), Toast.LENGTH_LONG).show();
}
}
}
public class More extends Fragment implements ConnectionSuccess<Data> {
#Override
public void onResponse(List<Data> result) {
}
}
public interface ConnectionSuccess<T> {
void onResponse(List<T> result);
}
public class Data {
#SerializedName("arabic_title")
String arabic_title;
#SerializedName("english_title")
String english_title;
#SerializedName("url")
String url;
public String getArabic_title() {
return arabic_title;
}
public void setArabic_title(String arabic_title) {
this.arabic_title = arabic_title;
}
public String getEnglish_title() {
return english_title;
}
public void setEnglish_title(String english_title) {
this.english_title = english_title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
#SerializedName("data")
List<Data> itemsList;
public List<Data> getItemsList() {
return itemsList;
}
public void setItemsList(List<Data> itemsList) {
this.itemsList = itemsList;
}
public interface ConnectionSuccess<T> {
void onResponse(List<T> result);
}
ConnectionSuccess has a type parameter T, but in your constructor arg and field declaration you are not passing it a type parameter. You may mean both to be ConnectionSuccess<Data>
This will allow the compiler to figure out that when you call connectionSuccess.onResponse(response1.getItemsList()) that it should expect an argument of type List<Data>
I am trying to implement an Instant Messaging functionality into my app following this guide: https://www.sinch.com/tutorials/android-messaging-tutorial-using-sinch-and-parse/#start the sinch client
I have followed everything in the guide exactly, but when I attempt to send a message I get a NullPointerException. Here is the guilty code:
private void sendMessage() {
messageBody = messageBodyField.getText().toString();
if (messageBody.isEmpty()) {
Toast.makeText(getApplicationContext(), "Enter a message", Toast.LENGTH_LONG).show();
return;
}
Log.i(TAG, "messageService: " + messageService);
Log.i(TAG, "recipientId: " + recipientId);
Log.i(TAG, "messageBody: " + messageBody);
messageService.sendMessage(recipientId, messageBody);
messageBodyField.setText("");
}
From the logs, I see that the recipientId and messageBody are properly assigned, and that the messageService object is null. Below is the full code of the activity:
public class ChatActivity extends AppCompatActivity {
private static final String TAG = "ChatActivity";
private String recipientId;
private EditText messageBodyField;
private ListView messagesList;
private ChatAdapter chatAdapter;
private String messageBody;
private MessageService.MessageServiceInterface messageService;
private String currentUserId;
private ServiceConnection serviceConnection = new MyServiceConnection();
private MessageClientListener messageClientListener = new MyMessageClientListener();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);
bindService(new Intent(this, MessageService.class), serviceConnection, BIND_AUTO_CREATE);
//Log.i("Tag", "bindService(): " + bindService(new Intent(this, MessageService.class), serviceConnection, BIND_AUTO_CREATE));
Intent intent = getIntent();
recipientId = intent.getStringExtra("RECIPIENT_ID");
currentUserId = ParseUser.getCurrentUser().getObjectId();
messagesList = (ListView) findViewById(R.id.listview_chat);
chatAdapter = new ChatAdapter(this);
messagesList.setAdapter(chatAdapter);
loadMessageHistory();
messageBodyField = (EditText) findViewById(R.id.edittext_messageBodyField);
findViewById(R.id.button_send).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
}
private void loadMessageHistory() {
String[] userIds = {currentUserId, recipientId};
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseMessage");
query.whereContainedIn("senderId", Arrays.asList(userIds));
query.whereContainedIn("recipientId", Arrays.asList(userIds));
query.orderByAscending("createdAt");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> messageList, ParseException e) {
if (e == null) {
for (int i = 0; i < messageList.size(); i++) {
WritableMessage message = new WritableMessage(messageList.get(i).get("recipientId").toString(), messageList.get(i).get("messageText").toString());
if (messageList.get(i).get("senderId").toString().equals(currentUserId)) {
chatAdapter.addMessage(message, ChatAdapter.DIRECTION_OUTGOING);
} else {
chatAdapter.addMessage(message, ChatAdapter.DIRECTION_INCOMING);
}
}
}
}
});
}
private void sendMessage() {
messageBody = messageBodyField.getText().toString();
if (messageBody.isEmpty()) {
Toast.makeText(getApplicationContext(), "Enter a message", Toast.LENGTH_LONG).show();
return;
}
Log.i(TAG, "messageService: " + messageService);
Log.i(TAG, "recipientId: " + recipientId);
Log.i(TAG, "messageBody: " + messageBody);
messageService.sendMessage(recipientId, messageBody);
messageBodyField.setText("");
}
#Override
public void onDestroy() {
messageService.removeMessageClientListener(messageClientListener);
unbindService(serviceConnection);
super.onDestroy();
}
private class MyServiceConnection implements ServiceConnection {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
messageService = (MessageService.MessageServiceInterface) iBinder;
Log.i(TAG, "messageService::onServiceConnected: " + messageService);
messageService.addMessageClientListener(messageClientListener);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
messageService = null;
Log.i(TAG, "messageService::onServiceDisconnected: " + messageService);
}
}
private class MyMessageClientListener implements MessageClientListener {
#Override
public void onMessageFailed(MessageClient client, Message message, MessageFailureInfo failureInfo) {
Toast.makeText(ChatActivity.this, "Failed to send message", Toast.LENGTH_LONG).show();
}
#Override
public void onIncomingMessage(MessageClient client, final Message message) {
if (message.getSenderId().equals(recipientId)) {
final WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseMessage");
query.whereEqualTo("sinchId", message.getMessageId());
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> messageList, ParseException e) {
if (e == null) {
if (messageList.size() == 0) {
ParseObject parseMessage = new ParseObject("ParseMessage");
parseMessage.put("senderId", currentUserId);
parseMessage.put("recipientId", writableMessage.getRecipientIds().get(0));
parseMessage.put("messageText", writableMessage.getTextBody());
parseMessage.put("sinchId", message.getMessageId());
parseMessage.saveInBackground();
chatAdapter.addMessage(writableMessage, chatAdapter.DIRECTION_INCOMING);
}
}
}
});
}
}
#Override
public void onMessageSent(MessageClient client, Message message, String recipientId) {
final WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());
chatAdapter.addMessage(writableMessage, ChatAdapter.DIRECTION_OUTGOING);
}
#Override
public void onMessageDelivered(MessageClient client, MessageDeliveryInfo deliveryInfo) {
}
#Override
public void onShouldSendPushData(MessageClient client, Message message, List<PushPair> pushPairs) {
}
}
}
And the MessageService class code:
package com.example.aes.ctf;
public class MessageService extends Service implements SinchClientListener {
private static final String APP_KEY = "app-key";
private static final String APP_SECRET = "secret";
private static final String ENVIRONMENT = "";
private final MessageServiceInterface serviceInterface = new MessageServiceInterface();
private SinchClient sinchClient = null;
private MessageClient messageClient = null;
private String currentUserId;
//private Intent broadcastIntent = new Intent("com.example.aes.ctf.ListUsersActivity");
//private LocalBroadcastManager broadcaster;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
currentUserId = ParseUser.getCurrentUser().getObjectId();
if (currentUserId != null && !isSinchClientStarted()) {
startSinchClient(currentUserId);
}
//broadcaster = LocalBroadcastManager.getInstance(this);
return super.onStartCommand(intent, flags, startId);
}
public void startSinchClient(String username) {
sinchClient = Sinch.getSinchClientBuilder().context(this).userId(username)
.applicationKey(APP_KEY).applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT).build();
sinchClient.addSinchClientListener(this);
sinchClient.setSupportMessaging(true);
sinchClient.setSupportActiveConnectionInBackground(true);
sinchClient.checkManifest();
sinchClient.start();
}
private boolean isSinchClientStarted() {
return sinchClient != null && sinchClient.isStarted();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onClientStarted(SinchClient client) {
/*broadcastIntent.putExtra("success", true);
broadcaster.sendBroadcast(broadcastIntent);*/
client.startListeningOnActiveConnection();
messageClient = client.getMessageClient();
}
#Override
public void onClientStopped(SinchClient client) {
client = null;
}
#Override
public void onClientFailed(SinchClient client, SinchError sinchError) {
/*broadcastIntent.putExtra("success", false);
broadcaster.sendBroadcast(broadcastIntent);*/
client = null;
}
#Override
public void onRegistrationCredentialsRequired(SinchClient sinchClient, ClientRegistration clientRegistration) {
}
#Override
public void onLogMessage(int i, String s, String s1) {
}
public void sendMessage(String recipientUserId, String textBody) {
if (messageClient != null) {
WritableMessage message = new WritableMessage(recipientUserId, textBody);
messageClient.send(message);
}
}
public void addMessageClientListener(MessageClientListener listener) {
if (messageClient != null) {
messageClient.addMessageClientListener(listener);
}
}
public void removeMessageClientListener(MessageClientListener listener) {
if (messageClient != null) {
messageClient.removeMessageClientListener(listener);
}
}
#Override
public void onDestroy() {
sinchClient.stopListeningOnActiveConnection();
sinchClient.terminate();
}
public class MessageServiceInterface extends Binder {
public void sendMessage(String recipientUserId, String textBody) {
MessageService.this.sendMessage(recipientUserId, textBody);
}
public void addMessageClientListener(MessageClientListener listener) {
MessageService.this.addMessageClientListener(listener);
}
public void removeMessageClientListener(MessageClientListener listener) {
MessageService.this.removeMessageClientListener(listener);
}
public boolean isSinchClientStarted() {
return MessageService.this.isSinchClientStarted();
}
}
}
I can post more related code if needed. I've been stuck on this error for awhile.
EDIT:
I was able to fix it by changing
#Override
public IBinder onBind(Intent intent) {
return null;
}
to
#Override
public IBinder onBind(Intent intent) {
return serviceInterface;
}
Thanks guy!
well, this is because you never INITIALIZE the messageService object.
it seems like you wish to start a service and then - control it from your activity... are you sure you wish to send messages from a service rather from an AsyncTask?
AsyncTask also run in the background and much more easier to control for this purpose...
try to chek this link: http://developer.android.com/reference/android/os/AsyncTask.html
Your problem is here:
#Override
public IBinder onBind(Intent intent) {
return null;
}
You should implement a binder for your service and return it in the onBind method of your service, so in your MessageServiceInterface class declare following method:
public MessageService getService() {
Log.v("Serivce Bind", "Bind");
return MessageService.this;
}
}
And declare a field in MessageService class:
IBinder binder = new MessageSeviceInterface();
Return binder instance in onBind method and finally get the allocated instance of MessageService using following code:
Replace
messageService = (MessageService.MessageServiceInterface) iBinder;
With:
MessageService.MessageServiceInterface binder = (MessageService.MessageServiceInterface) iBinder;
messageService = binder.getService()`
This is my code...
public class FacebookShare extends FragmentActivity {
private static final String TAG = "FacebookShare";
private static final String PERMISSION = "publish_actions";
public static final String PACKAGE = "com.facebook.katana";
private final String PENDING_ACTION_BUNDLE_KEY = "com.myapp.mypackage.facebook.facebookshare:PendingAction";
private FragmentActivity mActivity;
private PendingAction pendingAction = PendingAction.NONE;
private GraphUser user;
private GraphPlace place;
private List<GraphUser> tags;
private boolean canPresentShareDialog;
private boolean canPresentShareDialogWithPhotos;
private String mTitle, mDescription, mUrlShare, mUrlImg;
private enum PendingAction {
NONE,
POST_PHOTO,
POST_STATUS_UPDATE
}
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
private FacebookDialog.Callback dialogCallback = new FacebookDialog.Callback() {
#Override
public void onError(FacebookDialog.PendingCall pendingCall, Exception error, Bundle data) {
Log.d("HelloFacebook", String.format("Error: %s", error.toString()));
}
#Override
public void onComplete(FacebookDialog.PendingCall pendingCall, Bundle data) {
Log.d("HelloFacebook", "Success!");
}
};
public FacebookShare(FragmentActivity act, String applicationId, String title, String description, String urlShare, String urlImg) {
mActivity = act;
mTitle = title;
mDescription = description;
mUrlShare = urlShare;
mUrlImg = urlImg;
uiHelper = new UiLifecycleHelper(mActivity, callback, applicationId);
uiHelper.onCreate(new Bundle());
canPresentShareDialog = FacebookDialog.canPresentShareDialog(mActivity,
FacebookDialog.ShareDialogFeature.SHARE_DIALOG);
canPresentShareDialogWithPhotos = FacebookDialog.canPresentShareDialog(mActivity,
FacebookDialog.ShareDialogFeature.PHOTOS);
}
public static void showDialog(FragmentActivity act){
try{
Intent waIntent = new Intent(Intent.ACTION_SEND);
waIntent.setPackage(WhatsApp.PACKAGE);
act.startActivity(Intent.createChooser(waIntent, "Facebook no se encuentra instalado."));
}catch(Exception e){
Toast.makeText(act, "Facebook no se encuentra instalado.", Toast.LENGTH_LONG).show();
}
}
#Override
protected void onResume() {
super.onResume();
uiHelper.onResume();
AppEventsLogger.activateApp(this);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
outState.putString(PENDING_ACTION_BUNDLE_KEY, pendingAction.name());
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data, dialogCallback);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
AppEventsLogger.deactivateApp(mActivity);
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (pendingAction != PendingAction.NONE &&
(exception instanceof FacebookOperationCanceledException ||
exception instanceof FacebookAuthorizationException)) {
new AlertDialog.Builder(FacebookShare.this)
.setTitle(R.string.cancelled)
.setMessage(R.string.permission_not_granted)
.setPositiveButton(R.string.ok, null)
.show();
pendingAction = PendingAction.NONE;
} else if (state == SessionState.OPENED_TOKEN_UPDATED) {
handlePendingAction();
}
}
#SuppressWarnings("incomplete-switch")
private void handlePendingAction() {
PendingAction previouslyPendingAction = pendingAction;
pendingAction = PendingAction.NONE;
if(Session.getActiveSession() != null){
switch (previouslyPendingAction) {
case POST_PHOTO:
postPhoto();
break;
case POST_STATUS_UPDATE:
postStatusUpdate();
break;
}
}else{
Session.openActiveSession(mActivity, true, new Session.StatusCallback() {
#SuppressWarnings("deprecation")
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser mUser, Response response) {
if (user != null) {
FacebookShare.this.user = mUser;
}
}
});
}
}
});
}
}
private interface GraphObjectWithId extends GraphObject {
String getId();
}
private void showPublishResult(String message, GraphObject result, FacebookRequestError error) {
String title = null;
String alertMessage = null;
if (error == null) {
title = getString(R.string.success);
String id = result.cast(GraphObjectWithId.class).getId();
alertMessage = getString(R.string.successfully_posted_post, message, id);
} else {
title = getString(R.string.error);
alertMessage = error.getErrorMessage();
}
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(alertMessage)
.setPositiveButton(R.string.ok, null)
.show();
}
public void onClickPostStatusUpdate() {
performPublish(PendingAction.POST_STATUS_UPDATE, canPresentShareDialog);
}
public void onClickPostPhoto() {
performPublish(PendingAction.POST_PHOTO, canPresentShareDialogWithPhotos);
}
private FacebookDialog.PhotoShareDialogBuilder createShareDialogBuilderForPhoto(Bitmap... photos) {
return new FacebookDialog.PhotoShareDialogBuilder(mActivity)
.addPhotos(Arrays.asList(photos));
}
private void postPhoto() {
AsyncTaskGR.runParallelAsyncTask(new AsyncTask<Object, Bitmap, Bitmap>(){
#Override
protected Bitmap doInBackground(Object... params) {
Bitmap image = getBitmapFromURL(mUrlImg);
return image;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (canPresentShareDialogWithPhotos) {
FacebookDialog shareDialog = createShareDialogBuilderForPhoto(result).build();
uiHelper.trackPendingDialogCall(shareDialog.present());
} else if (hasPublishPermission()) {
Request request = Request.newUploadPhotoRequest(Session.getActiveSession(), result, new Request.Callback() {
#Override
public void onCompleted(Response response) {
showPublishResult(getString(R.string.photo_post), response.getGraphObject(), response.getError());
}
});
request.executeAsync();
} else {
pendingAction = PendingAction.POST_PHOTO;
}
}
});
}
private FacebookDialog.ShareDialogBuilder createShareDialogBuilderForLink() {
return new FacebookDialog.ShareDialogBuilder(mActivity)
.setName(mTitle)
.setDescription(mDescription)
.setLink(mUrlShare);
}
private void postStatusUpdate() {
if (canPresentShareDialog) {
FacebookDialog shareDialog = createShareDialogBuilderForLink().build();
uiHelper.trackPendingDialogCall(shareDialog.present());
} else if (user != null && hasPublishPermission()) {
final String message = getString(R.string.status_update, user.getFirstName(), (new Date().toString()));
Request request = Request.newStatusUpdateRequest(Session.getActiveSession(), message, place, tags, new Request.Callback() {
#Override
public void onCompleted(Response response) {
showPublishResult(message, response.getGraphObject(), response.getError());
}
});
request.executeAsync();
} else {
pendingAction = PendingAction.POST_STATUS_UPDATE;
}
}
private boolean hasPublishPermission() {
Session session = Session.getActiveSession();
return session != null && session.getPermissions().contains("publish_actions");
}
private void performPublish(PendingAction action, boolean allowNoSession) {
Session session = Session.getActiveSession();
if (session != null) {
pendingAction = action;
if (hasPublishPermission()) {
handlePendingAction();
return;
} else if (session.isOpened()) {
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(mActivity, PERMISSION));
return;
}
}
if (allowNoSession) {
pendingAction = action;
handlePendingAction();
}
}
private static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
Log.e(TAG, "getBitmapFromURL(): " + e.getMessage());
return null;
}
}
}
and this is the way i call it...
public static void send(FragmentActivity act, String applicationId, String title, String description, String urlShare, String urlImg) {
if(Utilities.isPackageInstalled(FacebookShare.PACKAGE, act)){
if(Util.isOnline(act)){
FacebookShare fb = new FacebookShare(act, applicationId, title, description, urlShare, urlImg);
if(Utilities.isNullorEmpty(urlImg)){
fb.onClickPostStatusUpdate();
}else{
fb.onClickPostPhoto();
}
}
}else{
FacebookShare.showDialog(act);
}
}
This works using my account but if i use another dont let me post, and y try to set the permission "publish_actions" in mi profile in webpage but dont let me... ps: fill in all the fields that required
Any Suggestion? ... Thanks !
The logcat dont show anything error...