Working with Sinch Instant Messaging System

Joh*_*ohn 2 java android android-layout android-activity sinch

I am using Sinch and Parse for my instant messaging system integrated in our application, and I have two concerns.

1) For some reason, I am receiving the following error when the messaging activity is displayed: The message client did not start". Furthermore, the message does not seem to go through in Sinch and not reflected visually in the application.

Below is the activity code (when the user clicks on the "quick chat" button, it takes them to the messaging activity page.

Below is the activity code for the messaging activity

public class MessagingActivity extends Activity implements ServiceConnection, MessageClientListener {

    private String recipientId;
    private Button sendButton;
    private EditText messageBodyField;
    private String messageBody;
    private MessageService.MessageServiceInterface messageService;
    private MessageAdapter messageAdapter;
    private ListView messagesList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.messaging);

        doBind();


        messagesList = (ListView) findViewById(R.id.listMessages);
        messageAdapter = new MessageAdapter(this);
        messagesList.setAdapter(messageAdapter);

        Intent intent = getIntent();
        recipientId = intent.getStringExtra("Name");

        messageBodyField = (EditText) findViewById(R.id.messageBodyField);
        sendButton = (Button) findViewById(R.id.sendButton);

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendMessage();
            }
        });
    }

    private void sendMessage() {
        messageBodyField = (EditText) findViewById(R.id.messageBodyField);
        messageBody = messageBodyField.getText().toString();
        if (messageBody.isEmpty()) {
            Toast.makeText(this, "Please enter a message", Toast.LENGTH_LONG).show();
            return;
        }

        //Here is where you will actually send the message throught Sinch
        messageService.sendMessage(recipientId, messageBody);
        messageBodyField.setText("");
    }

    private void doBind() {
        Intent serviceIntent = new Intent(this, MessageService.class);
        bindService(serviceIntent, this, BIND_AUTO_CREATE);
    }

    @Override
    public void onDestroy() {
        unbindService(this);
        super.onDestroy();
    }

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        //Define the messaging service and add a listener
        messageService = (MessageService.MessageServiceInterface) iBinder;
        messageService.addMessageClientListener(this);
        if (!messageService.isSinchClientStarted()) {
            Toast.makeText(this, "The message client did not start."
                ,Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        messageService = null;
    }

    @Override
    public void onMessageDelivered(MessageClient client, MessageDeliveryInfo deliveryInfo) {
        //Intentionally  left blank
    }

    @Override
    public void onMessageFailed(MessageClient client, Message message,
                                MessageFailureInfo failureInfo) {
        //Notify the user if message fails to send
        Toast.makeText(this, "Message failed to send.", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onIncomingMessage(MessageClient client, Message message) {
        messageAdapter.addMessage(message, MessageAdapter.DIRECTION_INCOMING);
    }

    @Override
    public void onMessageSent(MessageClient client, Message message, String recipientId) {
        messageAdapter.addMessage(message, MessageAdapter.DIRECTION_OUTGOING);
    }

    @Override
    public void onShouldSendPushData(MessageClient client, Message message, List<PushPair> pushPairs) {
        //Intentionally left blank
    }
}
Run Code Online (Sandbox Code Playgroud)

I have verified that the APP_KEY, the APP_SECRET and ENVIRONMENT matches what was recorded on Sinch. I have tried this both on the emulator, and on a physical device.

Thanks in advance

Code service

 public class MessageService extends Service implements SinchClientListener {

        private static final String APP_KEY = "XXXXX";
        private static final String APP_SECRET = "YYYYY";
        private static final String ENVIRONMENT = "sandbox.sinch.com";
        private final MessageServiceInterface serviceInterface = new MessageServiceInterface();
        private SinchClient sinchClient = null;
        private MessageClient messageClient = null;
        private String currentUserId;

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {

            currentUserId = ParseUser.getCurrentUser().getObjectId().toString();

            if (currentUserId != null && !isSinchClientStarted()) {
                startSinchClient(currentUserId);
            }

            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 void onClientFailed(SinchClient client, SinchError error) {
            sinchClient = null;
        }

        @Override
        public void onClientStarted(SinchClient client) {
            client.startListeningOnActiveConnection();
            messageClient = client.getMessageClient();
        }

        @Override
        public void onClientStopped(SinchClient client) {
            sinchClient = null;
        }

        public void stop() {
            if (isSinchClientStarted()) {
                sinchClient.stop();
                sinchClient.removeSinchClientListener(this);
            }
            sinchClient = null;
        }

        @Override
        public IBinder onBind(Intent intent) {
            return serviceInterface;
        }

        @Override
        public void onLogMessage(int level, String area, String message) {
            //Intentionally left blank
        }

        @Override
        public void onRegistrationCredentialsRequired(SinchClient client, ClientRegistration clientRegistration) {
            //Intentionally left blank
        }

        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);
            }
        }

        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();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

2)限制:我想设置一个限制,在一个特定的一方之间只有25条消息可用.

