目录

Drive Kit Manual Conversion Guide

Preparations

If you want your app to support Drive Kit, complete the integration preparation by referring to Preparations.

Sign-in Method Change

HMS implements sign-in using HUAWEI IDs and obtains authentication information and certificates. The process of obtaining an HMS credential is different from that of Google APIs. Manual conversion is required.

The following provides the sample code for obtaining unionId and accessToken during HMS sign-in to generate a credential. You can modify your code according to the sample.

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 sample code:

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

Character String Replacement

[h2]Replacement of mimeType Field Values in Files

Search for all application/vnd.google-apps.folder character strings in your app project and replace them with application/vnd.huawei-apps.folder.

[h2]Replacement of the Folder Query Parameter "in parents"

For file query, replace parentFileId + "in parents" with parentFileId + "in parentFolder" based on file name sorting.

  1. For query of files and folders in the root directory of a cloud drive, replace parentFileId with 'root'.

  2. For query of files and folders in the root directory of a non-cloud drive, parentFileId (needs to be enclosed in single quotation marks, for example, 'AgMhP8hcDTQDvvVzWeHZeJIO9X9Z7A04A') is a real directory ID.

[h2]File Sorting Parameter – File Name Replacement

For file query, replace "name" with "fileName" based on file name sorting.

[h2]File Sorting Parameter – Modification Time Replacement

For file query, replace "modifiedTime" with "editedTime" based on modification time sorting.

[h2]File Query Parameter – Recycle Bin Identifier Replacement

For file query, replace "trashed" with "recycled" based on recycle bin identifier filtering.

[h2]Query Range Parameter Replacement

Replace "appDataFolder" with "applicationData".

Drive Instantiation

The Drive builder in Google APIs is different from that in HMS and needs to be manually replaced.

Credential information needs to be initialized during sign-in for Drive building. For details about how to initialize credential information through HMS and Google APIs, please refer to Sign-in Method Change.

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)

For details about the implementation, please refer to Drive.

Google API sample code:
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();    
    }
}

Sample code of the replacement 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();
}

Drive.Builder Instantiation

The Drive.Builder builder in Google APIs is different from that in HMS and needs to be manually replaced.

Credential information needs to be initialized during sign-in for Drive.Builder building. For details about how to initialize credential information through HMS and Google APIs, please refer to Sign-in Method Change.

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)

For details about the implementation, please refer to Drive.Builder.

Google API sample code:

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 sample code:

public Drive.Builder getBuilder(Context context) {
    DriveCredential credential = CredentialManager.getInstance().getCredential();
    if (credential == null || context == null) {     
        return null;
    }
    return new Drive.Builder(credential, context);
}

setMd5Checksum(java.lang.String) Replacement Method

Method 1: Delete setMd5Checksum(java.lang.String) because the server can automatically generate an SHA-256 value, without need for you to set it on the app.

Method 2: Replace setMd5Checksum(java.lang.String) with setSha256(java.lang.String sha256) as follows:

Google API sample code:

String md5Checksum = "******************";
***.setMd5Checksum(md5Checksum);

Sample code of the replacement HMS API:

// Use the standard SHA-256 algorithm to calculate a value and set the value through the SHA-256 attribute.
String sha256 = "******************";
***.setSha256(sha256);

setUserIp(java.lang.String) Replacement Method

The setUserIp(java.lang.String) method in the com.google.api.services.drive.DriveRequest<T> class and its subclasses is replaced as follows.

Google API sample code:

Drive drive;  // You can initialize this variable by referring to Drive Instantiation.
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());
}

Sample code of the replacement HMS API:

Drive drive;  // You can initialize this variable by referring to Drive Instantiation.
Drive.About about = drive.about();
Drive.About.Get request = null;
try {    
    request = about.get();
    // A user-defined function generates a string of fewer 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());
}

Permission.setEmailAddress(java.lang.String emailAddress) Replacement Method

Google API sample code:

Permission permission = new Permission();
permission.setEmailAddress("example@***.com");

Sample code of the replacement HMS API:

Permission permission = new Permission();
permission.setUserAccount("example@***.com");
/** 
 * Set an account type. For details, please refer to Permission.setAccountType().
 * Currently, the options are 0 (default value), 1 (email), and 2 (phone number).
 */
permission.setAccountType("1");