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

本文档描述了在ejabberd服务器上遇到的用户注册问题,以及如何尝试通过修改访问规则和使用Github存储库中的LetsChat应用来解决。同时,详细展示了SmackHelper类的实现,该类用于XMPP连接、注册和登录操作,包括错误处理和网络状态监听。

我遇到了在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 {

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 {

private String user;

private String name;

private String password;

private byte[] avatar;

private ProgressDialog dialog;

public SignupTask(Listener 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 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 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 attributes = new HashMap();

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 getRosterEntries() {

List result = new ArrayList();

Roster roster = con.getRoster();

Collection 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 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 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 =用户名+" @" + con.getServiceName();

} else {

jid = StringUtils.parseBareAddress(username);

}

{

stats: {

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

tuesday:{goals:10,tackles:20}

}

}

}

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值