在此先感谢,如果您需要任何澄清,请告诉我.

更新3 当用户点击此按钮时,他将根据以下条件与他匹配的人一起接收MessagingActivity

 final Button ibutton = (Button) this.findViewById(R.id.btnQuickChat);
        idrinks.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            openConversation();
        }

        private void openConversation() {
            // TODO Auto-generated method stub
              ParseQuery<ParseUser> query = ParseUser.getQuery();
                query.whereNotEqualTo("objectId", ParseUser.getCurrentUser()
                        .getObjectId());

                query.setLimit(1);

                query.findInBackground(new FindCallback<ParseUser>() {
                    public void done(List<ParseUser> user, ParseException e) {
                          if (e == null) {
                               Intent intent = new Intent(getApplicationContext(), MessagingActivity.class);
                               intent.putExtra("RECIPIENT_ID", user.get(0).getObjectId());
                               startActivity(intent);
                           } else {
                               Toast.makeText(getApplicationContext(),
                                   "Error finding that user",
                                       Toast.LENGTH_SHORT).show();
                           }
                       }
                    });
                }
    });
Run Code Online (Sandbox Code Playgroud)

MessagingActivity(与教程中提供的几乎相同):

public class MessagingActivity extends Activity {

    private String recipientId;
    private EditText messageBodyField;
    private String messageBody;
    private MessageService.MessageServiceInterface messageService;
    private MessageAdapter messageAdapter;
    private ListView messagesList;
    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.messaging);

        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.listMessages);
        messageAdapter = new MessageAdapter(this);
        messagesList.setAdapter(messageAdapter);
        populateMessageHistory();

        messageBodyField = (EditText) findViewById(R.id.messageBodyField);

        findViewById(R.id.sendButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendMessage();
            }
        });
    }

    //get previous messages from parse & display
    private void populateMessageHistory() {
        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, com.parse.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)) {
                            messageAdapter.addMessage(message, MessageAdapter.DIRECTION_OUTGOING);
                        } else {
                            messageAdapter.addMessage(message, MessageAdapter.DIRECTION_INCOMING);
                        }
                    }
                }
            }
        });
    }

    private void sendMessage() {
        messageBody = messageBodyField.getText().toString();
        if (messageBody.isEmpty()) {
            Toast.makeText(this, "Please enter a message", Toast.LENGTH_LONG).show();
            return;
        }

        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;
            messageService.addMessageClientListener(messageClientListener);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            messageService = null;
        }
    }

    private class MyMessageClientListener implements MessageClientListener {
        @Override
        public void onMessageFailed(MessageClient client, Message message,
                                    MessageFailureInfo failureInfo) {
            Toast.makeText(MessagingActivity.this, "Message failed to send.", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onIncomingMessage(MessageClient client, Message message) {
            if (message.getSenderId().equals(recipientId)) {
                WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());
                messageAdapter.addMessage(writableMessage, MessageAdapter.DIRECTION_INCOMING);
            }
        }

        @Override
        public void onMessageSent(MessageClient client, Message message, String recipientId) {

            final WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());

            //only add message to parse database if it doesn't already exist there
            ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseMessage");
            query.whereEqualTo("sinchId", message.getMessageId());
            query.findInBackground(new FindCallback<ParseObject>() {
                @Override
                public void done(List<ParseObject> messageList, com.parse.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", writableMessage.getMessageId());
                            parseMessage.saveInBackground();

                            messageAdapter.addMessage(writableMessage, MessageAdapter.DIRECTION_OUTGOING);
                        }
                    }
                }
            });
        }

        @Override
        public void onMessageDelivered(MessageClient client, MessageDeliveryInfo deliveryInfo) {}

        @Override
        public void onShouldSendPushData(MessageClient client, Message message, List<PushPair> pushPairs) {}
    }
}
Run Code Online (Sandbox Code Playgroud)

