I just saw a Protocol Exception suddenly in a working app. Starting today all the network calls are failing and getting empty in our application, but the API is working with web browsers.
I updated okHttp & Gson dependencies in my application Gradle but still get the same error. My Server name is nginx .
I also checked same URL in volley and successfully got a response from the server, but I used the same URL and wrote code in Retrofit and it is not working there (no response from server)
Is this related to an android okHttp problem or is it a server-related problem?
MainActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerview = (RecyclerView) findViewById(R.id.recyclerview);
recyclerview.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerview.setLayoutManager(layoutManager);
tabs_adapter = new Tabs_Adapter(MainActivity.this, topTabList);
recyclerview.setAdapter(tabs_adapter);
new AsyncTask<JSONObject, Object, Tabs_Response>() {
#Override
protected Tabs_Response doInBackground(JSONObject... jsonObjects) {
try {
String url = "https://api.bargaincry.com/apurl/deal/get_ApiCategory/41187";
Request request = new Request.Builder().url(url).build();
Response response = new OkHttpClient().newCall(request).execute();
strResponse = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
Tabs_Response tabs_response = new Gson().fromJson(strResponse,Tabs_Response.class);
return tabs_response;
}
#Override
protected void onPostExecute(Tabs_Response tabs_response) {
if (tabs_response != null && tabs_response.getTopTabs() != null && tabs_response.getTopTabs().size() > 0) {
topTabList = tabs_response.getTopTabs();
tabs_adapter = new Tabs_Adapter(MainActivity.this, topTabList);
recyclerview.setAdapter(tabs_adapter);
}
}
}.execute();
}
Tap_Response.java:
public class Tabs_Response {
#SerializedName("status")
#Expose
private String status;
#SerializedName("top_tabs")
#Expose
private List<TopTab> topTabs = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<TopTab> getTopTabs() {
return topTabs;
}
public void setTopTabs(List<TopTab> topTabs) {
this.topTabs = topTabs;
}
}
TopTab.java:
public class TopTab {
#SerializedName("category_id")
#Expose
private String categoryId;
#SerializedName("category_name")
#Expose
private String categoryName;
public String getCategoryId() {
return categoryId;
}
public void setCategoryId(String categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
Tabs_Adapter.java:
public class Tabs_Adapter extends RecyclerView.Adapter {
private Context context;
private List<TopTab> tabList;
private TopTab topTab;
public Tabs_Adapter(Context context, List<TopTab> tabList){
this.context = context;
this.tabList = tabList;
}
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView textView;
public TopTab topTab;
public MyViewHolder(View itemView) {
super(itemView);
textView = (TextView)itemView.findViewById(R.id.tabtext_data);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.list_items,parent,false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
topTab = tabList.get(position);
((MyViewHolder)holder).textView.setText(topTab.getCategoryName());
((MyViewHolder)holder).topTab =topTab;
}
#Override
public int getItemCount() {
if (tabList != null){
return tabList.size();
}else {
return 0;
}
}
LogCat:
java.net.ProtocolException: Expected ':status' header not present
02-14 11:38:52.468 12631-19978/com.example.srikanth.toptabs_activity
W/System.err: at
com.squareup.okhttp.internal.http.FramedTransport.readNameValueBlock(FramedTransport.java:197)
02-14 11:38:52.468 12631-19978/com.example.srikanth.toptabs_activity
W/System.err: at
com.squareup.okhttp.internal.http.FramedTransport.readResponseHeaders(FramedTransport.java:104)
02-14 11:38:52.468 12631-19978/com.example.srikanth.toptabs_activity
W/System.err: at
com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:906)
02-14 11:38:52.468 12631-19978/com.example.srikanth.toptabs_activity
W/System.err: at
com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:92)
02-14 11:38:52.468 12631-19978/com.example.srikanth.toptabs_activity
W/System.err: at
com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:891)
Update Retrofit and Okhttp3 libraries to this version.
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
Fixed in current versions of OkHttp. Please upgrade.
Related
I am using sinch Video calling API for my android application. But when the app is in the background, whenever the user is offline i.e user cleared app from the recent tab, he was unable to get the call. I used Firebase for pushing notification whenever the user is offline, but it is not getting triggered all the time, it is getting triggered sometimes only. can anyone suggest me how to push notification of incoming call when the user cleared the app from recent and will sinch actually run in the background?
public class SinchService extends Service {
private static final String APP_KEY = "key";
private static final String APP_SECRET = "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;
static Context context;
private StartFailedListener mListener;
#Override
public void onCreate() {
super.onCreate();
}
/* #Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminate();
}
super.onDestroy();
}*/
private void start(String userName,String fcm_token) {
if (mSinchClient == null) {
mUserId = userName;
/*LooperThread looperThread = new LooperThread();
looperThread.start();*/
/* new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
}
});*/
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(mUserId)
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT)
.build();
//Log.d("OnMsg","coming after getSinchServiceInterface()");
mSinchClient.setSupportMessaging(true);
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportManagedPush(true);
mSinchClient.setSupportPushNotifications(true);
mSinchClient.startListeningOnActiveConnection();
/* mSinchClient.startListeningOnActiveConnection();
mSinchClient.setSupportActiveConnectionInBackground(true);*/
// mSinchClient.setSupportActiveConnectionInBackground(true);
// mSinchClient.startListeningOnActiveConnection();
/* mSinchClient.setSupportManagedPush(true);
mSinchClient.setSupportPushNotifications(true);*/
// Log.d("fcm:","fcm token in bytes "+ fcm_token.getBytes());
mSinchClient.checkManifest();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.start();
// mSinchClient.registerPushNotificationData(fcm_token.getBytes());
}
}
class LooperThread extends Thread {
public Handler mHandler;
#Override
public void run() {
// Initialize the current thread as a Looper
// (this thread can have a MessageQueue now)
Looper.prepare();
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// process incoming messages here
/* mSinchClient.setSupportMessaging(true);
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportManagedPush(true);
mSinchClient.setSupportPushNotifications(true);
mSinchClient.startListeningOnActiveConnection();
*//* mSinchClient.startListeningOnActiveConnection();
mSinchClient.setSupportActiveConnectionInBackground(true);*//*
// mSinchClient.setSupportActiveConnectionInBackground(true);
// mSinchClient.startListeningOnActiveConnection();
*//* mSinchClient.setSupportManagedPush(true);
mSinchClient.setSupportPushNotifications(true);*//*
// Log.d("fcm:","fcm token in bytes "+ fcm_token.getBytes());
mSinchClient.checkManifest();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.start();*/
}
};
// Run the message queue in this thread
Looper.loop();
}
}
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().callUserVideo(userId);
}
public String getUserName() {
return mUserId;
}
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName,String token) {
start(userName,token);
}
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();
mSinchClient.startListeningOnActiveConnection();
}
}
#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) {
}
}
public class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
Log.d("OnMsg", "Incoming call");
Intent intent = new Intent(SinchService.this, IncomingCallScreenActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}
}
}
public class PlaceCallActivity extends BaseActivity implements SinchService.StartFailedListener/*,PushTokenRegistrationCallback*/{
private Button mCallButton;
private EditText mCallName;
Button stopButton;
String token;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//initializing UI elements
mCallName = findViewById(R.id.callName);
mCallButton = findViewById(R.id.callButton);
mCallButton.setEnabled(false);
mCallButton.setOnClickListener(buttonClickListener);
stopButton = findViewById(R.id.stopButton);
stopButton.setEnabled(false);
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w("test", "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
token = task.getResult().getToken();
// Log and toast
//String msg = getString(R.string.msg_token_fmt, token);
Log.d("test", token);
Toast.makeText(PlaceCallActivity.this, token, Toast.LENGTH_SHORT).show();
}
});
stopButton.setOnClickListener(buttonClickListener);
/* try {
#SuppressLint("WrongThread") String regId = FirebaseInstanceId.getInstance().getToken("Your-Sender-ID", "FCM");
} catch (IOException e) {
e.printStackTrace();
}*/
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
getSinchServiceInterface().startClient(new PreferenceUtils(PlaceCallActivity.this).getName(),token);
}
}, 4000);
}
// invoked when the connection with SinchServer is established
#Override
protected void onServiceConnected() {
TextView userName = (TextView) findViewById(R.id.loggedInName);
getSinchServiceInterface().setStartListener(this);
userName.setText(new PreferenceUtils(PlaceCallActivity.this).getName());
mCallButton.setEnabled(true);
stopButton.setEnabled(true);
}
/* #Override
public void onDestroy() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
super.onDestroy();
}*/
/*//to kill the current session of SinchService
private void stopButtonClicked() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
finish();
}*/
//to place the call to the entered name
private void callButtonClicked() {
String userName = mCallName.getText().toString();
if (userName.isEmpty()) {
Toast.makeText(this, "Please enter a user to call", Toast.LENGTH_LONG).show();
return;
}
Call call = getSinchServiceInterface().callUserVideo(userName);
String callId = call.getCallId();
Log.d("test","call id is"+callId);
Intent callScreen = new Intent(this, CallScreenActivity.class);
callScreen.putExtra(SinchService.CALL_ID, callId);
callScreen.putExtra("TOKEN", token);
startActivity(callScreen);
}
private OnClickListener buttonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.callButton:
callButtonClicked();
break;
case R.id.stopButton:
// stopButtonClicked();
break;
}
}
};
#Override
public void onStartFailed(SinchError error) {
Toast.makeText(this, error.toString(), Toast.LENGTH_LONG).show();
}
#Override
public void onStarted() {
}
}
i am using Sinch in my app for video, audio and messaging purpose. calling and messaging works fine when the app is running in foreground. when the app is closed and removed from stack, incoming messages and calls still works as i implemented push notification to look for incoming calls and messages (i checked in debug mode). My problem is that
1) when i start incoming call activity from firebaseMessaginService it does not show the caller name and picture i am sending in headers as i start it through relayRemotePushNotificationPayload(HashMap);
2) i am unable to get the message content data from incoming message and show notification accordingly.
My Code.
public class MyFirebaseMessagingService extends FirebaseMessagingService implements ServiceConnection {
Context context;
private SinchService.SinchServiceInterface mSinchServiceInterface;
HashMap dataHashMap;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
context = this;
if (SinchHelpers.isSinchPushPayload(remoteMessage.getData())) {
Map data = remoteMessage.getData();
dataHashMap = (data instanceof HashMap) ? (HashMap) data : new HashMap<>(data);
if (SinchHelpers.isSinchPushPayload(dataHashMap)) {
getApplicationContext().bindService(new Intent(getApplicationContext(), SinchService.class), this, Context.BIND_AUTO_CREATE);
}
} else {
Intent intent;
PendingIntent pendingIntent = null;
if (remoteMessage.getData().size() > 0) {
String identifier = remoteMessage.getData().get("identifier");
if (identifier.equals("0")) {
intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
} else if (identifier.equals("1")) {
intent = new Intent(this, Appointments.class);
pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
StaticInfo.saveData("HEALTH_TIP", "TIP", this);
}
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setWhen(System.currentTimeMillis());
notificationBuilder.setContentTitle(remoteMessage.getNotification().getTitle());
notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
notificationBuilder.setDefaults(Notification.DEFAULT_ALL | Notification.DEFAULT_LIGHTS | Notification.FLAG_SHOW_LIGHTS | Notification.DEFAULT_SOUND);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
public static boolean foregrounded() {
ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
ActivityManager.getMyMemoryState(appProcessInfo);
return (appProcessInfo.importance == IMPORTANCE_FOREGROUND || appProcessInfo.importance == IMPORTANCE_VISIBLE);
}
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
if (SinchService.class.getName().equals(componentName.getClassName())) {
mSinchServiceInterface = (SinchService.SinchServiceInterface) iBinder;
}
// it starts incoming call activity which does not show incoming caller name and picture
NotificationResult result = mSinchServiceInterface.relayRemotePushNotificationPayload(dataHashMap);
if (result.isValid() && result.isCall()) {
CallNotificationResult callResult = result.getCallResult();
if (callResult.isCallCanceled() || callResult.isTimedOut()) {
createNotification("Missed Call from : ", callResult.getRemoteUserId());
return;
} else {
if (callResult.isVideoOffered()) {
Intent intent = new Intent(this, IncomingVideoCall.class);
intent.putExtra(SinchService.CALL_ID, callResult.getRemoteUserId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
} else {
Intent intent = new Intent(this, IncomingAudioCall.class);
intent.putExtra(SinchService.CALL_ID, callResult.getRemoteUserId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
}
} else if (result.isValid() && result.isMessage()) {
//i want to get message content here
MessageNotificationResult notificationResult = result.getMessageResult();
createNotification("Received Message from : ", notificationResult.getSenderId());
}
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
unbindService(this);
}
private void createNotification(String contentTitle, String userId) {
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext()).setSmallIcon(R.mipmap.ic_launcher).setContentTitle(contentTitle).setContentText(userId);
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
Sinch service is
public class SinchService extends Service {
private static final String APP_KEY = "123abc";
private static final String APP_SECRET = "123abc";
private static final String ENVIRONMENT = "sandbox.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;
private PersistedSettings mSettings;
#Override
public void onCreate() {
super.onCreate();
mSettings = new PersistedSettings(getApplicationContext());
String userName = mSettings.getUsername();
if (!userName.isEmpty()) {
start(userName);
}
}
#Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminate();
}
super.onDestroy();
}
private void start(String userName) {
if (mSinchClient == null) {
mSettings.setUsername(userName);
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(userName).applicationKey(APP_KEY).applicationSecret(APP_SECRET).environmentHost(ENVIRONMENT).build();
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportMessaging(true);
mSinchClient.setSupportManagedPush(true);
mSinchClient.checkManifest();
mSinchClient.setSupportActiveConnectionInBackground(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().setRespectNativeCalls(false);
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.getVideoController().setResizeBehaviour(VideoScalingType.ASPECT_FILL);
mSinchClient.start();
}
}
private void stop() {
if (mSinchClient != null) {
mSinchClient.terminate();
mSinchClient = null;
}
mSettings.setUsername("");
}
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
#Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public NotificationResult relayRemotePushNotificationPayload(final Map payload) {
if (mSinchClient == null && !mSettings.getUsername().isEmpty()) {
start(mSettings.getUsername());
} else if (mSinchClient == null && mSettings.getUsername().isEmpty()) {
if (!StaticInfo.getSavedData("username", SinchService.this).equals("")) {
start(StaticInfo.getSavedData("username", SinchService.this));
}
return null;
}
return mSinchClient.relayRemotePushNotificationPayload(payload);
}
public void sendMessage(String recipientUserId, String Name, String textBody, String imageUrl) {
SinchService.this.sendMessage(recipientUserId, Name, textBody, imageUrl);
}
public void addMessageClientListener(MessageClientListener listener) {
SinchService.this.addMessageClientListener(listener);
}
public void removeMessageClientListener(MessageClientListener listener) {
SinchService.this.removeMessageClientListener(listener);
}
public Call callUser(String userId, HashMap<String, String> name) {
if (mSinchClient == null) {
return null;
}
return mSinchClient.getCallClient().callUser(userId, name);
}
public Call callUserVideo(String userId, HashMap<String, String> name) {
return mSinchClient.getCallClient().callUserVideo(userId, name);
}
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 void LogOut() {
if (mSinchClient != null) {
mSinchClient.stopListeningOnActiveConnection();
mSinchClient.unregisterPushNotificationData();
mSinchClient.unregisterManagedPush();
//mSinchClient.terminate();
}
}
}
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) {
if (call.getDetails().isVideoOffered()) {
Intent intent = new Intent(SinchService.this, IncomingVideoCall.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
SinchService.this.startActivity(intent);
} else {
Intent intent = new Intent(SinchService.this, IncomingAudioCall.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
SinchService.this.startActivity(intent);
}
}
}
private class PersistedSettings {
private SharedPreferences mStore;
private static final String PREF_KEY = "Sinch";
public PersistedSettings(Context context) {
mStore = context.getSharedPreferences(PREF_KEY, MODE_PRIVATE);
}
public String getUsername() {
return mStore.getString("Username", "");
}
public void setUsername(String username) {
SharedPreferences.Editor editor = mStore.edit();
editor.putString("Username", username);
editor.commit();
}
}
public void sendMessage(String recipientUserId, String name, String textBody, String imageUrl) {
if (isStarted()) {
WritableMessage message = new WritableMessage();
message.addHeader("imageUrl", imageUrl);
message.addHeader("Name", name);
message.addRecipient(recipientUserId);
message.setTextBody(textBody);
mSinchClient.getMessageClient().send(message);
}
}
public void addMessageClientListener(MessageClientListener listener) {
if (mSinchClient != null) {
mSinchClient.getMessageClient().addMessageClientListener(listener);
}
}
public void removeMessageClientListener(MessageClientListener listener) {
if (mSinchClient != null) {
mSinchClient.getMessageClient().removeMessageClientListener(listener);
}
}
}
i am sending message like this.
private void sendMessage() {
String textBody = mTxtTextBody.getText().toString();
if (textBody.isEmpty()) {
Toast.makeText(this, "No text message", Toast.LENGTH_SHORT).show();
return;
}
getSinchServiceInterface().sendMessage(receiver_username, name, textBody, picture);
mTxtTextBody.setText("");
}
and the adapter where extracting message headers is
public class MessageAdapter extends BaseAdapter {
public static final int DIRECTION_INCOMING = 0;
public static final int DIRECTION_OUTGOING = 1;
private List<Pair<Message, Integer>> mMessages;
private SimpleDateFormat mFormatter;
private LayoutInflater mInflater;
Context context; // modification here
int res = 0;
String photo_url;
public MessageAdapter(Activity activity) {
mInflater = activity.getLayoutInflater();
context = activity;
mMessages = new ArrayList<>();
mFormatter = new SimpleDateFormat("hh:mm aa");
}
public void addMessage(Message message, int direction) {
mMessages.add(new Pair(message, direction));
notifyDataSetChanged();
}
#Override
public int getCount() {
return mMessages.size();
}
#Override
public Object getItem(int i) {
return mMessages.get(i);
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int i) {
return mMessages.get(i).second;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
int direction = getItemViewType(i);
if (convertView == null) {
if (direction == DIRECTION_INCOMING) {
res = R.layout.message_right;
} else if (direction == DIRECTION_OUTGOING) {
res = R.layout.message_left;
}
convertView = mInflater.inflate(res, viewGroup, false);
}
Message message = mMessages.get(i).first;
String name = message.getHeaders().get("Name");
if (direction == DIRECTION_INCOMING) {
photo_url = message.getHeaders().get("imageUrl");
} else if (direction == DIRECTION_OUTGOING) {
photo_url = StaticInfo.getSavedData("photo", context);
}
CircleImageView photo = convertView.findViewById(R.id.pic);
Picasso.with(context).load(photo_url).into(photo);
TextView txtSender = convertView.findViewById(R.id.txtSender);
TextView txtMessage = convertView.findViewById(R.id.txtMessage);
TextView txtDate = convertView.findViewById(R.id.txtDate);
txtSender.setText(name);
txtMessage.setText(message.getTextBody());
txtDate.setText(mFormatter.format(message.getTimestamp()));
return convertView;
}
}
i have used fresco library to load images in the adapter. but the images are not set correctly as i expected. Here is my code. please help me. thanks in advance.
public class HomeListingAdapter_recyler1 extends RecyclerView.Adapter {
private Context context;
private ArrayList propertyItemList;
private ImageLoader mImageLoader;
public HomeListingAdapter_recyler1(HomeListingActivity_recycler propertyViews, ArrayList propertyItemList) {
Fresco.initialize(propertyViews);
this.propertyItemList = propertyItemList;
this.context = propertyViews;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.property_item_layout,parent,false);
CustomViewHolder viewHolder = new CustomViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(final CustomViewHolder holder, final int position) {
mImageLoader = VolleySingletonPattern.getInstance(context).getImageLoader();
holder.txtPropertyName.setText(propertyItemList.get(position).ville);
holder.txtPropertyType.setText(propertyItemList.get(position).bienName);
if(propertyItemList.get(position).pieces.equalsIgnoreCase("0")){
holder.txtPropertySurfaceArea.setText(propertyItemList.get(position).surface+" "+context.getString(R.string.meter_square));
}else{ holder.txtPropertySurfaceArea.setText(propertyItemList.get(position).surface+" "+context.getString(R.string.meter_square)+" - "+ propertyItemList.get(position).pieces+" "+context.getResources().getString(R.string.pieces));
}
holder.txtPropertyPrice.setText(propertyItemList.get(position).montantLoyer);
Uri imageUri;
try {
if(!TextUtils.isNullOrEmpty(propertyItemList.get(position).photo)) {
imageUri = Uri.parse(propertyItemList.get(position).photo);
holder.imgPropertyImage.setVisibility(View.VISIBLE);
holder.imgPropertyImage.setImageURI(imageUri);
}
} catch (Exception e) {
}
}
#Override
public int getItemCount() {
return propertyItemList.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
SimpleDraweeView imgPropertyImage;
public TextView txtPropertyName , txtPropertyType , txtPropertySurfaceArea ,txtPropertyPrice;
public CustomViewHolder(View itemView) {
super(itemView);
imgPropertyImage = (SimpleDraweeView) itemView.findViewById(R.id.image_property);
txtPropertyName = (TextView) itemView.findViewById(R.id.txt_property_name);
txtPropertyType = (TextView) itemView.findViewById(R.id.txt_property_type);
txtPropertySurfaceArea = (TextView) itemView.findViewById(R.id.txt_property_surface_piece);
txtPropertyPrice = (TextView) itemView.findViewById(R.id.txt_property_price);
}
}
}
Your imgPropertyImage should be a SimpleDraweeView, not an ImageView.
How can I add terminate button to eclipse console toolbar? I create console in this way:
IOConsole console = new IOConsole( name, null, null, true );
ConsolePlugin.getDefault().getConsoleManager().addConsoles( new IConsole[]{console} );
I found solution. Here is the code:
<extension
point="org.eclipse.ui.console.consolePageParticipants">
<consolePageParticipant
class="com.plugin.console.ConsoleActions"
id="com.plugin.console.PageParticipant">
<enablement>
<instanceof value="com.plugin.console.Console"/>
</enablement>
</consolePageParticipant>
</extension>
Console class:
public class Console extends IOConsole {
public Console(String name, ImageDescriptor imageDescriptor) {
super(name, imageDescriptor);
}
public Console(String name, String consoleType, ImageDescriptor imageDescriptor, boolean autoLifeCycle) {
super(name, consoleType, imageDescriptor, autoLifeCycle);
}
}
Console Participant class:
public class ConsoleActions implements IConsolePageParticipant {
private IPageBookViewPage page;
private Action remove, stop;
private IActionBars bars;
private IConsole console;
#Override
public void init(final IPageBookViewPage page, final IConsole console) {
this.console = console;
this.page = page;
IPageSite site = page.getSite();
this.bars = site.getActionBars();
createTerminateAllButton();
createRemoveButton();
bars.getMenuManager().add(new Separator());
bars.getMenuManager().add(remove);
IToolBarManager toolbarManager = bars.getToolBarManager();
toolbarManager.appendToGroup(IConsoleConstants.LAUNCH_GROUP, stop);
toolbarManager.appendToGroup(IConsoleConstants.LAUNCH_GROUP,remove);
bars.updateActionBars();
}
private void createTerminateAllButton() {
ImageDescriptor imageDescriptor = ImageDescriptor.createFromFile(getClass(), "/icons/stop_all_active.gif");
this.stop = new Action("Terminate all", imageDescriptor) {
public void run() {
//code to execute when button is pressed
}
};
}
private void createRemoveButton() {
ImageDescriptor imageDescriptor = ImageDescriptor.createFromFile(getClass(), "/icons/remove_active.gif");
this.remove= new Action("Remove console", imageDescriptor) {
public void run() {
//code to execute when button is pressed
}
};
}
#Override
public void dispose() {
remove= null;
stop = null;
bars = null;
page = null;
}
#Override
public Object getAdapter(Class adapter) {
return null;
}
#Override
public void activated() {
updateVis();
}
#Override
public void deactivated() {
updateVis();
}
private void updateVis() {
if (page == null)
return;
boolean isEnabled = true;
stop.setEnabled(isEnabled);
remove.setEnabled(isEnabled);
bars.updateActionBars();
}
}
For a project,i want to switch the project from simple broker to full-feature broker(like rabiitmq, apollo).
the exception stack:
Caused by: org.springframework.messaging.MessageDeliveryException: Message broker is not active.
at org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler.handleMessageInternal(StompBrokerRelayMessageHandler.java:392)
at org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler.handleMessage(AbstractBrokerMessageHandler.java:177)
at org.springframework.messaging.support.ExecutorSubscribableChannel.sendInternal(ExecutorSubscribableChannel.java:64)
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:116)
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:98)
at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:125)
at org.springframework.messaging.simp.SimpMessagingTemplate.doSend(SimpMessagingTemplate.java:48)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:94)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:144)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:112)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:107)
at cn.clickmed.cmcp.websocket.plain.util.WebSocketUtil.sendMessage(WebSocketUtil.java:61)
at cn.clickmed.cmcp.websocket.plain.util.WebSocketUtil.sendMessage(WebSocketUtil.java:65)
at cn.clickmed.cmcp.websocket.plain.entity.WebSocketEntity.postPersist(WebSocketEntity.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
here is the config code:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
for(String mapping : WebSocketConstant.WEBSOCKETTYPE.keySet()) {
registry.addEndpoint(mapping).withSockJS();
}
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/websocket");
// registry.enableSimpleBroker("/topic");
registry.enableStompBrokerRelay("/topic","/queue").setRelayHost("localhost").setRelayPort(61613).setSystemHeartbeatReceiveInterval(2000).setSystemHeartbeatSendInterval(2000);
// registry.setUserDestinationPrefix("/topic/");
}
#Bean
public Broker broker() throws Exception {
final Broker broker = new Broker();
// Configure STOMP over WebSockects connector
final AcceptingConnectorDTO ws = new AcceptingConnectorDTO();
ws.id = "ws";
ws.bind = "ws://localhost:61613";
ws.protocols.add( new StompDTO() );
// Create a topic with name 'test'
final TopicDTO topic = new TopicDTO();
topic.id = "todoListener";
// Create virtual host (based on localhost)
final VirtualHostDTO host = new VirtualHostDTO();
host.id = "localhost";
host.topics.add( topic );
host.host_names.add( "localhost" );
host.host_names.add( "127.0.0.1" );
host.auto_create_destinations = false;
// Create a web admin UI (REST) accessible at: http://localhost:61680/api/index.html#!/
final WebAdminDTO webadmin = new WebAdminDTO();
webadmin.bind = "http://localhost:61680";
// Create JMX instrumentation
final JmxDTO jmxService = new JmxDTO();
jmxService.enabled = true;
// Finally, glue all together inside broker configuration
final BrokerDTO config = new BrokerDTO();
config.connectors.add( ws );
config.virtual_hosts.add( host );
config.web_admins.add( webadmin );
config.services.add( jmxService );
broker.setConfig( config );
broker.setTmp( new File( System.getProperty( "java.io.tmpdir" ) ) );
broker.start( new Runnable() {
#Override
public void run() {
System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:启动了");
}
} );
return broker;
}
}
send message code:
public class WebSocketUtil implements ILog{
public static Map<String, List<WebSocketSession>> webSocketSessionMap = new HashMap<String, List<WebSocketSession>>();
public static SimpMessagingTemplate simpMessagingTemplate = null;
public static void doSendMessage(String webSocketType) throws IOException {
if(WebSocketUtil.webSocketSessionMap.get(webSocketType) != null) {
String msg = "";
if(WebSocketConstant.WEBSOCKETTYPE_TODOLIST.equals(webSocketType)) {
msg = "change";
}
for(WebSocketSession webSocketSession :WebSocketUtil.webSocketSessionMap.get(webSocketType)) {
webSocketSession.sendMessage(new TextMessage(msg));
}
}
}
public static String getWebSocketType(String url) {
int length = url.indexOf("/cmcp/");
String theUrl = url.substring(length+5);
if(theUrl.startsWith(WebSocketConstant.COMPATIBLEMAPPING)) {
String [] arr = theUrl.split("/");
theUrl = "/"+arr[2];
}
if(!WebSocketConstant.WEBSOCKETTYPE.containsKey(theUrl)) {
logger.error("please config the websocketConstant !!!!");
throw new RuntimeException();
}
String theType = WebSocketConstant.WEBSOCKETTYPE.get(theUrl);
return theType;
}
public synchronized static void initSimpMessagingTemplate() {
if(simpMessagingTemplate == null) {
simpMessagingTemplate = SpringUtil.getBeanByName("brokerMessagingTemplate");
}
}
public static void sendMessage(String topic, String message) {
if(simpMessagingTemplate == null) {
initSimpMessagingTemplate();
}
simpMessagingTemplate.convertAndSend("/topic"+topic, message);
}
public static void sendMessage(String topic) {
sendMessage(topic,"change");
}
}
this is the trigger entity:
#MappedSuperclass
public class WebSocketEntity extends CommonEntity {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
#PostPersist
public void postPersist() throws IOException{
if(this instanceof TodoEntity) {
WebSocketUtil.sendMessage(WebSocketConstant.WEBSOCKETTYPE_TODOLIST_MAPPING);
}
}
#PostRemove
public void postRemove() throws IOException{
if(this instanceof TodoEntity) {
WebSocketUtil.sendMessage(WebSocketConstant.WEBSOCKETTYPE_TODOLIST_MAPPING);
}
}
}
please give me help! thanks!