2016-12-07 3 views
2

ejabberdサーバーに新しいユーザーを作成する際に問題が発生していますが、ログインすると問題はありません。私はgithubリポジトリ(https://github.com/dilicode/LetsChat)を使って新しいユーザを登録し、2人以上のユーザ間でチャットを行いました。私は私がそれらを登録するためにいくつかの方法を発見し、インターネットを完備にされている検索: はejabberdサーバと 2にアクセスルールでandroidのejabberdサーバーに新しいユーザーを登録する

%% In-band registration 
{access, register, [{allow, all}]}. 

を1.addもejabberdのアクセスルールに

{mod_register, [ 
     {access_from, register}, 
     ... 
       ] ... 

にそれを追加しますサーバ。 私のサインアップの活動を次のように

public class SignupActivity extends AppCompatActivity implements OnClickListener, Listener<Boolean> { 
    private static final int REQUEST_CODE_SELECT_PICTURE = 1; 
    private static final int REQUEST_CODE_CROP_IMAGE = 2; 

    private static final String RAW_PHOTO_FILE_NAME = "camera.png"; 
    private static final String AVATAR_FILE_NAME = "avatar.png"; 

    private EditText nameText; 
    private EditText phoneNumberText; 
    private EditText passwordText; 

    private Button submitButton; 
    private ImageButton uploadAvatarButton; 

    private File rawImageFile; 
    private File avatarImageFile; 

    private SignupTask signupTask; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_signup); 

     nameText = (EditText)findViewById(R.id.et_name); 
     phoneNumberText = (EditText)findViewById(R.id.et_phone_number); 
     passwordText = (EditText)findViewById(R.id.et_password); 
     uploadAvatarButton = (ImageButton)findViewById(R.id.btn_upload_avatar); 
     submitButton = (Button)findViewById(R.id.btn_submit); 

     submitButton.setOnClickListener(this); 
     uploadAvatarButton.setOnClickListener(this); 

     File dir = FileUtils.getDiskCacheDir(this, "temp"); 
     if (!dir.exists()) { 
      dir.mkdirs(); 
     } 
     rawImageFile = new File(dir, RAW_PHOTO_FILE_NAME); 
     avatarImageFile = new File(dir, AVATAR_FILE_NAME); 

     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case android.R.id.home: 
       finish(); 
       return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onClick(View v) { 
     if (v == submitButton) { 
      String phoneNumber = phoneNumberText.getText().toString(); 
      String password = passwordText.getText().toString(); 
      String name = nameText.getText().toString(); 

      if (phoneNumber.trim().length() == 0 || password.trim().length() == 0 || 
        name.trim().length() == 0) { 
       Toast.makeText(this, R.string.incomplete_signup_info, Toast.LENGTH_SHORT).show(); 
       return; 
      } 

      signupTask = new SignupTask(this, this, phoneNumber, password, name, getAvatarBytes()); 
      signupTask.execute(); 
     } else if(v == uploadAvatarButton) { 
      chooseAction(); 
     } 
    } 

    private void chooseAction() { 
     Intent captureImageIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
     captureImageIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(rawImageFile)); 

     Intent pickIntent = new Intent(Intent.ACTION_GET_CONTENT); 
     pickIntent.setType("image/*"); 

     Intent chooserIntent = Intent.createChooser(pickIntent, getString(R.string.profile_photo)); 
     chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {captureImageIntent}); 

     startActivityForResult(chooserIntent, REQUEST_CODE_SELECT_PICTURE); 
    } 

    @Override 
    public void onResponse(Boolean result) { 
     if (result) { 
      Toast.makeText(this, R.string.login_success, Toast.LENGTH_SHORT).show(); 

      startActivity(new Intent(this, MainActivity.class)); 

      setResult(RESULT_OK); 
      finish(); 
     } 
    } 

    @Override 
    public void onErrorResponse(Exception exception) { 
     Toast.makeText(this, R.string.create_account_error, Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (resultCode == RESULT_OK) { 
      switch (requestCode) { 
       case REQUEST_CODE_SELECT_PICTURE: 
        boolean isCamera; 
        if (data == null) { 
         isCamera = true; 
        } else { 
         String action = data.getAction(); 
         if (action == null) { 
          isCamera = false; 
         } else { 
          isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
         } 
        } 

        if (isCamera) { 
         startCropImage(Uri.fromFile(rawImageFile)); 
        } else { 
         startCropImage(data == null ? null : data.getData()); 
        } 

        break; 

       case REQUEST_CODE_CROP_IMAGE: 
        Bitmap bitmap = BitmapFactory.decodeFile(avatarImageFile.getAbsolutePath()); 
        RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap); 
        drawable.setCircular(true); 
        uploadAvatarButton.setImageDrawable(drawable); 

        break; 
      } 
     } 

     super.onActivityResult(requestCode, resultCode, data); 
    } 

    private void startCropImage(Uri source) { 
     if (source != null) { 
      int size = getResources().getDimensionPixelSize(R.dimen.default_avatar_size); 
      CropImageIntentBuilder cropImage = new CropImageIntentBuilder(size, size, Uri.fromFile(avatarImageFile)); 
      cropImage.setSourceImage(source); 

      startActivityForResult(cropImage.getIntent(this), REQUEST_CODE_CROP_IMAGE); 
     } 
    } 

    private byte[] getAvatarBytes() { 
     if (!avatarImageFile.exists()) return null; 

     InputStream inputStream = null; 
     try { 
      inputStream = new FileInputStream(avatarImageFile); 
     } catch (FileNotFoundException e) { 
      AppLog.e("avatar file not found", e); 
     } 

     byte[] buffer = new byte[1024]; 
     int bytesRead; 
     ByteArrayOutputStream output = new ByteArrayOutputStream(); 
     try { 
      while ((bytesRead = inputStream.read(buffer)) != -1) { 
       output.write(buffer, 0, bytesRead); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return output.toByteArray(); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 

     if (signupTask != null) { 
      signupTask.dismissDialogAndCancel(); 
     } 
    } 
} 

SignupTaskActivityを次のように:

public class SignupTask extends BaseAsyncTask<Void, Void, Boolean> { 
    private String user; 
    private String name; 
    private String password; 
    private byte[] avatar; 

    private ProgressDialog dialog; 

    public SignupTask(Listener<Boolean> listener, Context context, String user, String password, String name, byte[] avatar) { 
     super(listener, context); 

     this.user = user; 
     this.name = name; 
     this.password = password; 
     this.avatar = avatar; 

     dialog = ProgressDialog.show(context, null, context.getResources().getString(R.string.signup)); 
    } 

    @Override 
    public Response<Boolean> doInBackground(Void... params) { 
     Context context = getContext(); 
     if (context != null) { 
      try { 
       SmackHelper.getInstance(context).signupAndLogin(user, password, name, avatar); 

       if (avatar != null) { 
        ImageCache.addAvatarToFile(context, user, BitmapFactory.decodeByteArray(avatar, 0, avatar.length)); 
       } 

       PreferenceUtils.setLoginUser(context, user, password, name); 

       return Response.success(true); 
      } catch(SmackInvocationException e) { 
       AppLog.e(String.format("sign up error %s", e.toString()), e); 

       return Response.error(e); 
      } 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Response<Boolean> response) { 
     dismissDialog(); 

     super.onPostExecute(response); 
    } 

    @Override 
    protected void onCancelled() { 
     super.onCancelled(); 

     dismissDialog(); 
    } 

    public void dismissDialog() { 
     if (dialog != null && dialog.isShowing()) { 
      dialog.dismiss(); 
     } 
    } 

    public void dismissDialogAndCancel() { 
     dismissDialog(); 
     cancel(false); 
    } 
} 

SmackHelperクラスを次のように

public class SmackHelper { 
    private static final String LOG_TAG = "SmackHelper"; 

    private static final int PORT = 5222; 

    public static final String RESOURCE_PART = "Smack"; 

    private XMPPConnection con; 

    private ConnectionListener connectionListener; 

    private Context context; 

    private State state; 

    private PacketListener messagePacketListener; 

    private PacketListener presencePacketListener; 

    private SmackAndroid smackAndroid; 

    private static SmackHelper instance; 

    private SmackContactHelper contactHelper; 

    private SmackVCardHelper vCardHelper; 

    private FileTransferManager fileTransferManager; 

    private PingManager pingManager; 

    private long lastPing = new Date().getTime(); 

    public static final String ACTION_CONNECTION_CHANGED = "com.mstr.letschat.intent.action.CONNECTION_CHANGED"; 
    public static final String EXTRA_NAME_STATE = "com.mstr.letschat.State"; 

    private SmackHelper(Context context) { 
     this.context = context; 

     smackAndroid = SmackAndroid.init(context); 

     messagePacketListener = new MessagePacketListener(context); 
     presencePacketListener = new PresencePacketListener(context); 

     SmackConfiguration.setDefaultPacketReplyTimeout(20 * 1000); 
     Roster.setDefaultSubscriptionMode(SubscriptionMode.manual); 

     ProviderManager.addExtensionProvider(UserLocation.ELEMENT_NAME, UserLocation.NAMESPACE, new LocationMessageProvider()); 
    } 

    public static synchronized SmackHelper getInstance(Context context) { 
     if (instance == null) { 
      instance = new SmackHelper(context.getApplicationContext()); 
     } 

     return instance; 
    } 

    public void setState(State state) { 
     if (this.state != state) { 
      Log.d(LOG_TAG, "enter state: " + state.name()); 

      this.state = state; 
     } 
    } 

    public void signupAndLogin(String user, String password, String nickname, byte[] avatar) throws SmackInvocationException { 
     connect(); 

     Map<String, String> attributes = new HashMap<String, String>(); 
     attributes.put("name", nickname); 
     try { 
      AccountManager.getInstance(con).createAccount(user, password, attributes); 
     } catch (Exception e) { 
      throw new SmackInvocationException(e); 
     } 

     login(user, password); 

     vCardHelper.save(nickname, avatar); 
    } 

    public void sendChatMessage(String to, String body, PacketExtension packetExtension) throws SmackInvocationException { 
     Message message = new Message(to, Message.Type.chat); 
     message.setBody(body); 
     if (packetExtension != null) { 
      message.addExtension(packetExtension); 
     } 
     try { 
      con.sendPacket(message); 
     } catch (NotConnectedException e) { 
      throw new SmackInvocationException(e); 
     } 
    } 

    public List<RosterEntry> getRosterEntries() { 
     List<RosterEntry> result = new ArrayList<RosterEntry>(); 

     Roster roster = con.getRoster(); 
     Collection<RosterGroup> groups = roster.getGroups(); 
     for (RosterGroup group : groups) { 
      result.addAll(group.getEntries()); 
     } 

     return result; 
    } 

、最終的には私のmenifestファイル 公共のUserProfileの検索(文字列のユーザー名を)スローSmackInvocationException { String name = StringUtils.parseName(username); 文字列jid = null; if(name == null || name.trim()。length()== 0){ jid = username + "@" + con.getServiceName(); } else { jid = StringUtils.parseBareAddress(username); }

if (vCardHelper == null) { 
     return null; 
    } 

    VCard vCard = vCardHelper.loadVCard(jid); 
    String nickname = vCard.getNickName(); 

    return nickname == null ? null : new UserProfile(jid, vCard); 
} 

public String getNickname(String jid) throws SmackInvocationException { 
    VCard vCard = vCardHelper.loadVCard(jid); 

    return vCard.getNickName(); 
} 

private void connect() throws SmackInvocationException { 
    if (!isConnected()) { 
     setState(State.CONNECTING); 

     if (con == null) { 
      con = createConnection(); 
     } 

     try { 
      con.connect(); 
     }catch (SmackException.NoResponseException er){ 
      Log.e(LOG_TAG,"Norespponse exception"); 
     } 
     catch(Exception e) { 
      Log.e(LOG_TAG, String.format("Unhandled exception %s", e.toString()), e); 

      startReconnectIfNecessary(); 

      throw new SmackInvocationException(e); 
     } 
    } 
} 

@SuppressLint("TrulyRandom") 
private XMPPConnection createConnection() { 
    ConnectionConfiguration config = new ConnectionConfiguration(PreferenceUtils.getServerHost(context), PORT); 

    SSLContext sc = null; 
    MemorizingTrustManager mtm = null; 
    try { 
     mtm = new MemorizingTrustManager(context); 
     sc = SSLContext.getInstance("TLS"); 
     sc.init(null, new X509TrustManager[] { mtm }, new SecureRandom()); 
    } catch (NoSuchAlgorithmException e) { 
     throw new IllegalStateException(e); 
    } catch (KeyManagementException e) { 
     throw new IllegalStateException(e); 
    } 

    config.setCustomSSLContext(sc); 
    config.setHostnameVerifier(mtm.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier())); 
    config.setSecurityMode(SecurityMode.required); 
    config.setReconnectionAllowed(false); 
    config.setSendPresence(false); 
    config.setSecurityMode(SecurityMode.disabled); 
    List<HostAddress> list = config.getHostAddresses(); 
    boolean data = config.isSendPresence(); 


    return new XMPPTCPConnection(config); 
} 

public void cleanupConnection() { 
    if (con != null) { 
     con.removePacketListener(messagePacketListener); 
     con.removePacketListener(presencePacketListener); 

     if (connectionListener != null) { 
      con.removeConnectionListener(connectionListener); 
     } 
    } 

    if (isConnected()) { 
     try { 
      con.disconnect(); 
     } catch (NotConnectedException e) {} 
    } 
} 

private void onConnectionEstablished() { 
    if (state != State.CONNECTED) { 
     //processOfflineMessages(); 

     try { 
      con.sendPacket(new Presence(Presence.Type.available)); 
     } catch (NotConnectedException e) {} 

     contactHelper = new SmackContactHelper(context, con); 
     vCardHelper = new SmackVCardHelper(context, con); 
     fileTransferManager = new FileTransferManager(con); 
     OutgoingFileTransfer.setResponseTimeout(30000); 
     addFileTransferListener(); 

     pingManager = PingManager.getInstanceFor(con); 
     pingManager.registerPingFailedListener(new PingFailedListener() { 
      @Override 
      public void pingFailed() { 
       // Note: remember that maybeStartReconnect is called from a different thread (the PingTask) here, it may causes synchronization problems 
       long now = new Date().getTime(); 
       if (now - lastPing > 30000) { 
        Log.e(LOG_TAG, "Ping failure, reconnect"); 
        startReconnectIfNecessary(); 
        lastPing = now; 
       } else { 
        Log.e(LOG_TAG, "Ping failure reported too early. Skipping this occurrence."); 
       } 
      } 
     }); 

     con.addPacketListener(messagePacketListener, new MessageTypeFilter(Message.Type.chat)); 
     con.addPacketListener(presencePacketListener, new PacketTypeFilter(Presence.class)); 
     con.addConnectionListener(createConnectionListener()); 

     setState(State.CONNECTED); 

     broadcastState(State.CONNECTED); 

     MessageService.reconnectCount = 0; 
    } 
} 

private void broadcastState(State state) { 
    Intent intent = new Intent(ACTION_CONNECTION_CHANGED); 
    intent.putExtra(EXTRA_NAME_STATE, state.toString()); 
    LocalBroadcastManager.getInstance(context).sendBroadcast(intent); 
} 

public void login(String username, String password) throws SmackInvocationException { 
    connect(); 

    try { 
     if (!con.isAuthenticated()) { 
      con.login(username, password, RESOURCE_PART); 
     } 

     onConnectionEstablished(); 
    } catch(Exception e) { 
     SmackInvocationException exception = new SmackInvocationException(e); 
     // this is caused by wrong username/password, do not reconnect 
     if (exception.isCausedBySASLError()) { 
      cleanupConnection(); 
     } else { 
      startReconnectIfNecessary(); 
     } 

     throw exception; 
    } 
} 

public String getLoginUserNickname() throws SmackInvocationException { 
    try { 
     return AccountManager.getInstance(con).getAccountAttribute("name"); 
    } catch (Exception e) { 
     throw new SmackInvocationException(e); 
    } 
} 

private void processOfflineMessages() { 
    Log.i(LOG_TAG, "Begin retrieval of offline messages from server"); 

    OfflineMessageManager offlineMessageManager = new OfflineMessageManager(con); 
    try { 
     if (!offlineMessageManager.supportsFlexibleRetrieval()) { 
      Log.d(LOG_TAG, "Offline messages not supported"); 
      return; 
     } 

     List<Message> msgs = offlineMessageManager.getMessages(); 
     for (Message msg : msgs) { 
      Intent intent = new Intent(MessageService.ACTION_MESSAGE_RECEIVED, null, context, MessageService.class); 
      intent.putExtra(MessageService.EXTRA_DATA_NAME_FROM, StringUtils.parseBareAddress(msg.getFrom())); 
      intent.putExtra(MessageService.EXTRA_DATA_NAME_MESSAGE_BODY, msg.getBody()); 

      context.startService(intent); 
     } 

     offlineMessageManager.deleteMessages(); 
    } catch (Exception e) { 
     Log.e(LOG_TAG, "handle offline messages error ", e); 
    } 

    Log.i(LOG_TAG, "End of retrieval of offline messages from server"); 
} 

private ConnectionListener createConnectionListener() { 
    connectionListener = new ConnectionListener() { 
     @Override 
     public void authenticated(XMPPConnection arg0) {} 

     @Override 
     public void connected(XMPPConnection arg0) {} 

     @Override 
     public void connectionClosed() { 
      Log.e(LOG_TAG, "connection closed"); 
     } 

     @Override 
     public void connectionClosedOnError(Exception arg0) { 
      // it may be due to network is not available or server is down, update state to WAITING_TO_CONNECT 
      // and schedule an automatic reconnect 
      Log.e(LOG_TAG, "connection closed due to error ", arg0); 

      startReconnectIfNecessary(); 
     } 

     @Override 
     public void reconnectingIn(int arg0) {} 

     @Override 
     public void reconnectionFailed(Exception arg0) {} 

     @Override 
     public void reconnectionSuccessful() {} 
    }; 

    return connectionListener; 
} 

private void startReconnectIfNecessary() { 
    cleanupConnection(); 

    setState(State.WAITING_TO_CONNECT); 

    if (NetworkUtils.isNetworkConnected(context)) { 
     context.startService(new Intent(MessageService.ACTION_RECONNECT, null, context, MessageService.class)); 
    } 
} 

private boolean isConnected() { 
    return con != null && con.isConnected(); 
} 

public void onNetworkDisconnected() { 
    setState(State.WAITING_FOR_NETWORK); 
} 

public void requestSubscription(String to, String nickname) throws SmackInvocationException { 
    contactHelper.requestSubscription(to, nickname); 
} 

public void approveSubscription(String to, String nickname, boolean shouldRequest) throws SmackInvocationException { 
    contactHelper.approveSubscription(to); 

    if (shouldRequest) { 
     requestSubscription(to, nickname); 
    } 
} 

public void delete(String jid) throws SmackInvocationException { 
    contactHelper.delete(jid); 
} 

public String loadStatus() throws SmackInvocationException { 
    if (vCardHelper == null) { 
     throw new SmackInvocationException("server not connected"); 
    } 
    return vCardHelper.loadStatus(); 
} 

public VCard loadVCard(String jid) throws SmackInvocationException { 
    if (vCardHelper == null) { 
     throw new SmackInvocationException("server not connected"); 
    } 

    return vCardHelper.loadVCard(jid); 
} 

public VCard loadVCard() throws SmackInvocationException { 
    if (vCardHelper == null) { 
     throw new SmackInvocationException("server not connected"); 
    } 

    return vCardHelper.loadVCard(); 
} 

public void saveStatus(String status) throws SmackInvocationException { 
    if (vCardHelper == null) { 
     throw new SmackInvocationException("server not connected"); 
    } 

    vCardHelper.saveStatus(status); 

    contactHelper.broadcastStatus(status); 
} 

public SubscribeInfo processSubscribe(String from) throws SmackInvocationException { 
    SubscribeInfo result = new SubscribeInfo(); 

    RosterEntry rosterEntry = contactHelper.getRosterEntry(from); 
    ItemType rosterType = rosterEntry != null ? rosterEntry.getType() : null; 

    if (rosterEntry == null || rosterType == ItemType.none) { 
     result.setType(SubscribeInfo.TYPE_WAIT_FOR_APPROVAL); 
     result.setNickname(getNickname(from)); 
    } else if (rosterType == ItemType.to) { 
     result.setType(SubscribeInfo.TYPE_APPROVED); 
     result.setNickname(rosterEntry.getName()); 

     approveSubscription(from, null, false); 
    } 

    result.setFrom(from); 
    return result; 
} 

public void sendImage(File file, String to) throws SmackInvocationException { 
    if (fileTransferManager == null || !isConnected()) { 
     throw new SmackInvocationException("server not connected"); 
    } 

    String fullJid = to + "/" + RESOURCE_PART; 
    OutgoingFileTransfer transfer = fileTransferManager.createOutgoingFileTransfer(fullJid); 
    try { 
     transfer.sendFile(file, file.getName()); 
    } catch (SmackException e) { 
     Log.e(LOG_TAG, "send file error"); 
     throw new SmackInvocationException(e); 
    } 

    while(!transfer.isDone()) { 
     if(transfer.getStatus().equals(Status.refused) || transfer.getStatus().equals(Status.error) 
       || transfer.getStatus().equals(Status.cancelled)){ 
      throw new SmackInvocationException("send file error, " + transfer.getError()); 
     } 
    } 

    Log.d(LOG_TAG, "send file status: " + transfer.getStatus()); 
    if(transfer.getStatus().equals(Status.refused) || transfer.getStatus().equals(Status.error) 
      || transfer.getStatus().equals(Status.cancelled)){ 
     throw new SmackInvocationException("send file error, " + transfer.getError()); 
    } 
} 

private void addFileTransferListener() { 
    fileTransferManager.addFileTransferListener(new FileTransferListener() { 
     public void fileTransferRequest(final FileTransferRequest request) { 
      new Thread() { 
       @Override 
       public void run() { 
        IncomingFileTransfer transfer = request.accept(); 
        String fileName = String.valueOf(System.currentTimeMillis()); 
        File file = new File(FileUtils.getReceivedImagesDir(context), fileName + FileUtils.IMAGE_EXTENSION); 
        try { 
         transfer.recieveFile(file); 
        } catch (SmackException e) { 
         Log.e(LOG_TAG, "receive file error", e); 
         return; 
        } 

        while (!transfer.isDone()) { 
         if(transfer.getStatus().equals(Status.refused) || transfer.getStatus().equals(Status.error) 
           || transfer.getStatus().equals(Status.cancelled)){ 
          Log.e(LOG_TAG, "receive file error, " + transfer.getError()); 
          return; 
         } 
        } 

        // start service to save the image to sqlite 
        if (transfer.getStatus().equals(Status.complete)) { 
         Intent intent = new Intent(MessageService.ACTION_MESSAGE_RECEIVED, null, context, MessageService.class); 
         intent.putExtra(MessageService.EXTRA_DATA_NAME_FROM, StringUtils.parseBareAddress(request.getRequestor())); 
         intent.putExtra(MessageService.EXTRA_DATA_NAME_MESSAGE_BODY, context.getString(R.string.image_message_body)); 
         intent.putExtra(MessageService.EXTRA_DATA_NAME_FILE_PATH, file.getAbsolutePath()); 
         intent.putExtra(MessageService.EXTRA_DATA_NAME_TYPE, ChatMessageTableHelper.TYPE_INCOMING_IMAGE); 

         context.startService(intent); 
        } 

       } 
      }.start(); 
     } 
    }); 
} 

public void onDestroy() { 
    cleanupConnection(); 

    smackAndroid.onDestroy(); 
} 

public static enum State { 
    CONNECTING, 

    CONNECTED, 

    DISCONNECTED, 

    // this is a state that client is trying to reconnect to server 
    WAITING_TO_CONNECT, 

    WAITING_FOR_NETWORK; 
} 

}

しかし、私はどのprogress.pleaseが私を助けていませんでした。前もって感謝します。

答えて

1

闘争の末、私はこの種の問題の解決策を見つけました。我々はejabberdサーバー上に新しいユーザーを登録することができますすべてのこれらの手順を実行した後 enter image description here

: STEP1: enter image description here

STEP2: enter image description here

STEP3我々のようなサーバー側の変更を行う必要があります。

関連する問題