在android中的ejabberd服务器上注册一个新用户

时间:2016-12-07 10:24:24

标签: android ejabberd ejabberd-module

我遇到了在ejabberd服务器上创建新用户的问题,但登录工作正常。我使用github存储库(https://github.com/dilicode/LetsChat)注册新用户并在两个或更多用户之间聊天。我在intenet上搜索,我找到了一些注册方法: 1.增加

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

ejabberd服务器和{mod_register, [ {access_from, register}, ... ] ... 中的访问规则中 2.还要添加

ejabberd

它在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(); } } } 服务器的访问规则中。 我的注册活动如下:

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

SignupTaskActivity如下:

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

SmackHelper课程如下:

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

最后我的清单文件     public UserProfile search(String username)抛出SmackInvocationException {         String name = StringUtils.parseName(username);         String jid = null;         if(name == null || name.trim()。length()== 0){             jid =用户名+&#34; @&#34; + con.getServiceName();         } else {             jid = StringUtils.parseBareAddress(username);         }

{
  stats: {
    monday:{goals:10,tackles:20},
    tuesday:{goals:10,tackles:20}
  }
}

}

但是我找不到任何进展。请帮助我。提前谢谢。

1 个答案:

答案 0 :(得分:1)

经过奋斗,我找到了解决这类问题的方法。我们需要进行服务器端更改,例如: 步骤1: enter image description here

步骤2: enter image description here

步骤3: enter image description here

完成所有这些步骤后,我们将能够在ejabberd服务器上注册新用户。