MessageService活动

public class MessageService extends Service implements SinchClientListener {

    private static final String APP_KEY = "61b1bfc0-b82a-44f5-ab68-dedca69ead8c";
    private static final String APP_SECRET = "jrFrLr8Adkm0Na4nLdASDw==";
    private static final String ENVIRONMENT = "sandbox.sinch.com";
    private final MessageServiceInterface serviceInterface = new MessageServiceInterface();
    private SinchClient sinchClient = null;
    private MessageClient messageClient = null;
    private String currentUserId;
    private LocalBroadcastManager broadcaster;

    private Intent broadcastIntent = new Intent("com.dooba.beta.matchOptionActivity");

    @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 void onClientFailed(SinchClient client, SinchError error) {
        broadcastIntent.putExtra("success", false);
        broadcaster.sendBroadcast(broadcastIntent);

        sinchClient = 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) {
        sinchClient = null;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return serviceInterface;
    }

    @Override
    public void onLogMessage(int level, String area, String message) {
    }

    @Override
    public void onRegistrationCredentialsRequired(SinchClient client, ClientRegistration clientRegistration) {
    }

    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);
        }
    }

    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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

消息适配器活动:

public class MessageAdapter extends BaseAdapter {

    public static final int DIRECTION_INCOMING = 0;
    public static final int DIRECTION_OUTGOING = 1;

    private List<Pair<WritableMessage, Integer>> messages;
    private LayoutInflater layoutInflater;

    public MessageAdapter(Activity activity) {
        layoutInflater = activity.getLayoutInflater();
        messages = new ArrayList<Pair<WritableMessage, Integer>>();
    }

    public void addMessage(WritableMessage message, int direction) {
        messages.add(new Pair(message, direction));
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return messages.size();
    }

    @Override
    public Object getItem(int i) {
        return messages.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int i) {
        return messages.get(i).second;
    }

    @Override
    public View getView(int i, View convertView, ViewGroup viewGroup) {
        int direction = getItemViewType(i);

        //show message on left or right, depending on if
        //it's incoming or outgoing
        if (convertView == null) {
            int res = 0;
            if (direction == DIRECTION_INCOMING) {
                res = R.layout.message_right;
            } else if (direction == DIRECTION_OUTGOING) {
                res = R.layout.message_left;
            }
            convertView = layoutInflater.inflate(res, viewGroup, false);
        }

        WritableMessage message = messages.get(i).first;

        TextView txtMessage = (TextView) convertView.findViewById(R.id.txtMessage);
        txtMessage.setText(message.getTextBody());

        return convertView;
    }
}
Run Code Online (Sandbox Code Playgroud)

mra*_*vca 5

我写了你正在关注的教程,实际上昨天刚刚更新它以解决你的第一个问题.查看http://tutorial.sinch.com/android-messaging-tutorial/#show-spinner以查看更新.当服务未启动时,新版本将显示进度对话框(加载微调器),直到服务启动或无法启动,而不是显示Toast消息.

你能澄清你的第二个问题吗?