com.avos.avoscloud.AVUser Maven / Gradle / Ivy
package com.avos.avoscloud;
import android.os.Parcel;
import android.text.TextUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.avos.avoscloud.utils.StringUtils;
import java.io.File;
import java.util.*;
@JSONType(ignores = {"query", "password"}, asm = false)
public class AVUser extends AVObject {
transient private static boolean enableAutomatic = false;
private String sessionToken;
transient private boolean isNew;
private String username;
transient private String password;
private String mobilePhoneNumber;
private String email;
private transient String facebookToken;
private transient String twitterToken;
private transient String sinaWeiboToken;
private transient String qqWeiboToken;
private transient boolean needTransferFromAnonymousUser;
private boolean anonymous;
public static final String LOG_TAG = AVUser.class.getSimpleName();
public static final String FOLLOWER_TAG = "follower";
public static final String FOLLOWEE_TAG = "followee";
public static final String SESSION_TOKEN_KEY = "sessionToken";
public static final String SMS_VALIDATE_TOKEN = "validate_token";
public static final String SMS_PHONE_NUMBER = "mobilePhoneNumber";
public static final String AVUSER_ENDPOINT = "users";
public static final String AVUSER_ENDPOINT_FAILON = "users?failOnNotExist=true";
public static final String SNS_TENCENT_WEIBO = "qq";
public static final String SNS_SINA_WEIBO = "weibo";
public static final String SNS_TENCENT_WEIXIN = "weixin";
private static Class extends AVUser> subClazz;
private static final String accessTokenTag = "access_token";
private static final String expiresAtTag = "expires_at";
private static final String authDataTag = "authData";
private static final String anonymousTag = "anonymous";
private static final String AUTHDATA_ATTR_UNIONID = "unionid";
private static final String AUTHDATA_ATTR_UNIONID_PLATFORM = "platform";
private static final String AUTHDATA_ATTR_MAIN_ACCOUNT = "main_account";
static private File currentUserArchivePath() {
File file = new File(AVPersistenceUtils.getPaasDocumentDir() + "/currentUser");
return file;
}
static private boolean userArchiveExist() {
return currentUserArchivePath().exists();
}
// getter/setter for fastjson
public String getFacebookToken() {
return facebookToken;
}
void setFacebookToken(String facebookToken) {
this.facebookToken = facebookToken;
}
public String getTwitterToken() {
return twitterToken;
}
void setTwitterToken(String twitterToken) {
this.twitterToken = twitterToken;
}
public String getQqWeiboToken() {
return qqWeiboToken;
}
void setQqWeiboToken(String qqWeiboToken) {
this.qqWeiboToken = qqWeiboToken;
}
String getPassword() {
return password;
}
// end of getter/setter
static void setEnableAutomatic(boolean enableAutomatic) {
AVUser.enableAutomatic = enableAutomatic;
}
void setNew(boolean isNew) {
this.isNew = isNew;
}
/**
* Constructs a new AVUser with no data in it. A AVUser constructed in this way will not have an
* objectId and will not persist to the database until AVUser.signUp() is called.
*/
public AVUser() {
super(userClassName());
}
public AVUser(Parcel in) {
super(in);
}
@Override
protected void rebuildInstanceData() {
super.rebuildInstanceData();
this.sessionToken = (String) get(SESSION_TOKEN_KEY);
this.username = (String) get("username");
this.processAuthData(null);
this.email = (String) get("email");
this.mobilePhoneNumber = (String) get("mobilePhoneNumber");
}
/**
* Enables automatic creation of anonymous users. After calling this method,
* AVUser.getCurrentUser() will always have a value. The user will only be created on the server
* once the user has been saved, or once an object with a relation to that user or an ACL that
* refers to the user has been saved. Note: saveEventually will not work if an item being saved
* has a relation to an automatic user that has never been saved.
*/
public static void enableAutomaticUser() {
enableAutomatic = true;
}
public static boolean isEnableAutomatic() {
return enableAutomatic;
}
public static void disableAutomaticUser() {
enableAutomatic = false;
}
public static synchronized void changeCurrentUser(AVUser newUser, boolean save) {
// clean password for security reason
if (newUser != null) {
newUser.password = null;
}
File currentUserArchivePath = currentUserArchivePath();
if (newUser != null && save) {
try {
// Serialize the whole user
String jsonString =
JSON.toJSONString(newUser, ObjectValueFilter.instance,
SerializerFeature.WriteClassName,
SerializerFeature.DisableCircularReferenceDetect);
if (AVOSCloud.showInternalDebugLog()) {
LogUtil.log.d(jsonString);
}
AVPersistenceUtils.saveContentToFile(jsonString, currentUserArchivePath);
} catch (Exception e) {
LogUtil.log.e(LOG_TAG, "", e);
}
} else if (save) {
AVPersistenceUtils.removeLock(currentUserArchivePath.getAbsolutePath());
currentUserArchivePath.delete();
}
PaasClient.storageInstance().setCurrentUser(newUser);
}
/**
* This retrieves the currently logged in AVUser with a valid session, either from memory or disk
* if necessary.
*
* @return The currently logged in AVUser
*/
public static AVUser getCurrentUser() {
return getCurrentUser(AVUser.class);
}
/**
* This retrieves the currently logged in AVUser with a valid session, either from memory or disk
* if necessary.
*
* @param userClass subclass.
* @return The currently logged in AVUser subclass instance.
*/
@SuppressWarnings("unchecked")
public static T getCurrentUser(Class userClass) {
T user = (T) PaasClient.storageInstance().getCurrentUser();
if (user != null) {
if (!userClass.isAssignableFrom(user.getClass())) {
user = AVUser.cast(user, userClass);
}
} else if (AVUser.userArchiveExist()) {
synchronized (AVUser.class) {
String jsonString = AVPersistenceUtils.readContentFromFile(currentUserArchivePath());
if (jsonString != null) {
if (jsonString.indexOf("@type") > 0) {
try {
// Wrap it in deserializing to avoid adding extra
// pending
// keys.
AVUser savedUser = (AVUser) JSON.parse(jsonString);
if (!userClass.isAssignableFrom(savedUser.getClass())) {
user = AVUser.cast(savedUser, userClass);
} else {
user = (T) savedUser;
}
// 这里要回写到PaasClient里面去
PaasClient.storageInstance().setCurrentUser(user);
} catch (Exception e) {
LogUtil.log.e(LOG_TAG, jsonString, e);
}
} else {
// oldest format
T userObject = newAVUser(userClass, null);
AVUtils.copyPropertiesFromJsonStringToAVObject(jsonString, userObject);
// update it to new format
changeCurrentUser(userObject, true);
user = userObject;
}
}
}
}
if (enableAutomatic && user == null) {
user = newAVUser(userClass, null);
AVUser.changeCurrentUser(user, false);;
}
return user;
}
static String userClassName() {
return AVPowerfulUtils.getAVClassName(AVUser.class.getSimpleName());
}
void setNewFlag(boolean isNew) {
this.isNew = isNew;
}
/**
* Retrieves the email address.
*/
public String getEmail() {
return this.email;
}
/**
* Constructs a query for AVUsers subclasses.
*/
public static AVQuery getUserQuery(Class clazz) {
AVQuery query = new AVQuery(userClassName(), clazz);
return query;
}
/**
* Constructs a query for AVUsers.
*/
public static AVQuery getQuery() {
return getQuery(AVUser.class);
}
public String getSessionToken() {
return sessionToken;
}
/**
* set the session token
* @param sessionToken
*/
void setSessionToken(String sessionToken) {
this.sessionToken = sessionToken;
}
/**
* Retrieves the username.
*/
public String getUsername() {
return username;
}
/**
* Whether the AVUser has been authenticated on this device. This will be true if the AVUser was
* obtained via a logIn or signUp method. Only an authenticated AVUser can be saved (with altered
* attributes) and deleted.
* @deprecated Please use {@link #isAuthenticated(AVCallback)}
*/
public boolean isAuthenticated() {
return (!AVUtils.isBlankString(sessionToken) || !AVUtils.isBlankString(sinaWeiboToken) || !AVUtils
.isBlankString(qqWeiboToken));
}
/**
* Whether the AVUser has been authenticated on this device.
* @param callback
*/
public void isAuthenticated(final AVCallback callback) {
if (null == callback) {
return;
}
if (AVUtils.isBlankContent(sessionToken)) {
callback.internalDone(false, null);
return;
}
AVRequestParams params = new AVRequestParams();
params.put("session_token", sessionToken);
PaasClient.storageInstance().getObject("users/me", params, false, null, new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
callback.internalDone(true, e);
}
@Override
public void onFailure(Throwable error, String content) {
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
});
}
public boolean isAnonymous() {
return this.anonymous;
}
protected void setAnonymous(boolean anonymous) {
this.anonymous = anonymous;
}
/**
*
* Indicates whether this AVUser was created during this session through a call to AVUser.signUp()
* or by logging in with a linked service such as Facebook.
*
*/
public boolean isNew() {
return isNew;
}
/**
* @see #logIn(String, String, Class)
* @param username
* @param password
* @return
*/
public static AVUser logIn(String username, String password) throws AVException {
return logIn(username, password, AVUser.class);
}
/**
*
* Logs in a user with a username and password. On success, this saves the session to disk, so you
* can retrieve the currently logged in user using AVUser.getCurrentUser()
*
*
* Typically, you should use {@link #logInInBackground(String, String,LogInCallback)}
* instead of this, unless you are managing your own
* threading.
*
*
* @param username The username to log in with.
* @param password The password to log in with.
* @param clazz The AVUser itself or subclass.
* @return The user if the login was successful.
*/
public static T logIn(String username, String password, Class clazz)
throws AVException {
final AVUser[] list = {null};
logInInBackground(username, password, true, new LogInCallback() {
@Override
public void done(T user, AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
} else {
list[0] = user;
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
}, clazz);
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
return (T) list[0];
}
private static String anonymousAuthData() {
String json =
String.format("{\"authData\": {\"anonymous\" : {\"id\": \"%s\"}}}", UUID.randomUUID()
.toString().toLowerCase());
return json;
}
/**
* anonymously login.
*
* @param callback
*/
public static void logInAnonymously(final LogInCallback callback) {
String string = anonymousAuthData();
PaasClient.storageInstance().postObject(AVUser.AVUSER_ENDPOINT, string, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
AVUser user = AVUser.newAVUser();
AVUtils.copyPropertiesFromJsonStringToAVObject(content, user);
user.setAnonymous(true);
AVUser.changeCurrentUser(user, true);
if (callback != null) {
callback.internalDone(user, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
});
}
static private String logInPath() {
return "login";
}
/**
* @see #logInInBackground(String, String, LogInCallback, Class)
* @param username
* @param password
* @param callback
*/
public static void logInInBackground(String username, String password,
LogInCallback callback) {
logInInBackground(username, password, callback, AVUser.class);
}
/**
*
* Logs in a user with a username and password. On success, this saves the session to disk, so you
* can retrieve the currently logged in user using AVUser.getCurrentUser()
*
*
* This is preferable to using AVUser.logIn(java.lang.String, java.lang.String), unless your code
* is already running from a background thread.
*
*
* @param username The username to log in with.
* @param password The password to log in with.
* @param clazz The AVUser itself or subclass.
* @param callback callback.done(user, e) is called when the login completes.
*/
public static void logInInBackground(String username, String password,
LogInCallback callback, Class clazz) {
logInInBackground(username, password, false, callback, clazz);
}
private static Map createUserMap(String username, String password, String email) {
Map map = new HashMap();
map.put("username", username);
if (AVUtils.isBlankString(username)) {
throw new IllegalArgumentException("Blank username.");
}
if (!AVUtils.isBlankString(password)) {
map.put("password", password);
}
if (!AVUtils.isBlankString(email)) {
map.put("email", email);
}
return map;
}
private static Map createUserMap(String username, String password, String email,
String phoneNumber, String smsCode) {
Map map = new HashMap();
if (AVUtils.isBlankString(username) && AVUtils.isBlankString(phoneNumber)) {
throw new IllegalArgumentException("Blank username and blank mobile phone number");
}
if (!AVUtils.isBlankString(username)) {
map.put("username", username);
}
if (!AVUtils.isBlankString(password)) {
map.put("password", password);
}
if (!AVUtils.isBlankString(email)) {
map.put("email", email);
}
if (!AVUtils.isBlankString(phoneNumber)) {
map.put("mobilePhoneNumber", phoneNumber);
}
if (!AVUtils.isBlankString(smsCode)) {
map.put("smsCode", smsCode);
}
return map;
}
private static Map createUserMapAFAP(String username, String password, String email,
String phoneNumber, String smsCode) {
Map map = new HashMap();
if (!AVUtils.isBlankString(username)) {
map.put("username", username);
}
if (!AVUtils.isBlankString(password)) {
map.put("password", password);
}
if (!AVUtils.isBlankString(email)) {
map.put("email", email);
}
if (!AVUtils.isBlankString(phoneNumber)) {
map.put("mobilePhoneNumber", phoneNumber);
}
if (!AVUtils.isBlankString(smsCode)) {
map.put("smsCode", smsCode);
}
return map;
}
private static void logInInBackground(String username, String password,
boolean sync, LogInCallback callback, Class clazz) {
Map map = createUserMap(username, password, "");
final LogInCallback internalCallback = callback;
final T user = newAVUser(clazz, callback);
if (user == null) {
return;
}
user.put("username", username, false);
PaasClient.storageInstance().postObject(logInPath(), JSON.toJSONString(map), sync, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
AVException error = e;
T resultUser = user;
if (!AVUtils.isBlankContent(content)) {
AVUtils.copyPropertiesFromJsonStringToAVObject(content, user);
user.processAuthData(null);
AVUser.changeCurrentUser(user, true);
} else {
resultUser = null;
error = new AVException(AVException.OBJECT_NOT_FOUND, "User is not found.");
}
if (internalCallback != null) {
internalCallback.internalDone(resultUser, error);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* login by email.
* @param email
* @param password
* @param callback
*/
public static void loginByEmailInBackground(String email, String password, final LogInCallback callback) {
loginByEmailInBackground(email, password, callback, AVUser.class);
}
/**
* login by email with specified User class.
* @param email
* @param password
* @param callback
* @param clazz
* @param
*/
public static void loginByEmailInBackground(String email, String password, final LogInCallback callback, Class clazz) {
Map map = createUserMapAFAP(null, password, email, null, null);
final LogInCallback internalCallback = callback;
final T user = newAVUser(clazz, callback);
if (user == null) {
return;
}
user.put("email", email, false);
PaasClient.storageInstance().postObject(logInPath(), JSON.toJSONString(map), false, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
AVException error = e;
T resultUser = user;
if (!AVUtils.isBlankContent(content)) {
AVUtils.copyPropertiesFromJsonStringToAVObject(content, user);
user.processAuthData(null);
AVUser.changeCurrentUser(user, true);
} else {
resultUser = null;
error = new AVException(AVException.OBJECT_NOT_FOUND, "User is not found.");
}
if (internalCallback != null) {
internalCallback.internalDone(resultUser, error);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
public static AVUser loginByMobilePhoneNumber(String phone, String password) throws AVException {
return loginByMobilePhoneNumber(phone, password, AVUser.class);
}
public static T loginByMobilePhoneNumber(String phone, String password,
Class clazz) throws AVException {
final AVUser[] list = {null};
loginByMobilePhoneNumberInBackground(phone, password, true, new LogInCallback() {
@Override
public void done(T user, AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
} else {
list[0] = user;
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
}, clazz);
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
return (T) list[0];
}
public static void loginByMobilePhoneNumberInBackground(String phone, String password,
LogInCallback callback) {
loginByMobilePhoneNumberInBackground(phone, password, false, callback, AVUser.class);
}
public static void loginByMobilePhoneNumberInBackground(String phone,
String password, LogInCallback callback, Class clazz) {
loginByMobilePhoneNumberInBackground(phone, password, false, callback, clazz);
}
private static void loginByMobilePhoneNumberInBackground(String phone,
String password, boolean sync, LogInCallback callback, Class clazz) {
Map map = createUserMap(null, password, null, phone, null);
final LogInCallback internalCallback = callback;
final T user = newAVUser(clazz, callback);
if (user == null) {
return;
}
user.setMobilePhoneNumber(phone);
PaasClient.storageInstance().postObject(logInPath(), JSON.toJSONString(map), sync, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
AVException error = e;
T resultUser = user;
if (!AVUtils.isBlankContent(content)) {
AVUtils.copyPropertiesFromJsonStringToAVObject(content, user);
AVUser.changeCurrentUser(user, true);
} else {
resultUser = null;
error = new AVException(AVException.OBJECT_NOT_FOUND, "User is not found.");
}
if (internalCallback != null) {
internalCallback.internalDone(resultUser, error);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* 通过短信验证码和手机号码来登录用户
*
* 请不要在UI线程内调用本方法
*
* @param phone
* @param smsCode
* @return
* @throws AVException
*/
public static AVUser loginBySMSCode(String phone, String smsCode) throws AVException {
return loginBySMSCode(phone, smsCode, AVUser.class);
}
/**
* 通过短信验证码和手机号码来登录用户
*
* 请不要在UI线程内调用本方法
*
* @param phone
* @param smsCode
* @param clazz AVUser的子类对象
* @return
* @throws AVException
*/
public static T loginBySMSCode(String phone, String smsCode, Class clazz)
throws AVException {
final AVUser[] list = {null};
loginBySMSCodeInBackground(phone, smsCode, true, new LogInCallback() {
@Override
public void done(T user, AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
} else {
list[0] = user;
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
}, clazz);
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
return (T) list[0];
}
/**
* 通过短信验证码和手机号码来登录用户
*
* 本方法为异步方法,可以在UI线程中调用
*
* @param phone
* @param smsCode
* @param callback
*/
public static void loginBySMSCodeInBackground(String phone, String smsCode,
LogInCallback callback) {
loginBySMSCodeInBackground(phone, smsCode, false, callback, AVUser.class);
}
/**
* 通过短信验证码和手机号码来登录用户
*
* 本方法为异步方法,可以在UI线程中调用
*
* @param phone
* @param smsCode
* @param callback
* @param clazz AVUser的子类
*/
public static void loginBySMSCodeInBackground(String phone, String smsCode,
LogInCallback callback, Class clazz) {
loginBySMSCodeInBackground(phone, smsCode, false, callback, clazz);
}
private static void loginBySMSCodeInBackground(String phone, String smsCode,
boolean sync, LogInCallback callback, Class clazz) {
Map map = createUserMap(null, null, "", phone, smsCode);
final LogInCallback internalCallback = callback;
final T user = newAVUser(clazz, callback);
if (user == null) {
return;
}
user.setMobilePhoneNumber(phone);
PaasClient.storageInstance().postObject(logInPath(), JSON.toJSONString(map), sync, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
AVException error = e;
T resultUser = user;
if (!AVUtils.isBlankContent(content)) {
AVUtils.copyPropertiesFromJsonStringToAVObject(content, user);
AVUser.changeCurrentUser(user, true);
} else {
resultUser = null;
error = new AVException(AVException.OBJECT_NOT_FOUND, "User is not found.");
}
if (internalCallback != null) {
internalCallback.internalDone(resultUser, error);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* 刷新该用户的 sessionToken
* 同步方法,请不要在UI线程内调用本方法
* @param
* @return
*/
public T refreshSessionToken() {
final ArrayList arrayList = new ArrayList<>();
refreshSessionToken(true, new LogInCallback(){
@Override
public void done(T user, AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
} else {
arrayList.add(user);
}
}
});
return arrayList.get(0);
}
/**
* 刷新该用户的 sessionToken
* 异步方法,可以在 UI 线程中调用
* @param callback
* @param
*/
public void refreshSessionTokenInBackground(LogInCallback callback) {
refreshSessionToken(false, callback);
}
private void refreshSessionToken(boolean sync, final LogInCallback callback) {
if (AVUtils.isBlankContent(objectId) || AVUtils.isBlankContent(sessionToken)) {
if (null != callback) {
callback.internalDone(null, new AVException(AVException.MISSING_OBJECT_ID, "current user is not login"));
}
return;
}
String path = String.format("users/%s/refreshSessionToken", objectId);
String param = AVUtils.restfulServerData(null);
PaasClient.storageInstance().putObject(path, param, sync, headerMap(), new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
AVException error = e;
T user = (T)AVUser.newAVUser(subClazz == null ? AVUser.class : subClazz, null);
if (null != user && !AVUtils.isBlankContent(content)) {
AVUtils.copyPropertiesFromJsonStringToAVObject(content, user);
user.processAuthData(null);
AVUser.changeCurrentUser(user, true);
} else {
error = new AVException(AVException.OBJECT_NOT_FOUND, "User is not found.");
}
if (callback != null) {
callback.internalDone(user, error);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* Logs in a user with a session token. this saves the session to disk, so you
* can retrieve the currently logged in user using AVUser.getCurrentUser().
* Don't call this method on the UI thread
* @param sessionToken The sessionToken to log in with
* @return
* @throws AVException
*/
public static AVUser becomeWithSessionToken(String sessionToken) throws AVException {
return becomeWithSessionToken(sessionToken, AVUser.class);
}
/**
* Logs in a user with a session token. this saves the session to disk, so you
* can retrieve the currently logged in user using AVUser.getCurrentUser().
* Don't call this method on the UI thread
* @param sessionToken The sessionToken to log in with
* @param clazz The AVUser itself or subclass.
* @return
* @throws AVException
*/
public static AVUser becomeWithSessionToken(String sessionToken, Class clazz) throws AVException {
final AVUser[] list = {null};
becomeWithSessionTokenInBackground(sessionToken, true, new LogInCallback() {
@Override
public void done(T user, AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
} else {
list[0] = user;
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
}, clazz);
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
return (T) list[0];
}
/**
* Logs in a user with a session token. this saves the session to disk, so you
* can retrieve the currently logged in user using AVUser.getCurrentUser().
* @param sessionToken The sessionToken to log in with
* @param callback
*/
public static void becomeWithSessionTokenInBackground(String sessionToken,
LogInCallback callback) {
becomeWithSessionTokenInBackground(sessionToken, callback, AVUser.class);
}
/**
* Logs in a user with a session token. this saves the session to disk, so you
* can retrieve the currently logged in user using AVUser.getCurrentUser().
* @param sessionToken The sessionToken to log in with
* @param callback
* @param clazz
*/
public static void becomeWithSessionTokenInBackground(String sessionToken,
LogInCallback callback, Class clazz) {
becomeWithSessionTokenInBackground(sessionToken, false, callback, clazz);
}
private static void becomeWithSessionTokenInBackground(String sessionToken,
boolean sync, LogInCallback callback, Class clazz) {
final LogInCallback internalCallback = callback;
final T user = newAVUser(clazz, callback);
if (user == null) {
return;
}
AVRequestParams params = new AVRequestParams();
params.put("session_token", sessionToken);
PaasClient.storageInstance().getObject("users/me", params, sync, null, new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
AVException error = e;
T resultUser = user;
if (!AVUtils.isBlankContent(content)) {
AVUtils.copyPropertiesFromJsonStringToAVObject(content, user);
user.processAuthData(null);
AVUser.changeCurrentUser(user, true);
} else {
resultUser = null;
error = new AVException(AVException.OBJECT_NOT_FOUND, "User is not found.");
}
if (internalCallback != null) {
internalCallback.internalDone(resultUser, error);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
});
}
/**
* 直接通过手机号码和验证码来创建或者登录用户。 如果手机号码已经存在则为登录,否则创建新用户
*
* 请不要在UI线程中间调用此方法
*
* @param mobilePhoneNumber
* @param smsCode
* @return
* @throws AVException
* @since 2.6.10
* @see AVOSCloud#requestSMSCode(String)
*/
public static AVUser signUpOrLoginByMobilePhone(String mobilePhoneNumber, String smsCode)
throws AVException {
return signUpOrLoginByMobilePhone(mobilePhoneNumber, smsCode, AVUser.class);
}
/**
* 直接通过手机号码和验证码来创建或者登录用户。 如果手机号码已经存在则为登录,否则创建新用户
*
* 请不要在UI线程中间调用此方法
*
* @param mobilePhoneNumber
* @param smsCode
* @param clazz
* @return
* @throws AVException
* @since 2.6.10
* @see AVOSCloud#requestSMSCode(String)
*/
public static T signUpOrLoginByMobilePhone(String mobilePhoneNumber,
String smsCode, Class clazz) throws AVException {
final AVUser[] list = {null};
signUpOrLoginByMobilePhoneInBackground(mobilePhoneNumber, smsCode, true, clazz,
new LogInCallback() {
@Override
public void done(T user, AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
} else {
list[0] = user;
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
});
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
return (T) list[0];
}
/**
* 直接通过手机号码和验证码来创建或者登录用户。 如果手机号码已经存在则为登录,否则创建新用户
*
*
* @param mobilePhoneNumber
* @param smsCode
* @param callback
* @since 2.6.10
* @see AVOSCloud#requestSMSCodeInBackground(String, RequestMobileCodeCallback)
*/
public static void signUpOrLoginByMobilePhoneInBackground(String mobilePhoneNumber,
String smsCode, LogInCallback callback) {
signUpOrLoginByMobilePhoneInBackground(mobilePhoneNumber, smsCode, AVUser.class, callback);
}
/**
* 直接通过手机号码和验证码来创建或者登录用户。 如果手机号码已经存在则为登录,否则创建新用户
*
* @param mobilePhoneNumber
* @param smsCode
* @param clazz AVUser的子类对象
* @param callback
* @since 2.6.10
* @see AVOSCloud#requestSMSCodeInBackground(String, RequestMobileCodeCallback)
*/
public static void signUpOrLoginByMobilePhoneInBackground(
String mobilePhoneNumber, String smsCode, Class clazz, LogInCallback callback) {
signUpOrLoginByMobilePhoneInBackground(mobilePhoneNumber, smsCode, false, clazz, callback);
}
private static void signUpOrLoginByMobilePhoneInBackground(
String mobilePhoneNumber, String smsCode, boolean sync, Class clazz,
LogInCallback callback) {
if (AVUtils.isBlankString(smsCode)) {
if (callback != null) {
callback.internalDone(null, new AVException(AVException.OTHER_CAUSE,
"SMS Code can't be empty"));
} else {
LogUtil.avlog.e("SMS Code can't be empty");
}
return;
}
Map map = createUserMap(null, null, "", mobilePhoneNumber, smsCode);
final LogInCallback internalCallback = callback;
final T user = newAVUser(clazz, callback);
if (user == null) {
return;
}
user.setMobilePhoneNumber(mobilePhoneNumber);
PaasClient.storageInstance().postObject("usersByMobilePhone", JSON.toJSONString(map), sync,
false, new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
AVException error = e;
T resultUser = user;
if (!AVUtils.isBlankContent(content)) {
AVUtils.copyPropertiesFromJsonStringToAVObject(content, user);
AVUser.changeCurrentUser(user, true);
} else {
resultUser = null;
error = new AVException(AVException.OBJECT_NOT_FOUND, "User is not found.");
}
if (internalCallback != null) {
internalCallback.internalDone(resultUser, error);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
public static T newAVUser(Class clazz, LogInCallback cb) {
try {
final T user = clazz.newInstance();
return user;
} catch (Exception e) {
if (cb != null) {
cb.internalDone(null, AVErrorUtils.createException(e, null));
} else {
throw new AVRuntimeException("Create user instance failed.", e);
}
}
return null;
}
protected static T newAVUser() {
return (T) newAVUser(subClazz == null ? AVUser.class : subClazz, null);
}
/**
* Logs out the currently logged in user session. This will remove the session from disk, log out
* of linked services, and future calls to AVUser.getCurrentUser() will return null.
*/
public static void logOut() {
AVUser.changeCurrentUser(null, true);
PaasClient.storageInstance().setDefaultACL(null);
}
/**
* Add a key-value pair to this object. It is recommended to name keys in
* partialCamelCaseLikeThis.
*
* @param key Keys must be alphanumerical plus underscore, and start with a letter.
* @param value Values may be numerical, String, JSONObject, JSONArray, JSONObject.NULL, or other
* AVObjects.
*/
@Override
public void put(String key, Object value) {
super.put(key, value);
}
/**
* Removes a key from this object's data if it exists.
*
* @param key The key to remove.
*/
@Override
public void remove(String key) {
super.remove(key);
}
/**
*
* Requests a password reset email to be sent to the specified email address associated with the
* user account. This email allows the user to securely reset their password on the AVOSCloud
* site.
*
*
* Typically, you should use AVUser.requestPasswordResetInBackground(java.lang.String,
* {@link #requestPasswordResetInBackground(String,RequestPasswordResetCallback)} instead of this, unless you are managing your own
* threading.
*
*
* @param email The email address associated with the user that forgot their password.
*/
public static void requestPasswordReset(String email) {
requestPasswordResetInBackground(email, true, null);
}
/**
*
* Requests a password reset email to be sent in a background thread to the specified email
* address associated with the user account. This email allows the user to securely reset their
* password on the AVOSCloud site.
*
*
* This is preferable to using requestPasswordReset(), unless your code is already running from a
* background thread.
*
*
* @param email The email address associated with the user that forgot their password.
* @param callback callback.done(e) is called when the request completes.
*/
public static void requestPasswordResetInBackground(String email,
RequestPasswordResetCallback callback) {
requestPasswordResetInBackground(email, false, callback);
}
private static void requestPasswordResetInBackground(String email, boolean sync,
RequestPasswordResetCallback callback) {
final RequestPasswordResetCallback internalCallback = callback;
Map map = new HashMap();
map.put("email", email);
String object = AVUtils.jsonStringFromMapWithNull(map);
PaasClient.storageInstance().postObject("requestPasswordReset", object, sync, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (internalCallback != null) {
internalCallback.internalDone(null, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* 同步方法调用修改用户当前的密码
*
* 您需要保证用户有效的登录状态
*/
public void updatePassword(String oldPassword, String newPassword) throws AVException {
updatePasswordInBackground(oldPassword, newPassword, new UpdatePasswordCallback() {
@Override
public void done(AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
}, true);
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
}
/**
* 异步方法调用修改用户当前的密码
*
* 您需要保证用户有效的登录状态
*/
public void updatePasswordInBackground(String oldPassword, String newPassword,
UpdatePasswordCallback callback) {
updatePasswordInBackground(oldPassword, newPassword, callback, false);
}
private void updatePasswordInBackground(String oldPassword, String newPassword,
final UpdatePasswordCallback callback, boolean sync) {
if (!this.isAuthenticated() || AVUtils.isBlankString(getObjectId())) {
callback.internalDone(AVErrorUtils.sessionMissingException());
} else {
String relativePath = String.format("users/%s/updatePassword", this.getObjectId());
Map params = new HashMap();
params.put("old_password", oldPassword);
params.put("new_password", newPassword);
String paramsString = AVUtils.restfulServerData(params);
PaasClient.storageInstance().putObject(relativePath, paramsString, sync, headerMap(),
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (null == e && !TextUtils.isEmpty(content)) {
sessionToken = AVUtils.getJSONValue(content, SESSION_TOKEN_KEY);
}
callback.internalDone(e);
}
@Override
public void onFailure(Throwable error, String content) {
callback.internalDone(AVErrorUtils.createException(error, content));
}
}, getObjectId(), getObjectId());
}
}
/**
* request a sms code to reset the password
* this is a synchronous method, if you need an asynchronous method, please use {@link #requestPasswordResetBySmsCodeInBackground(String, RequestMobileCodeCallback)}
* @param phoneNumber the phone need to reset password
* @throws AVException
*/
public static void requestPasswordResetBySmsCode(String phoneNumber) throws AVException {
requestPasswordResetBySmsCode(phoneNumber, null);
}
/**
* request a sms code to reset the password
* This is a synchronous method, if you need an asynchronous method, please use {@link #requestPasswordResetBySmsCodeInBackground(String, String, RequestMobileCodeCallback)}
* @param phoneNumber the phone need to reset password
* @param validateToken the token has been verified by captcha
* @throws AVException
*/
public static void requestPasswordResetBySmsCode(String phoneNumber, String validateToken) throws AVException {
requestPasswordResetBySmsCodeInBackground(phoneNumber, validateToken, true,
new RequestMobileCodeCallback() {
@Override
public void done(AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
});
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
}
/**
* request a sms code to reset the password
* @param phoneNumber the phone need to reset password
* @param callback callback.done(e) is called when this action complete.
*/
public static void requestPasswordResetBySmsCodeInBackground(String phoneNumber,
RequestMobileCodeCallback callback) {
requestPasswordResetBySmsCodeInBackground(phoneNumber, null, callback);
}
/**
* request a sms code to reset the password
* @param phoneNumber the phone need to reset password
* @param validateToken the token has been verified by captcha
* @param callback callback.done(e) is called when this action complete.
*/
public static void requestPasswordResetBySmsCodeInBackground(String phoneNumber, String validateToken,
RequestMobileCodeCallback callback) {
requestPasswordResetBySmsCodeInBackground(phoneNumber, validateToken, false, callback);
}
protected static void requestPasswordResetBySmsCodeInBackground(String phoneNumber, String validateToken,
boolean sync, RequestMobileCodeCallback callback) {
final RequestMobileCodeCallback internalCallback = callback;
if (AVUtils.isBlankString(phoneNumber)
|| !AVUtils.checkMobilePhoneNumber(phoneNumber)) {
callback.internalDone(new AVException(AVException.INVALID_PHONE_NUMBER,
"Invalid Phone Number"));
return;
}
Map map = new HashMap();
map.put(SMS_PHONE_NUMBER, phoneNumber);
if (!AVUtils.isBlankString(validateToken)) {
map.put(SMS_VALIDATE_TOKEN, validateToken);
}
String object = AVUtils.jsonStringFromMapWithNull(map);
PaasClient.storageInstance().postObject("requestPasswordResetBySmsCode", object, sync, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (internalCallback != null) {
internalCallback.internalDone(null, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* 通过短信验证码更新用户密码
*
* 请确保是在异步方法中调用本方法否则请调用resetPasswordBySmsCodeInBackground(String smsCode, String newPassword,
* UpdatePasswordCallback callback) 方法
*
* @param smsCode
* @param newPassword
* @throws AVException
*/
public static void resetPasswordBySmsCode(String smsCode, String newPassword) throws AVException {
resetPasswordBySmsCodeInBackground(smsCode, newPassword, true, new UpdatePasswordCallback() {
@Override
public void done(AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
});
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
}
/**
* 通过短信验证码更新用户密码
*
* @param smsCode
* @param newPassword
* @param callback
*/
public static void resetPasswordBySmsCodeInBackground(String smsCode, String newPassword,
UpdatePasswordCallback callback) {
resetPasswordBySmsCodeInBackground(smsCode, newPassword, false, callback);
}
protected static void resetPasswordBySmsCodeInBackground(String smsCode, String newPassword,
boolean sync, UpdatePasswordCallback callback) {
final UpdatePasswordCallback internalCallback = callback;
if (AVUtils.isBlankString(smsCode) || !AVUtils.checkMobileVerifyCode(smsCode)) {
callback
.internalDone(new AVException(AVException.INVALID_PHONE_NUMBER, "Invalid Verify Code"));
return;
}
String endpointer = String.format("resetPasswordBySmsCode/%s", smsCode);
Map params = new HashMap();
params.put("password", newPassword);
PaasClient.storageInstance().putObject(endpointer, AVUtils.restfulServerData(params), sync,
null, new GenericObjectCallback() {
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(new AVException(content, error));
}
}
@Override
public void onSuccess(String content, AVException e) {
internalCallback.internalDone(e);
}
}, null, null);
}
/**
*
* 调用这个方法会给用户的邮箱发送一封验证邮件,让用户能够确认在AVOS Cloud网站上注册的账号邮箱
*
*
* 除非是在一个后台线程中调用这个方法, 否则,一般情况下,请使用AVUser.requestEmailVerifyInBackground(email,callback)方法进行调用
*
*
*
* @param email The email address associated with the user that forgot their password.
*/
public static void requestEmailVerify(String email) {
requestEmailVerifyInBackground(email, true, null);
}
/**
*
* 调用这个方法会给用户的邮箱发送一封验证邮件,让用户能够确认在AVOS Cloud网站上注册的账号邮箱
*
*
* 除非这个方法在一个后台线程中被调用,请勿使用 requestEmailVerify()
*
*
* @param email The email address associated with the user that forgot their password.
* @param callback callback.done(e) is called when the request completes.
*/
public static void requestEmailVerifyInBackground(String email,
RequestEmailVerifyCallback callback) {
requestEmailVerifyInBackground(email, false, callback);
}
private static void requestEmailVerifyInBackground(String email, boolean sync,
RequestEmailVerifyCallback callback) {
final RequestEmailVerifyCallback internalCallback = callback;
if (AVUtils.isBlankString(email) || !AVUtils.checkEmailAddress(email)) {
callback.internalDone(new AVException(AVException.INVALID_EMAIL_ADDRESS, "Invalid Email"));
return;
}
Map map = new HashMap();
map.put("email", email);
String object = AVUtils.jsonStringFromMapWithNull(map);
PaasClient.storageInstance().postObject("requestEmailVerify", object, sync, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (internalCallback != null) {
internalCallback.internalDone(null, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* request to send a sms to verify the phone
* @param phoneNumber the phone need to be verified
* @throws AVException
*/
public static void requestMobilePhoneVerify(String phoneNumber) throws AVException {
requestMobilePhoneVerify(phoneNumber, null);
}
/**
* request to send a sms to verify the phone
* @param phoneNumber the phone need to be verified
* @param validateToken the token has been verified by captcha
* @throws AVException
*/
public static void requestMobilePhoneVerify(String phoneNumber, String validateToken) throws AVException {
requestMobilePhoneVerifyInBackground(phoneNumber, validateToken, true, new RequestMobileCodeCallback() {
@Override
public void done(AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
});
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
}
/**
* request to send a sms to verify the phone
* @param phoneNumber the phone need to be verified
* @param callback callback.done(e) will be called when the request complete.
*/
public static void requestMobilePhoneVerifyInBackground(String phoneNumber,
RequestMobileCodeCallback callback) {
requestMobilePhoneVerifyInBackground(phoneNumber, null, false, callback);
}
/**
* request to send a sms to verify the phone
*
* @param phoneNumber the phone need to be verified
* @param validateToken the token has been verified by captcha
* @param callback callback.done(e) will be called when the request complete.
*/
public static void requestMobilePhoneVerifyInBackground(String phoneNumber, String validateToken,
RequestMobileCodeCallback callback) {
requestMobilePhoneVerifyInBackground(phoneNumber, validateToken, false, callback);
}
private static void requestMobilePhoneVerifyInBackground(String phoneNumber, String validateToken,
boolean sync, RequestMobileCodeCallback callback) {
final RequestMobileCodeCallback internalCallback = callback;
if (AVUtils.isBlankString(phoneNumber)
|| !AVUtils.checkMobilePhoneNumber(phoneNumber)) {
callback.internalDone(new AVException(AVException.INVALID_PHONE_NUMBER,
"Invalid Phone Number"));
return;
}
Map map = new HashMap();
map.put(SMS_PHONE_NUMBER, phoneNumber);
if (!AVUtils.isBlankString(validateToken)) {
map.put(SMS_VALIDATE_TOKEN, validateToken);
}
String object = AVUtils.jsonStringFromMapWithNull(map);
PaasClient.storageInstance().postObject("requestMobilePhoneVerify", object, sync, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (internalCallback != null) {
internalCallback.internalDone(null, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* request a login verification code
* This is a synchronous method, if you need an asynchronous method, please use {@link #requestLoginSmsCodeInBackground(String, RequestMobileCodeCallback)}
* @param phoneNumber the phone need to login
* @throws AVException
*/
public static void requestLoginSmsCode(String phoneNumber) throws AVException {
requestLoginSmsCode(phoneNumber, null);
}
/**
* request a login verification code
* This is a synchronous method, if you need an asynchronous method, please use {@link #requestLoginSmsCodeInBackground(String, String, RequestMobileCodeCallback)}
* @param phoneNumber the phone need to login
* @param validateToken the token has been verified by captcha
* @throws AVException
*/
public static void requestLoginSmsCode(String phoneNumber, String validateToken) throws AVException {
requestLoginSmsCodeInBackground(phoneNumber, validateToken, false, new RequestMobileCodeCallback() {
@Override
public void done(AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
});
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
}
/**
* request a login verification code
* @param phoneNumber the phone need to login
* @param callback callback.done(e) will be called when the request complete.
*/
public static void requestLoginSmsCodeInBackground(String phoneNumber,
RequestMobileCodeCallback callback) {
requestLoginSmsCodeInBackground(phoneNumber, null, callback);
}
/**
* request a login verification code
* @param phoneNumber the phone need to login
* @param validateToken the token has been verified by captcha
* @param callback callback.done(e) will be called when the request complete.
*/
public static void requestLoginSmsCodeInBackground(String phoneNumber, String validateToken,
RequestMobileCodeCallback callback) {
requestLoginSmsCodeInBackground(phoneNumber, validateToken, false, callback);
}
private static void requestLoginSmsCodeInBackground(String phoneNumber, String validateToken, boolean sync,
RequestMobileCodeCallback callback) {
final RequestMobileCodeCallback internalCallback = callback;
if (AVUtils.isBlankString(phoneNumber)
|| !AVUtils.checkMobilePhoneNumber(phoneNumber)) {
callback.internalDone(new AVException(AVException.INVALID_PHONE_NUMBER,
"Invalid Phone Number"));
return;
}
Map map = new HashMap();
map.put(SMS_PHONE_NUMBER, phoneNumber);
if (!AVUtils.isBlankString(validateToken)) {
map.put(SMS_VALIDATE_TOKEN, validateToken);
}
String object = AVUtils.jsonStringFromMapWithNull(map);
PaasClient.storageInstance().postObject("requestLoginSmsCode", object, sync, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (internalCallback != null) {
internalCallback.internalDone(null, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* 验证手机收到的验证码
*
* 请在异步方法中调用此方法,或者您可以调用verifyMobilePhoneInBackground方法
*
* @param verifyCode
*/
public static void verifyMobilePhone(String verifyCode) throws AVException {
verifyMobilePhoneInBackground(true, verifyCode, new AVMobilePhoneVerifyCallback() {
@Override
public void done(AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
}
}
@Override
public boolean mustRunOnUIThread() {
return false;
}
});
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
}
/**
* 验证手机收到的验证码
*
*
* @param verifyCode
*/
public static void verifyMobilePhoneInBackground(String verifyCode,
AVMobilePhoneVerifyCallback callback) {
verifyMobilePhoneInBackground(false, verifyCode, callback);
}
private static void verifyMobilePhoneInBackground(boolean sync, String verifyCode,
AVMobilePhoneVerifyCallback callback) {
final AVMobilePhoneVerifyCallback internalCallback = callback;
if (AVUtils.isBlankString(verifyCode) || !AVUtils.checkMobileVerifyCode(verifyCode)) {
callback
.internalDone(new AVException(AVException.INVALID_PHONE_NUMBER, "Invalid Verify Code"));
return;
}
String endpointer = String.format("verifyMobilePhone/%s", verifyCode);
PaasClient.storageInstance().postObject(endpointer, AVUtils.restfulServerData(null), sync,
false, new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (internalCallback != null) {
internalCallback.internalDone(null, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
if (internalCallback != null) {
internalCallback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* Sets the email address.
*
* @param email The email address to set.
*/
public void setEmail(String email) {
this.email = email;
this.put("email", email);
}
/**
* Sets the password.
*
* @param password The password to set.
*/
public void setPassword(String password) {
this.password = password;
this.put("password", password);
markAnonymousUserTransfer();
}
/**
* Sets the username. Usernames cannot be null or blank.
*
* @param username The username to set.
*/
public void setUsername(String username) {
this.username = username;
this.put("username", username);
markAnonymousUserTransfer();
}
public String getMobilePhoneNumber() {
return mobilePhoneNumber;
}
public void setMobilePhoneNumber(String mobilePhoneNumber) {
this.mobilePhoneNumber = mobilePhoneNumber;
this.put("mobilePhoneNumber", mobilePhoneNumber);
}
public boolean isMobilePhoneVerified() {
return this.getBoolean("mobilePhoneVerified");
}
void setMobilePhoneVerified(boolean mobilePhoneVerified) {
this.put("mobileVerified", mobilePhoneVerified);
}
@JSONField(serialize = false)
public List getRoles() throws AVException {
AVQuery roleQuery = new AVQuery(AVRole.className);
roleQuery.whereEqualTo(AVUser.AVUSER_ENDPOINT, this);
return roleQuery.find();
}
public void getRolesInBackground(final AVCallback> callback) {
AVQuery roleQuery = new AVQuery(AVRole.className);
roleQuery.whereEqualTo(AVUSER_ENDPOINT, this);
roleQuery.findInBackground(new FindCallback() {
@Override
public void done(List list, AVException e) {
callback.internalDone(list, e);
}
});
}
private void signUp(boolean sync, final SignUpCallback callback) {
if (sync) {
try {
this.save();
if (callback != null) callback.internalDone(null);
} catch (AVException e) {
if (callback != null) callback.internalDone(e);
}
} else {
this.saveInBackground(new SaveCallback() {
@Override
public void done(AVException e) {
if (callback != null) callback.internalDone(e);
}
});
}
}
/**
*
* Signs up a new user. You should call this instead of AVObject.save() for new AVUsers. This will
* create a new AVUser on the server, and also persist the session on disk so that you can access
* the user using AVUser.getCurrentUser().
*
*
* A username and password must be set before calling signUp.
*
*
* Typically, you should use {@link #signUpInBackground(SignUpCallback)} instead of this,
* unless you are managing your own threading.
*
*/
public void signUp() throws AVException {
signUp(true, new SignUpCallback() {
@Override
public void done(AVException e) {
if (e != null) {
AVExceptionHolder.add(e);
}
}
@Override
protected boolean mustRunOnUIThread() {
return false;
}
});
if (AVExceptionHolder.exists()) {
throw AVExceptionHolder.remove();
}
}
/**
*
* Signs up a new user. You should call this instead of AVObject.save() for new AVUsers. This will
* create a new AVUser on the server, and also persist the session on disk so that you can access
* the user using AVUser.getCurrentUser().
*
*
* A username and password must be set before calling signUp.
*
*
* This is preferable to using AVUser.signUp(), unless your code is already running from a
* background thread.
*
*
* @param callback callback.done(user, e) is called when the signUp completes.
*/
public void signUpInBackground(SignUpCallback callback) {
signUp(false, callback);
}
void setSinaWeiboToken(String token) {
this.sinaWeiboToken = token;
}
public String getSinaWeiboToken() {
return sinaWeiboToken;
}
void setQQWeiboToken(String token) {
qqWeiboToken = token;
}
public String getQQWeiboToken() {
return qqWeiboToken;
}
@Override
protected void onSaveSuccess() {
super.onSaveSuccess();
this.processAuthData(null);
if (!AVUtils.isBlankString(sessionToken)) {
changeCurrentUser(this, true);
}
}
@Override
protected void onDataSynchronized() {
processAuthData(null);
if (!AVUtils.isBlankString(sessionToken)) {
changeCurrentUser(this, true);
}
}
@Override
protected Map headerMap() {
Map map = new HashMap();
if (!AVUtils.isBlankString(sessionToken)) {
map.put(PaasClient.sessionTokenField, sessionToken);
}
return map;
}
static AVUser userFromSinaWeibo(String weiboToken, String userName) {
AVUser user = newAVUser();
user.sinaWeiboToken = weiboToken;
user.username = userName;
return user;
}
static AVUser userFromQQWeibo(String weiboToken, String userName) {
AVUser user = newAVUser();
user.qqWeiboToken = weiboToken;
user.username = userName;
return user;
}
private boolean checkUserAuthentication(final AVCallback callback) {
if (!this.isAuthenticated() || AVUtils.isBlankString(getObjectId())) {
if (callback != null) {
callback.internalDone(AVErrorUtils.createException(AVException.SESSION_MISSING,
"No valid session token, make sure signUp or login has been called."));
}
return false;
}
return true;
}
/**
*
* Follow the user specified by userObjectId. This will create a follow relation between this user
* and the user specified by the userObjectId.
*
*
* @param userObjectId The user objectId.
* @param callback callback.done(user, e) is called when the follow completes.
* @since 2.1.3
*/
public void followInBackground(String userObjectId, final FollowCallback callback) {
this.followInBackground(userObjectId, null, callback);
}
public void followInBackground(String userObjectId, Map attributes,
final FollowCallback callback) {
if (!checkUserAuthentication(callback)) {
return;
}
String endPoint = AVPowerfulUtils.getFollowEndPoint(getObjectId(), userObjectId);
String paramsString = "";
if (attributes != null) {
paramsString = AVUtils.restfulServerData(attributes);
}
PaasClient.storageInstance().postObject(endPoint, paramsString, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
super.onSuccess(content, e); // To change body of overridden methods use File | Settings
// |
// File Templates.
if (callback != null) {
callback.internalDone(AVUser.this, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
super.onFailure(error, content); // To change body of overridden methods use File |
// Settings
// | File Templates.
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
});
}
public void unfollowInBackground(String userObjectId, final FollowCallback callback) {
if (!checkUserAuthentication(callback)) {
return;
}
String endPoint = AVPowerfulUtils.getFollowEndPoint(getObjectId(), userObjectId);
PaasClient.storageInstance().deleteObject(endPoint, false, new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
super.onSuccess(content, e); // To change body of overridden methods use File | Settings |
// File Templates.
if (callback != null) {
callback.internalDone(AVUser.this, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
super.onFailure(error, content); // To change body of overridden methods use File | Settings
// | File Templates.
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/*
* {"results":
* [{"objectId":"52bbd4f9e4b0be6d851ef395",
* "follower":{"className":"_User","objectId":"52bbd4f8e4b0be6d851ef394","__type":"Pointer"},
* "user":{"className":"_User","objectId":"52bbd4f3e4b0be6d851ef393","__type":"Pointer"},
* "createdAt":"2013-12-26T15:04:25.856Z", "updatedAt":"2013-12-26T15:04:25.856Z"},
* {"objectId":"52bbd4ffe4b0be6d851ef398",
* "follower":{"className":"_User","objectId":"52bbd4fee4b0be6d851ef397","__type":"Pointer"},
* "user":{"className":"_User","objectId":"52bbd4f3e4b0be6d851ef393","__type":"Pointer"},
* "createdAt":"2013-12-26T15:04:31.066Z", "updatedAt":"2013-12-26T15:04:31.066Z"} ] }
*/
private List processResultByTag(String content, String tag) {
List list = new LinkedList();
if (AVUtils.isBlankString(content)) {
return list;
}
AVFollowResponse resp = new AVFollowResponse();
resp = JSON.parseObject(content, resp.getClass());
processResultList(resp.results, list, tag);
return list;
}
private Map> processFollowerAndFollowee(String content) {
Map> map = new HashMap>();
if (AVUtils.isBlankString(content)) {
return map;
}
AVFollowResponse resp = new AVFollowResponse();
resp = JSON.parseObject(content, resp.getClass());
List followers = new LinkedList();
List followees = new LinkedList();
processResultList(resp.followers, followers, FOLLOWER_TAG);
processResultList(resp.followees, followees, FOLLOWEE_TAG);
map.put(FOLLOWER_TAG, followers);
map.put(FOLLOWEE_TAG, followees);
return map;
}
// TODO, consider subclass.
private void processResultList(Map[] results, List list, String tag) {
for (Map item : results) {
if (item != null && !item.isEmpty()) {
AVUser user = (AVUser) AVUtils.getObjectFrom(item.get(tag));
list.add(user);
}
}
}
/**
*
* 创建follower查询。请确保传入的userObjectId不为空,否则会抛出IllegalArgumentException。
* 创建follower查询后,您可以使用whereEqualTo("follower", userFollower)查询特定的follower。 您也可以使用skip和limit支持分页操作。
*
*
*
* @param userObjectId 待查询的用户objectId。
* @param clazz AVUser类或者其子类。
*
* @since 2.3.0
*/
static public AVQuery followerQuery(final String userObjectId,
Class clazz) {
if (AVUtils.isBlankString(userObjectId)) {
throw new IllegalArgumentException("Blank user objectId.");
}
AVFellowshipQuery query = new AVFellowshipQuery("_Follower", clazz);
query.whereEqualTo("user", AVUser.createWithoutData("_User", userObjectId));
query.setFriendshipTag(AVUser.FOLLOWER_TAG);
return query;
}
/**
*
* 创建follower查询。创建follower查询后,您可以使用whereEqualTo("follower", userFollower)查询特定的follower。
* 您也可以使用skip和limit支持分页操作。
*
*
*
* @param clazz AVUser类或者其子类。
* @since 2.3.0
*/
public AVQuery followerQuery(Class clazz) throws AVException {
if (AVUtils.isBlankString(this.getObjectId())) {
throw AVErrorUtils.sessionMissingException();
}
return followerQuery(getObjectId(), clazz);
}
/**
*
* 创建followee查询。请确保传入的userObjectId不为空,否则会抛出IllegalArgumentException。
* 创建followee查询后,您可以使用whereEqualTo("followee", userFollowee)查询特定的followee。 您也可以使用skip和limit支持分页操作。
*
*
*
* @param userObjectId 待查询的用户objectId。
* @param clazz AVUser类或者其子类。
*
* @since 2.3.0
*/
static public AVQuery followeeQuery(final String userObjectId,
Class clazz) {
if (AVUtils.isBlankString(userObjectId)) {
throw new IllegalArgumentException("Blank user objectId.");
}
AVFellowshipQuery query = new AVFellowshipQuery("_Followee", clazz);
query.whereEqualTo("user", AVUser.createWithoutData("_User", userObjectId));
query.setFriendshipTag(AVUser.FOLLOWEE_TAG);
return query;
}
/**
*
* 创建followee查询。 创建followee查询后,您可以使用whereEqualTo("followee", userFollowee)查询特定的followee。
* 您也可以使用skip和limit支持分页操作。
*
*
*
* @param clazz AVUser类或者其子类。
*
* @since 2.3.0
*/
public AVQuery followeeQuery(Class clazz) throws AVException {
if (AVUtils.isBlankString(this.getObjectId())) {
throw AVErrorUtils.sessionMissingException();
}
return followeeQuery(getObjectId(), clazz);
}
/**
* 获取用户好友关系的查询条件,同时包括用户的关注和用户粉丝
*
* @return
*/
public AVFriendshipQuery friendshipQuery() {
return this.friendshipQuery(subClazz == null ? AVUser.class : subClazz);
}
/**
* 获取用户好友关系的查询条件,同时包括用户的关注和用户粉丝
*
* @param clazz 最终返回的AVUser的子类
* @param
* @return
*/
public AVFriendshipQuery friendshipQuery(Class clazz) {
return new AVFriendshipQuery(this.objectId, clazz);
}
/**
* 获取用户好友关系的查询条件,同时包括用户的关注和用户粉丝
*
* @param userId AVUser的objectId
* @param
* @return
*/
public static AVFriendshipQuery friendshipQuery(String userId) {
return new AVFriendshipQuery(userId, subClazz == null ? AVUser.class : subClazz);
}
/**
* 获取用户好友关系的查询条件,同时包括用户的关注和用户粉丝
*
* @param userId AVUser的objectId
* @param clazz 指定的AVUser或者其子类
* @param
* @return
*/
public static AVFriendshipQuery friendshipQuery(String userId,
Class clazz) {
return new AVFriendshipQuery(userId, clazz);
}
@Deprecated
public void getFollowersInBackground(final FindCallback callback) {
if (!checkUserAuthentication(callback)) {
return;
}
String endPoint = AVPowerfulUtils.getFollowersEndPoint(getObjectId());
PaasClient.storageInstance().getObject(endPoint, null, false, null,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
super.onSuccess(content, e);
List list = processResultByTag(content, FOLLOWER_TAG);
if (callback != null) {
callback.internalDone(list, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
super.onFailure(error, content);
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
});
}
@Deprecated
public void getMyFolloweesInBackground(final FindCallback callback) {
if (!checkUserAuthentication(callback)) {
return;
}
String endPoint = AVPowerfulUtils.getFolloweesEndPoint(getObjectId());
PaasClient.storageInstance().getObject(endPoint, null, false, null,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
super.onSuccess(content, e);
List list = processResultByTag(content, FOLLOWEE_TAG);
if (callback != null) {
callback.internalDone(list, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
super.onFailure(error, content);
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
});
}
public void getFollowersAndFolloweesInBackground(final FollowersAndFolloweesCallback callback) {
if (!checkUserAuthentication(callback)) {
return;
}
String endPoint = AVPowerfulUtils.getFollowersAndFollowees(getObjectId());
PaasClient.storageInstance().getObject(endPoint, null, false, null,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
super.onSuccess(content, e);
Map> map = processFollowerAndFollowee(content);
if (callback != null) {
callback.internalDone(map, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
super.onFailure(error, content);
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
});
}
/*
* 通过这个方法可以将AVUser对象强转为其子类对象
*/
public static T cast(AVUser user, Class clazz) {
try {
T newUser = AVObject.cast(user, clazz);
return newUser;
} catch (Exception e) {
LogUtil.log.e("ClassCast Exception", e);
}
return null;
}
/**
*
* 通过设置此方法,所有关联对象中的AVUser对象都会被强转成注册的AVUser子类对象
*/
public static void alwaysUseSubUserClass(Class extends AVUser> clazz) {
subClazz = clazz;
}
private static Map authData(AVThirdPartyUserAuth userInfo) {
Map result = new HashMap();
Map map = new HashMap();
map.put(accessTokenTag, userInfo.accessToken);
map.put(expiresAtTag, userInfo.expiredAt);
if (!AVUtils.isBlankString(userInfo.snsType)) {
map.put(AVThirdPartyUserAuth.platformUserIdTag(userInfo.snsType), userInfo.userId);
}
result.put(userInfo.snsType, map);
return result;
}
/**
* 生成一个新的 AVUser,并且将AVUser与SNS平台获取的userInfo关联。
*
* @param userInfo 包含第三方授权必要信息的内部类
* @param callback 关联完成后,调用的回调函数。
*/
@Deprecated
static public void loginWithAuthData(AVThirdPartyUserAuth userInfo,
final LogInCallback callback) {
loginWithAuthData(AVUser.class, userInfo, callback);
}
/**
* 生成一个新的 AVUser,并且将AVUser与SNS平台获取的 authData 关联。
*
* @param authData 包含第三方授权必要信息,例如
* {
* "openid": "abc123",
* "access_token": "123abc",
* "expires_in": 1382686496
* }
* @param platform 平台名字,可以使用几个预定义的常量:
* AVUser.SNS_TENCENT_WEIBO - "qq"
* AVUser.SNS_SINA_WEIBO - "weibo"
* AVUser.SNS_TENCENT_WEIXIN - "weixin"
* 你也可以使用自定义的其他平台名字。
* @param callback 关联完成后,调用的回调函数。
* @since 4.5.3
*/
public static void loginWithAuthData(final Map authData, final String platform, final LogInCallback callback) {
loginWithAuthData(AVUser.class, authData, platform, callback);
}
public static void loginWithAuthData(final Map authData, final String platform,
final String unionId, final String unionIdPlatform, final boolean asMainAccount,
final LogInCallback callback) {
loginWithAuthData(AVUser.class, authData, platform, unionId, unionIdPlatform, asMainAccount, callback);
}
public static void loginWithAuthData(final Class clazz, final Map authData, final String platform,
final String unionId, final String unionIdPlatform, final boolean asMainAccount,
final LogInCallback callback) {
if (null == clazz) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. clazz must not null/empty."));
}
return;
}
if (null == authData || authData.isEmpty()) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. authdata must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(platform)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. platform must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(unionId)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. unionId must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(unionIdPlatform)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. unionIdPlatform must not null/empty."));
}
return;
}
authData.put(AUTHDATA_ATTR_UNIONID, unionId);
authData.put(AUTHDATA_ATTR_UNIONID_PLATFORM, unionIdPlatform);
if (asMainAccount) {
authData.put(AUTHDATA_ATTR_MAIN_ACCOUNT, asMainAccount);
}
loginWithAuthData(clazz, authData, platform, callback);
}
/**
* 生成一个新的 AVUser 子类化对象,并且将该对象与 SNS 平台获取的 authData 关联。
*
* @param clazz 子类化的 AVUe r的 class 对象
* @param authData 在 SNS 登录成功后,返回的 authData 信息,例如
* {
* "openid": "abc123",
* "access_token": "123abc",
* "expires_in": 1382686496
* }
* @param platform 平台名字,可以使用几个预定义的常量:
* AVUser.SNS_TENCENT_WEIBO - "qq"
* AVUser.SNS_SINA_WEIBO - "weibo"
* AVUser.SNS_TENCENT_WEIXIN - "weixin"
* 你也可以使用自定义的其他平台名字。
* @param callback 关联完成后,调用的回调函数。
* @since 4.5.3
*/
public static void loginWithAuthData(final Class clazz, final Map authData,
final String platform, final LogInCallback callback) {
if (null == clazz) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. clazz must not null/empty."));
}
return;
}
if (null == authData || authData.isEmpty()) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. authdata must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(platform)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. platform must not null/empty."));
}
return;
}
Map data = new HashMap();
Map authMap = new HashMap();
authMap.put(platform, authData);
data.put(authDataTag, authMap);
String jsonString = JSON.toJSONString(data);
PaasClient.storageInstance().postObject(AVUSER_ENDPOINT, jsonString, false, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (e == null) {
T userObject = AVUser.newAVUser(clazz, callback);
if (userObject == null) {
return;
}
AVUtils.copyPropertiesFromJsonStringToAVObject(content, userObject);
userObject.processAuthData(null);
if (platform.equals(SNS_SINA_WEIBO)) {
((AVUser)userObject).sinaWeiboToken = (String)authData.get(accessTokenTag);
} else if (platform.equals(SNS_TENCENT_WEIBO)) {
((AVUser)userObject).qqWeiboToken = (String)authData.get(accessTokenTag);
}
AVUser.changeCurrentUser(userObject, true);
if (callback != null) {
callback.internalDone(userObject, null);
}
}
}
@Override
public void onFailure(Throwable error, String content) {
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
public void loginWithAuthData(final Map authData, final String platform,
final String unionId, final String unionIdPlatform,
final boolean asMainAccount, final boolean failOnNotExist,
final LogInCallback callback) {
if (null == authData || authData.isEmpty()) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. authdata must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(unionId)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. unionId must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(unionIdPlatform)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. unionIdPlatform must not null/empty."));
}
return;
}
authData.put(AUTHDATA_ATTR_UNIONID, unionId);
authData.put(AUTHDATA_ATTR_UNIONID_PLATFORM, unionIdPlatform);
if (asMainAccount) {
authData.put(AUTHDATA_ATTR_MAIN_ACCOUNT, asMainAccount);
}
loginWithAuthData(authData, platform, failOnNotExist, callback);
}
public void loginWithAuthData(final Map authData, final String platform,
final boolean failOnNotExist, final LogInCallback callback) {
if (null == authData || authData.isEmpty()) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. authdata must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(platform)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. platform must not null/empty."));
}
return;
}
Map userData = createUserMapAFAP(getUsername(), null, getEmail(), getMobilePhoneNumber(), null);
Map data = new HashMap<>();
Map authMap = new HashMap();
authMap.put(platform, authData);
if(!userData.isEmpty()) {
data.putAll(userData);
}
data.put(authDataTag, authMap);
String jsonString = JSON.toJSONString(data);
String path = failOnNotExist ? AVUSER_ENDPOINT_FAILON : AVUSER_ENDPOINT;
PaasClient.storageInstance().postObject(path, jsonString, false, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (e == null) {
AVUtils.copyPropertiesFromJsonStringToAVObject(content, AVUser.this);
AVUser.this.processAuthData(null);
if (platform.equals(SNS_SINA_WEIBO)) {
AVUser.this.sinaWeiboToken = (String)authData.get(accessTokenTag);
} else if (platform.equals(SNS_TENCENT_WEIBO)) {
AVUser.this.qqWeiboToken = (String)authData.get(accessTokenTag);
}
AVUser.changeCurrentUser(AVUser.this, true);
if (callback != null) {
callback.internalDone(AVUser.this, null);
}
}
}
@Override
public void onFailure(Throwable error, String content) {
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* 生成一个新的AVUser子类化对象,并且将该对象与SNS平台获取的userInfo关联。
*
* @param clazz 子类化的AVUer的class对象
* @param userInfo 在SNS登录成功后,返回的userInfo信息。
* @param callback 关联完成后,调用的回调函数。
* @since 1.4.4
*/
@Deprecated
public static void loginWithAuthData(final Class clazz,
final AVThirdPartyUserAuth userInfo, final LogInCallback callback) {
if (userInfo == null) {
if (callback != null) {
callback.internalDone(null,
AVErrorUtils.createException(AVException.OTHER_CAUSE, "NULL userInfo."));
}
return;
}
Map data = new HashMap();
data.put(authDataTag, authData(userInfo));
String jsonString = JSON.toJSONString(data);
PaasClient.storageInstance().postObject(AVUSER_ENDPOINT, jsonString, false, false,
new GenericObjectCallback() {
@Override
public void onSuccess(String content, AVException e) {
if (e == null) {
T userObject = AVUser.newAVUser(clazz, callback);
if (userObject == null) {
return;
}
AVUtils.copyPropertiesFromJsonStringToAVObject(content, userObject);
userObject.processAuthData(userInfo);
AVUser.changeCurrentUser(userObject, true);
if (callback != null) {
callback.internalDone(userObject, null);
}
}
}
@Override
public void onFailure(Throwable error, String content) {
if (callback != null) {
callback.internalDone(null, AVErrorUtils.createException(error, content));
}
}
}, null, null);
}
/**
* 将现存的AVUser与从SNS平台获取的userInfo关联起来。
*
* @param user AVUser 对象。
* @param userInfo 在SNS登录成功后,返回的userInfo信息。
* @param callback 关联完成后,调用的回调函数。
* @since 1.4.4
*/
@Deprecated
static public void associateWithAuthData(AVUser user, AVThirdPartyUserAuth userInfo,
final SaveCallback callback) {
if (userInfo == null) {
if (callback != null) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE,
"NULL userInfo."));
}
return;
}
Map authData = authData(userInfo);
if (user.get(authDataTag) != null && user.get(authDataTag) instanceof Map) {
authData.putAll((Map) user.get(authDataTag));
}
user.put(authDataTag, authData);
user.markAnonymousUserTransfer();
user.saveInBackground(callback);
}
/**
* 将现存的 AVUser 与从 SNS 平台获取的 authData 关联起来。
*
* @param authData 在 SNS 登录成功后,返回的 authData 信息,例如
* {
* "openid": "abc123",
* "access_token": "123abc",
* "expires_in": 1382686496
* }
* @param platform 平台名字,可以使用几个预定义的常量:
* AVUser.SNS_TENCENT_WEIBO - "qq"
* AVUser.SNS_SINA_WEIBO - "weibo"
* AVUser.SNS_TENCENT_WEIXIN - "weixin"
* 你也可以使用自定义的其他平台名字。
* @param callback 关联完成后,调用的回调函数。
* @since 4.5.3
*/
public void associateWithAuthData(Map authData, String platform, final SaveCallback callback) {
if (null == authData || authData.isEmpty()) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. authdata must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(platform)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. platform must not null/empty."));
}
return;
}
Map authDataAttr = new HashMap();
authDataAttr.put(platform, authData);
Object existedAuthData = this.get(authDataTag);
if (existedAuthData != null && existedAuthData instanceof Map) {
authDataAttr.putAll((Map)existedAuthData);
}
this.put(authDataTag, authDataAttr);
this.markAnonymousUserTransfer();
this.saveInBackground(callback);
}
public void associateWithAuthData(Map authData, String platform, String unionId, String unionIdPlatform,
boolean asMainAccount, final SaveCallback callback) {
if (null == authData || authData.isEmpty()) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. authdata must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(platform)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. platform must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(unionId)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. unionId must not null/empty."));
}
return;
}
if (StringUtils.isBlankString(unionIdPlatform)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. unionIdPlatform must not null/empty."));
}
return;
}
authData.put(AUTHDATA_ATTR_UNIONID, unionId);
authData.put(AUTHDATA_ATTR_UNIONID_PLATFORM, unionIdPlatform);
if (asMainAccount) {
authData.put(AUTHDATA_ATTR_MAIN_ACCOUNT, true);
}
this.associateWithAuthData(authData, platform, callback);
}
/**
* 解除 AVUser 与从 SNS 平台获取的 authData 之间的关联。
*
* @param platform 平台名字,可以使用几个预定义的常量:
* AVUser.SNS_TENCENT_WEIBO - "qq"
* AVUser.SNS_SINA_WEIBO - "weibo"
* AVUser.SNS_TENCENT_WEIXIN - "weixin"
* 你也可以使用自定义的其他平台名字。
* @param callback 关联完成后,调用的回调函数。
* @since 4.5.3
*/
public void dissociateAuthData(final String platform, final SaveCallback callback) {
if (AVUtils.isBlankString(platform)) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. platform must not null/empty."));
}
return;
}
this.remove(authDataTag + "." + platform);
if (this.isAuthenticated() && !AVUtils.isBlankString(getObjectId())) {
this.saveInBackground(new SaveCallback() {
@Override
public void done(AVException e) {
if (null == e) {
Map authData = (Map) AVUser.this.get(authDataTag);
if (authData != null) {
authData.remove(platform);
}
processAuthData(new AVThirdPartyUserAuth(null, null, platform, null));
}
if (null != callback) {
callback.internalDone(e);
}
}
});
} else {
if (null != callback) {
callback.internalDone(new AVException(AVException.SESSION_MISSING,
"the user object missing a valid session"));
}
}
}
@Deprecated
static public void dissociateAuthData(final AVUser user, final String platform,
final SaveCallback callback) {
if (null == user) {
if (null != callback) {
callback.internalDone(AVErrorUtils.createException(AVException.OTHER_CAUSE, "illegal parameter. user must not be null."));
}
return;
}
user.dissociateAuthData(platform, callback);
}
protected void processAuthData(AVThirdPartyUserAuth auth) {
Map authData = (Map) this.get(authDataTag);
// 匿名用户转化为正式用户
if (needTransferFromAnonymousUser) {
if (authData != null && authData.containsKey(anonymousTag)) {
authData.remove(anonymousTag);
} else {
anonymous = false;
}
needTransferFromAnonymousUser = false;
}
if (authData != null) {
if (authData.containsKey(SNS_SINA_WEIBO)) {
Map sinaAuthData =
(Map) authData.get(SNS_SINA_WEIBO);
this.sinaWeiboToken = (String) sinaAuthData.get(accessTokenTag);
} else {
this.sinaWeiboToken = null;
}
if (authData.containsKey(SNS_TENCENT_WEIBO)) {
Map qqAuthData =
(Map) authData.get(SNS_TENCENT_WEIBO);
this.qqWeiboToken = (String) qqAuthData.get(accessTokenTag);
} else {
this.qqWeiboToken = null;
}
if (authData.containsKey(anonymousTag)) {
this.anonymous = true;
} else {
this.anonymous = false;
}
}
if (auth != null) {
if (auth.snsType.equals(SNS_SINA_WEIBO)) {
sinaWeiboToken = auth.accessToken;
return;
}
if (auth.snsType.equals(SNS_TENCENT_WEIBO)) {
qqWeiboToken = auth.accessToken;
return;
}
}
}
@Deprecated
public static class AVThirdPartyUserAuth {
String accessToken;
String expiredAt;
String snsType;
String userId;
public static final String SNS_TENCENT_WEIBO = "qq";
public static final String SNS_SINA_WEIBO = "weibo";
public static final String SNS_TENCENT_WEIXIN = "weixin";
public AVThirdPartyUserAuth(String accessToken, String expiredAt, String snstype, String userId) {
this.accessToken = accessToken;
this.snsType = snstype;
this.expiredAt = expiredAt;
this.userId = userId;
}
protected static String platformUserIdTag(String type) {
if (SNS_TENCENT_WEIBO.equalsIgnoreCase(type) || SNS_TENCENT_WEIXIN.equalsIgnoreCase(type)) {
return "openid";
} else {
return "uid";
}
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getExpireAt() {
return expiredAt;
}
public void setExpireAt(String expireAt) {
this.expiredAt = expireAt;
}
public String getSnsType() {
return snsType;
}
public void setSnsType(String snsType) {
this.snsType = snsType;
}
}
private void markAnonymousUserTransfer() {
if (isAnonymous()) {
needTransferFromAnonymousUser = true;
}
}
public static transient final Creator CREATOR = AVObjectCreator.instance;
}