2014-09-19 139 views
2

我在我的應用程序中集成了我的即時消息系統,並使用Sinch和Parse,我有兩個問題。使用Sinch即時消息系統

1)出於某種原因,當顯示消息傳遞活動時,我收到以下錯誤:消息客戶端沒有啓動。「此外,該消息似乎沒有經過Sinch,並且在應用程序中沒有反映出來。

下面是活動代碼(當用戶點擊「快速聊天」按鈕,就帶他們去消息活動頁面。

以下是消息活動

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 
    } 
} 
活動代碼

我已經驗證APP_KEY,APP_SECRET和ENVIRONMENT匹配Sinch上記錄的內容。 我已經在模擬器上和物理設備上嘗試了這一點。

在此先感謝

代碼服務

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

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

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

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

消息適配器活動:

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

回答

5

我寫您關注的教程,實際上剛剛更新昨天解決您的第一個問題。查看http://tutorial.sinch.com/android-messaging-tutorial/#show-spinner查看更新。當服務未啓動時,不會顯示吐司消息,新版本將顯示進度對話框(加載微調器),直到服務啓動或啓動失敗。

你能澄清你的第二個問題嗎?

+0

感謝您的及時響應和更新。然而,在我的應用程序中,我沒有一個ListUsersActivity,其中有一個用戶列表,用戶可以選擇與之聊天。相反,用戶會根據各種標準直接與他所匹配的人聊天。爲了您的禮貌,我已將前一個活動(用戶輸入MessagingActivity之前的活動)包括在我的初始文章的更新部分下。至於第二個問題,它在每個對話之間設置了25條消息的限制。提前致謝。 – John 2014-09-19 16:49:02

+0

我遵循了你的建議,並在我的mattchOptionActivity中添加了一個進度對話框(加載微調器),並更新了我最初發布的更新2部分中的代碼。我現在的問題是它無限期地加載,似乎沒有連接到客戶端。 – John 2014-09-19 17:35:40

+1

好抓!我意識到進程對話框只會在重新安裝應用程序時消失,因爲服務會在後臺持續運行,並且每次打開應用程序時都不會調用onClientStarted。我會盡快推出教程的更新。 – mravca 2014-09-19 20:28:18

0

只需在清單中聲明您的服務。我有同樣的問題,它解決了它。