What Is AppGallery Connect Cloud DB Service

AppGallery Connect (AGC) Cloud DB Service provides collaborative management of device-cloud data, unified data models, and abundant data management APIs. It ensures data availability, reliability, consistency, and security, implements seamless data synchronization between the client and cloud, and provides offline support for applications, helping developers quickly build device-cloud and multi-device collaborative applications.

What Will You Create

In this codelab, you will create an Android application based on the AGC Cloud DB. Your application will be able to add, modify, and delete data, and synchronize between the device and cloud.

What Will You Learn

Development Environment and Skill Requirements

Device Requirements

Prepare a device running Android 4.4 or later version.

To integrate the AGC Cloud DB service, you need to complete the following preparations:

For details, please refer to Configuring App Information in AppGallery Connect.

Enabling the CloudDB Service

Before integrating the Cloud DB SDK, you need to enable the Cloud DB service. The procedure is as follows:

  1. Sign in to AppGallery Connect and click My projects.
  2. In the project list, select the project for which you want to enable the Cloud DB service.
  3. In the navigation tree, choose Build > Cloud DB.
  4. Click Enable now to enable the Cloud DB service.
  5. Set Data storage location as prompted.
  6. Click OK.

Integrating Cloud DB SDK

If you are using Android Studio, you need to integrate the Cloud DB SDK into your Android Studio project before development.

  1. Sign in to AppGallery Connect and click My projects.
  2. Click your project from the project list.
  3. Go to Project settings > General information. In the App information area, download the agconnect-services.json file.
  4. Copy the agconnect-services.json file to the app directory of the project.
  5. Open the build.gradle file in your app's module directory and add the following code to integrate the Cloud DB SDK:
    dependencies { // Add the Cloud DB SDK. implementation 'com.huawei.agconnect:agconnect-cloud-database:1.4.7.300' }
  6. Open the Android Studio application-level build.gradle file and set the Java source code compatibility mode to JDK1.8.
    compileOptions { sourceCompatibility = 1.8 targetCompatibility = 1.8 }
  1. You can create two screen layouts in the Android Studio project in this codelab.
    • Screen 1 is the Home screen for data operation.
    • Screen 2 is the About me screen for user login management.
  2. New functions are as follows:
    • AppGallery Connect user login
    • Data query
    • Data addition
    • Data modification
    • Data deletion
    • Data sorting
  3. You can refer to the following figure to design the UI and develop a book management application.

The sample code in this codelab uses the anonymous sign-in mode. Therefore, you need to enable the anonymous account authentication mode of Auth Service in AGC. Otherwise, the sign-in fails.

  1. Sign in to AppGallery Connect and click My projects.
  2. Click your project from the project list.
  3. Choose Build > Auth Service.
  4. If it is the first time that you use Auth Service, click Enable now in the upper right corner.
  5. On the Authentication mode tab page, click Enable in the Operation column corresponding to Anonymous account.
  6. Add the following build dependencies to the application-level build.gradle file (usually in the app directory) to integrate the AGConnect Auth:
    implementation 'com.huawei.agconnect:agconnect-auth:1.5.0.300'
  7. Call the authetication service methods in OnCreate of HomePageFragment. The sample code for anonymous authentication is as follows (before using the Cloud DB functions, ensure that the anonymous login is successful):
    public void login() { AGConnectAuth auth = AGConnectAuth.getInstance(); auth.signInAnonymously().addOnSuccessListener(mActivity, signInResult -> { Log.w(TAG, "addOnSuccessListener: " + signInResult.getUser().getDisplayName()); for (OnLoginEventCallBack loginEventCallBack : mLoginCallbacks) { loginEventCallBack.onLogin(true, signInResult); } }).addOnFailureListener(mActivity, e -> { Log.w(TAG, "sign in for agc failed: " + e.getMessage()); for (OnLoginEventCallBack loginEventCallBack : mLoginCallbacks) { loginEventCallBack.onLogOut(false); } }); }
  1. Sign in to AppGallery Connect and click My projects.
  2. Select a project from the project list and click an app for which you need to add an object type.
  3. In the navigation tree, choose Build > Cloud DB.
  4. Click Add to go to the object type creation page.
  5. Set Object Type Name to BookInfo, and click Next.
  6. Click , add the following fields, and click Next.
    Field Name TypePrimary KeyNot NullEncryptionDefault Value
    idInteger
    bookNameString
    authorString
    priceDouble
    publisherString
    publishTimeDate
    shadowFlagBooleantrue
  7. Click , set Index Name to bookName and Index Field to bookName, and click Next.
  8. Set role permissions as follows and click Next.
    Role queryupsertdelete
    Everyone
    Authenticated users
    Data creator
    Administrator
  9. Click OK. The created object types are displayed in the object type list.
  10. Click Export.
  11. Set the format of the file to be exported to JAVA.
  12. Set the Java file type to Android.
  13. Enter the package name com.huawei.agc.clouddb.quickstart.model, that is, the package name in the Java file.
  14. Click Export. The file is exported to the local PC. The file contains all the object type files and object type information files of the version. The exported Java file will be added to the local development environment in subsequent steps.
  1. Sign in to AppGallery Connect and click My projects.
  2. Select a project from the project list and click an app for which you need to add a Cloud DB zone.
  3. In the navigation tree, choose Build > Cloud DB.
  4. Click the Cloud DB Zones tab.
  5. Click Add to go to the Cloud DB zone creation page.
  6. Enter QuickStartDemo in the Cloud DB Zone Name text box.
  7. Click OK.

During application development, you can directly add the JAVA files exported from the AGC console to the local development environment, and use the createObjectType() method in the AGConnectCloudDB class to define and create object types. Then you do not need to create object types for local application development.
Add all exported files to the local development environment. If the files exist, replace them. The file is stored in the < agc-clouddb-demo-java >/app/src/main/java/com/huawei/agc/clouddb/quickstart/model directory.

After adding the object type file, you can use the Cloud DB for application development. Before developing an application, you need to initialize AGConnectCloudDB and create a Cloud DB zone and object type. The key code for each initialization step is as follows:

  1. Initialize AGConnectCloudDB in the application.
    public static void initAGConnectCloudDB(Context context) { AGConnectCloudDB.initialize(context); }
  2. Obtain an AGConnectCloudDB instance and create an object type.
    public CloudDBZoneWrapper() { mCloudDB = AGConnectCloudDB.getInstance(); } public void createObjectType() { try { mCloudDB.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo()); } catch (AGConnectCloudDBException e) { Log.w(TAG, "createObjectType: " + e.getMessage()); } }
  3. Create a Cloud DB zone configuration object and open the Cloud DB zone.
    public void openCloudDBZoneV2() { mConfig = new CloudDBZoneConfig("QuickStartDemo", CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE, CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC); mConfig.setPersistenceEnabled(true); Task<CloudDBZone> openDBZoneTask = mCloudDB.openCloudDBZone2(mConfig, true); openDBZoneTask.addOnSuccessListener(new OnSuccessListener<CloudDBZone>() { @Override public void onSuccess(CloudDBZone cloudDBZone) { Log.w(TAG, "open clouddbzone success"); mCloudDBZone = cloudDBZone; // Add subscription after opening cloudDBZone success addSubscription(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.w(TAG, "open clouddbzone failed for " + e.getMessage()); } }); }

This section mainly describes how to write data to an application using the Cloud DB SDK. On the application screen, the Add button is added for users to add data and use executeUpsert() to write data in the CloudDBZoneWrapper. The executeUpsert() method is encapsulated. You can directly use the upsertBookInfos() method to write data. The key code is as follows:

public void upsertBookInfos(BookInfo bookInfo) { if (mCloudDBZone == null) { Log.w(TAG, "CloudDBZone is null, try re-openit"); return; } Task upsertTask = mCloudDBZone.executeUpsert(bookInfo); upsertTask.addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Integer cloudDBZoneResult) { Log.w(TAG, "upsert " + cloudDBZoneResult + " records"); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { mUiCallBack.updateUiOnError("Insert book info failed"); } }); }

}

This section describes how to view data in an application, including displaying all data and obtaining updated data.

Displaying All Data

All data is displayed each time you enter the main screen of the application. Call executeQuery(). Set the first parameter to CloudDBZoneQuery.where(BookInfo.class). When the query is successful, execute addOnSuccessListener(). All queried data is transferred through the snapshot parameter. The key code is as follows:

public void queryAllBooks() { if (mCloudDBZone == null) { Log.w(TAG, "CloudDBZone is null, try re-open it"); return; } Task> queryTask = mCloudDBZone.executeQuery( CloudDBZoneQuery.where(BookInfo.class), CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY); queryTask.addOnSuccessListener(new OnSuccessListener>() { @Override public void onSuccess(CloudDBZoneSnapshot snapshot) { processQueryResult(snapshot); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { mUiCallBack.updateUiOnError("Query book list from cloud failed"); } }); }

Obtaining and Displaying the Updated Data

Data added by users on the application screen will be synchronized to the cloud. You can add a listener on the device to listen to the objects that meet the conditions. When the object data that meets the conditions changes, the data is pushed to the device. The device can receive the changed object data in the listener callback.
When the application is started, you can use the subscribeSnapshot() method to register the listening of data changes and use the listener mSnapshotListener to obtain data changes in real time.

public void addSubscription() { if (mCloudDBZone == null) { Log.w(TAG, "CloudDBZone is null, try re-open it"); return; } try { CloudDBZoneQuery snapshotQuery = CloudDBZoneQuery.where(BookInfo.class) .equalTo(BookEditFields.SHADOW_FLAG, true); mRegister = mCloudDBZone.subscribeSnapshot(snapshotQuery, CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY, mSnapshotListener); } catch (AGConnectCloudDBException e) { Log.w(TAG, "subscribeSnapshot: " + e.getMessage()); } }

Obtain the updated data by defining the listener mSnapshotListener. You can use getSnapshotObjects() to obtain the latest data, use next() to traverse specific objects, and use mUiCallBack.onSubscribe(bookInfos) to update the UI.

private OnSnapshotListener mSnapshotListener = new OnSnapshotListener() { @Override public void onSnapshot(CloudDBZoneSnapshot cloudDBZoneSnapshot, AGConnectCloudDBException e) { if (e != null) { Log.w(TAG, "onSnapshot: " + e.getMessage()); return; } CloudDBZoneObjectList snapshotObjects = cloudDBZoneSnapshot.getSnapshotObjects(); List bookInfos = new ArrayList<>(); try { if (snapshotObjects != null) { while (snapshotObjects.hasNext()) { BookInfo bookInfo = snapshotObjects.next(); bookInfos.add(bookInfo); updateBookIndex(bookInfo); } } mUiCallBack.onSubscribe(bookInfos); } catch (AGConnectCloudDBException snapshotException) { Log.w(TAG, "onSnapshot:(getObject) " + snapshotException.getMessage()); } finally { cloudDBZoneSnapshot.release(); } } };

In this section, we'll focus on how to sort data and filter queries in an application.

Sorting Data

On the application screen, click titles such as the book name, author, and unit price to sort existing data. Use orderByAsc() to sort data in ascending order and orderByDesc() to sort data in descending order. The input parameter is the field name in the column, for example, BookEditFields .BOOK_NAME. The key code is as follows:

private void queryWithOrder() { invalidateViewInNormalMode(); CloudDBZoneQuery<BookInfo> query = CloudDBZoneQuery.where(BookInfo.class); if (!mQueryInfo.bookName.isEmpty()) { query.contains(BookEditFields.BOOK_NAME, mQueryInfo.bookName); } query.greaterThanOrEqualTo(BookEditFields.PRICE, mQueryInfo.lowestPrice); if (mQueryInfo.lowestPrice != mQueryInfo.highestPrice || mQueryInfo.lowestPrice != 0.0) { query.lessThanOrEqualTo(BookEditFields.PRICE, mQueryInfo.highestPrice); } if (mQueryInfo.showCount > 0) { query.limit(mQueryInfo.showCount); } if (mSortState.state == SortState.State.UP) { query.orderByAsc(mSortState.field); } else { query.orderByDesc(mSortState.field); } mHandler.post(() -> mCloudDBZoneWrapper.queryBooks(query)); }

Filtering Queries

The button is added to the application screen. Click the button to query a book. Filter and query data by book name, unit price range, and number of displayed records. Use the executeQuery() API to query data. The first parameter in executeQuery() is the query condition, and the second parameter is the data source to be queried. POLICY_QUERY_FROM_CLOUD_ONLY is used to query data on the cloud. The key code is as follows:

public void queryBooks(CloudDBZoneQuery<BookInfo> query) { if (mCloudDBZone == null) { Log.w(TAG, "CloudDBZone is null, try re-open it"); return; } Task<CloudDBZoneSnapshot<BookInfo>> queryTask = mCloudDBZone.executeQuery(query, CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY); queryTask.addOnSuccessListener(new OnSuccessListener<CloudDBZoneSnapshot<BookInfo>>() { @Override public void onSuccess(CloudDBZoneSnapshot<BookInfo> snapshot) { processQueryResult(snapshot); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { mUiCallBack.updateUiOnError("Query failed"); } }); }

The query parameter is used to set the query conditions, such as the book name, unit price range, and number of records to be displayed.

private void processSearchAction(Intent data) { CloudDBZoneQuery<BookInfo> query = CloudDBZoneQuery.where(BookInfo.class); String bookName = data.getStringExtra(BookEditFields.BOOK_NAME); if (!TextUtils.isEmpty(bookName)) { query.contains(BookEditFields.BOOK_NAME, bookName); mQueryInfo.bookName = bookName; } double lowestPrice = data.getDoubleExtra(BookEditFields.LOWEST_PRICE, 0); double highestPrice = data.getDoubleExtra(BookEditFields.HIGHEST_PRICE, 0); if (lowestPrice > highestPrice) { double temp = lowestPrice; lowestPrice = highestPrice; highestPrice = temp; } mQueryInfo.lowestPrice = lowestPrice; mQueryInfo.highestPrice = highestPrice; query.greaterThanOrEqualTo(BookEditFields.PRICE, lowestPrice); if (mQueryInfo.lowestPrice != mQueryInfo.highestPrice || mQueryInfo.lowestPrice != 0.0) { query.lessThanOrEqualTo(BookEditFields.PRICE, mQueryInfo.highestPrice); } int showCount = data.getIntExtra(BookEditFields.SHOW_COUNT, 0); if (showCount > 0) { query.limit(showCount); mQueryInfo.showCount = showCount; } toggleShowAllState(true); mHandler.post(() -> mCloudDBZoneWrapper.queryBooks(query)); }
  1. The related methods in OnCreate are as follows:
    @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); mActivity = (MainActivity) getActivity(); mHandler = new Handler(Looper.getMainLooper()); mBookInfoAdapter = new BookInfoAdapter(getContext()); mHandler.post(() -> { LoginHelper loginHelper = mActivity.getLoginHelper(); loginHelper.addLoginCallBack(this); loginHelper.login(); }); }
  1. Run the Android Studio project to generate an APK package and install the APK package on the two test mobile phones.
  2. Open the installed APK package and test the add, delete, modify, and query functions.
  3. Click + to add data to a mobile phone A.

  4. View the new data of mobile phone A on mobile phone B.

Congratulations! You have successfully built your first application that integrates the AGC Cloud DB service and learned how to build an application for device-cloud collaborative data management through the AGC Cloud DB.

For details about the APIs of AGC Cloud DB, see the Cloud DB API Reference.
Download the demo source code used in this codelab:

Source Code Download

Code copied