HMS使用华为帐号进行登录,并以此获取鉴权信息、证书等。获取HMS Credential的过程与Google API相差较大,需要手动转换。
下面提供了HMS登录阶段获取unionId、accessToken来生成Credential的示例代码,您可以参考代码进行修改。
Google API:
public class DriveQuickstart {
private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE_METADATA_READONLY);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
* @param HTTP_TRANSPORT The network HTTP Transport.
* @return An authorized Credential object.
* @throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = DriveQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
} HMS API示例代码:
public class LoginActivity extends Activity implements View.OnClickListener {
private static DriveCredential.AccessMethod refreshAT = new DriveCredential.AccessMethod() {
@Override
public String refreshToken() {
return HmsProxyImpl.getInstance().refreshAccessToken();
}
};
@Override
public void onClick(View v) {
if (R.id.account_login_button == v.getId()) {
HmsProxyImpl.getInstance().signIn(this);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case HmsProxyImpl.REQUEST_SIGN_IN_LOGIN:
com.huawei.hmf.tasks.Task<AuthHuaweiId> signInHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data);
if (signInHuaweiIdTask.isSuccessful()) {
AuthHuaweiId huaweiAccount = signInHuaweiIdTask.getResult();
HmsProxyImpl.getInstance().dealSignInResult(huaweiAccount);
initDrive();
} else {
finish();
}
break;
default:
break;
}
}
private void initDrive() {
final String unionID = HmsProxyImpl.getInstance().getUnionId();
final String at = HmsProxyImpl.getInstance().getAccessToken();
TaskManager.getInstance().execute(new Task() {
@Override
public void call() {
int returnCode = CredentialManager.getInstance().init(unionID, at, refreshAT);
// go to the main activity
....
}
});
}
}
public class HmsProxyImpl {
private HuaweiIdAuthParams signInOptions;
private static HmsProxyImpl instance = new HmsProxyImpl();
public static final int REQUEST_SIGN_IN_LOGIN = 1002;
private ReentrantLock getATLock = new ReentrantLock();
private HuaweiIdAuthService client;
private String accessToken;
private String unionId;
private Activity activity;
private HmsProxyImpl() {
signInOptions = initData();
}
public static HmsProxyImpl getInstance() {
return instance;
}
private HuaweiIdAuthParams initData() {
List<Scope> scopeList = new LinkedList<>(Arrays.asList(
HuaweiIdAuthAPIManager.HUAWEIID_BASE_SCOPE,
new Scope(DriveScopes.SCOPE_DRIVE),
new Scope(DriveScopes.SCOPE_DRIVE_METADATA),
new Scope(DriveScopes.SCOPE_DRIVE_FILE),
new Scope(DriveScopes.SCOPE_DRIVE_APPDATA)));
HuaweiIdAuthParams authParams = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setScopeList(scopeList)
.setIdToken()
.setAccessToken()
.createParams();
return authParams ;
}
public void signIn(Activity activity) {
this.activity = activity;
if (signInOptions == null) {
signInOptions = initData();
}
client = HuaweiIdAuthManager.getService(activity, signInOptions);
activity.startActivityForResult(client.getSignInIntent(), REQUEST_SIGN_IN_LOGIN);
}
public String refreshAccessToken() {
try {
if (client != null) {
getATLock.lock();
try {
getAT();
} finally {
getATLock.unlock();
}
}
} catch (Exception e) {
// deal Exception
}
return accessToken;
}
private void getAT() {
for (int retry = 0; retry < 2; retry++) {
if (signInBackend()) {
break;
}
}
}
private boolean signInBackend(){
clearAccountInfo();
final CountDownLatch countDownLatch = new CountDownLatch(1);
com.huawei.hmf.tasks.Task<AuthHuaweiId> task = client.silentSignIn();
task.addOnSuccessListener(new OnSuccessListener<AuthHuaweiId>() {
@Override
public void onSuccess(AuthHuaweiId signInHuaweiId) {
dealSignInResult(signInHuaweiId);
countDownLatch.countDown();
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
countDownLatch.countDown();
}
});
try {
countDownLatch.await(15, TimeUnit.SECONDS);
}catch (InterruptedException e) {
countDownLatch.countDown();
}
if (TextUtils.isEmpty(getAccessToken())) {
return false;
} else {
return true;
}
}
public void dealSignInResult(AuthHuaweiId huaweiAccount){
String tempAt = huaweiAccount.getAccessToken();
if (null == tempAt || tempAt.isEmpty()) {
return;
}
saveAccountInfo(huaweiAccount);
}
private void saveAccountInfo(AuthHuaweiId signInHuaweiId) {
if (signInHuaweiId == null) {
return;
}
unionId = signInHuaweiId.getUnionId();
accessToken = signInHuaweiId.getAccessToken();
}
private void clearAccountInfo() {
unionId = null;
accessToken = null;
}
public String getAccessToken() {
return this.accessToken;
}
public String getUnionId() {
return unionId;
}
}
public class CredentialManager {
/**
* Drive credential authorization
*/
private DriveCredential mCredential;
private CredentialManager() {
}
private static class InnerHolder {
private static CredentialManager sInstance = new CredentialManager();
}
public static CredentialManager getInstance() {
return InnerHolder.sInstance;
}
/**
* init the drive sdk with access token and HwId Account info,
* register a AccessMethod to get a new accessToken while accessToken is expired.
*
* @param unionID unionID from HwID
* @param at access token
* @param refreshAT a callback to refresh AT
*/
public int init(String unionID, String at, DriveCredential.AccessMethod refreshAT) {
if (StringUtils.isNullOrEmpty(unionID) || StringUtils.isNullOrEmpty(at)) {
return DriveCode.ERROR;
}
DriveCredential.Builder builder = new DriveCredential.Builder(unionID, refreshAT);
mCredential = builder.build().setAccessToken(at);
return DriveCode.SUCCESS;
}
public DriveCredential getCredential() {
return mCredential;
}
} 全量搜索App项目中的“application/vnd.google-apps.folder”字符串,将其替换为“application/vnd.huawei-apps.folder”,如下:

查询文件时候,通过文件名排序,将parentFileId + “in parents”替换为parentFileId + “in parentFolder”。
Google API中的Drive构造器跟HMS的完全不同,需要手工替换。
Drive的构造需要在登录时初始化Credential信息,HMS和Google API初始化Credential的内容请参见登录方式变更。
Google API | To HMS API |
|---|---|
Drive(com.google.api.client.http.HttpTransport transport, com.google.api.client.json.JsonFactory jsonFactory, com.google.api.client.http.HttpRequestInitializer httpRequestInitializer) | public Drive(com.huawei.cloud.base.auth.DriveCredential credential, android.content.Context context) |
具体实现请参见Drive。
public class DriveQuickstart {
private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE_METADATA_READONLY);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
* @param HTTP_TRANSPORT The network HTTP Transport.
* @return An authorized Credential object.
* @throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = DriveQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
}
} 替换成的HMS API示例:
public Drive buildDrive(Context context) {
DriveCredential credential = CredentialManager.getInstance().getCredential();
if (credential == null || context == null) {
return null;
}
return new Drive.Builder(credential, context).build();
} Google API中的Drive.Builder构造器跟HMS的完全不同,需要手工替换。
Drive.Builder的构造需要在登录时初始化Credential信息,HMS和Google API初始化credential的内容请参见登录方式变更。
Google API | To HMS API |
|---|---|
public Builder(com.google.api.client.http.HttpTransport transport, com.google.api.client.json.JsonFactory jsonFactory, com.google.api.client.http.HttpRequestInitializer httpRequestInitializer) | public Builder(com.huawei.api.huaweiapis.auth.DriveCredential credential, android.content.Context context) |
具体实现请参见Drive.Builder。
Google API示例:
public class DriveQuickstart {
private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE_METADATA_READONLY);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
* @param HTTP_TRANSPORT The network HTTP Transport.
* @return An authorized Credential object.
* @throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = DriveQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Drive.Builder builder= new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT));
}
} HMS API示例:
public Drive.Builder getBuilder(Context context) {
DriveCredential credential = CredentialManager.getInstance().getCredential();
if (credential == null || context == null) {
return null;
}
return new Drive.Builder(credential, context);
} 方法一:直接删除,因为客户端可以不主动设置Sha256的值,服务器会自动生成。
方法二:用setSha256(java.lang.String sha256)替换,如下:
Google API 示例:
String md5Checksum = "******************"; ***.setMd5Checksum(md5Checksum);
替换后的HMS API 示例:
// 使用标准的Sha256算法计算出一个值,并通过Sha256属性进行设置。 String sha256 = "******************"; ***.setSha256(sha256);
com.google.api.services.drive.DriveRequest<T>类及其子类中的setUserIp(java.lang.String)方法替代如下:
Google API示例:
Drive drive; // 该变量由您初始化,可以参见Drive实例化 Drive.About about = drive.about(); Drive.About.Get request = null; try { request = about.get(); request.setUserIp("10.12.10.1");} catch (IOException e) { Log.e(TAG, "about.get() failed, exception: " + e.toString()); }
替换后的HMS API示例:
Drive drive; // 该变量由您初始化,可以参见Drive实例化 Drive.About about = drive.about(); Drive.About.Get request = null; try { request = about.get(); // A user-defined function generates a string of less than 40 characters,which is used to represent the user, and the string generated by each user cannot be repeated String quotaId = StringUtil.randomString(); request.setQuotaId(quotaId);} catch (IOException e) { Log.e(TAG, "about.get() failed, exception: " + e.toString()); }
Google API示例:
Permission permission = new Permission();
permission.setEmailAddress("example@***.com"); 替换后的HMS API示例:
Permission permission = new Permission();
permission.setUserAccount("example@***.com");
/**
* 设置帐号类型,详情请参见Permission.setAccountType()指南。
* 目前枚举值有"0"、"1"、"2"("0"对应default、"1"对应email、"2"对应phoneNo)。
*/
permission.setAccountType("1");