Sharing Data Using DataShareExtensionAbility

When to Use

If complex services are involved in cross-application data access, you can use DataShareExtensionAbility to start the application of the data provider to implement data access.

You need to implement flexible service logics via callbacks of the service provider.

Working Principles

There are two roles in DataShare:

Figure 1 Data sharing mechanism

dataShare

  • The DataShareExtensionAbility module, as the data provider, implements services related to data sharing between applications.

  • The DataShareHelper module, as the data consumer, provides APIs for accessing data, including adding, deleting, modifying, and querying data.

  • The data consumer communicates with the data provider via inter-process communication (IPC). The data provider can be implemented through a database or other data storage.

  • The ResultSet module is implemented through shared memory. Shared memory stores the result sets, and interfaces are provided to traverse result sets.

How to Develop

Data Provider Application Development (Only for System Applications)

DataShareExtensionAbility provides the following APIs. You can override these APIs as required.

  • onCreate: called by the server to initialize service logic when the DataShare client connects to the DataShareExtensionAbility server.

  • insert: called to insert data upon the request of the client. Data insertion must be implemented in this callback on the server.

  • update: called to update data upon the request of the client. Data update must be implemented in this callback on the server.

  • delete: called to delete data upon the request of the client. Data deletion must be implemented in this callback on the server.

  • query: called to query data upon the request of the client. Data query must be implemented in this callback on the server.

  • batchInsert: called to batch insert data upon the request of the client. Batch data insertion must be implemented in this callback on the server.

  • normalizeUri: converts the URI provided by the client to the URI used by the server.

  • denormalizeUri: converts the URI used by the server to the initial URI passed by the client.

Before implementing a DataShare service, you need to create a DataShareExtensionAbility object in the DevEco Studio project as follows:

  1. In the ets directory of the Module project, right-click and choose New > Directory to create a directory named DataShareExtAbility.

  2. Right-click the DataShareAbility directory, and choose New > TypeScript File to create a file named DataShareExtAbility.ts.

  3. Import @ohos.application.DataShareExtensionAbility and other dependencies to the DataShareExtAbility.ts file, and override the service implementation as required. For example, if the data provider provides only the data insertion, deletion, and query services, you can override only these APIs.

    import Extension from '@ohos.application.DataShareExtensionAbility';
    import rdb from '@ohos.data.relationalStore';
    import dataSharePredicates from '@ohos.data.dataSharePredicates';
    
  4. Implement the data provider services. For example, implement data storage of the data provider by using a database, reading and writing files, or accessing the network.

    const DB_NAME = 'DB00.db';
    const TBL_NAME = 'TBL00';
    const DDL_TBL_CREATE = "CREATE TABLE IF NOT EXISTS "
    + TBL_NAME
    + ' (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, isStudent BOOLEAN, Binary BINARY)';
    
    let rdbStore;
    let result;
    
    export default class DataShareExtAbility extends Extension {
      private rdbStore_;
    
      // Override onCreate().
      onCreate(want, callback) {
        result = this.context.cacheDir + '/datashare.txt';
        // Create an RDB store.
        rdb.getRdbStore(this.context, {
          name: DB_NAME,
          securityLevel: rdb.SecurityLevel.S1
        }, function (err, data) {
          rdbStore = data;
          rdbStore.executeSql(DDL_TBL_CREATE, [], (err) => {
            console.info(`DataShareExtAbility onCreate, executeSql done err:${err}`);
          });
          if (callback) {
            callback();
          }
        });
      }
    
      // Override query().
      query(uri, predicates, columns, callback) {
        if (predicates === null || predicates === undefined) {
          console.info('invalid predicates');
        }
        try {
          rdbStore.query(TBL_NAME, predicates, columns, (err, resultSet) => {
            if (resultSet !== undefined) {
              console.info(`resultSet.rowCount:${resultSet.rowCount}`);
            }
            if (callback !== undefined) {
              callback(err, resultSet);
            }
          });
        } catch (err) {
          console.error(`Failed to query. Code:${err.code},message:${err.message}`);
        }
      }
      // Override other APIs as required.
    };
    
  5. Define DataShareExtensionAbility in module.json5.

    Table 1 Fields in module.json5

Field Description Mandatory
name Ability name, corresponding to the ExtensionAbility class name derived from Ability. Yes
type Ability type. The value is dataShare, indicating the development is based on the datashare template. Yes
uri URI used for communication. It is the unique identifier for the data consumer to connect to the provider. Yes
exported Whether it is visible to other applications. Data sharing is allowed only when the value is true. Yes
readPermission Permission required for accessing data. If this parameter is not set, the read permission is not verified by default. No
writePermission Permission required for modifying data. If this parameter is not set, write permission verification is not performed by default. No

module.json5 example

"extensionAbilities": [
  {
    "srcEntrance": "./ets/DataShareExtAbility/DataShareExtAbility.ts",
    "name": "DataShareExtAbility",
    "icon": "$media:icon",
    "description": "$string:description_datashareextability",
    "type": "dataShare",
    "uri": "datashare://com.samples.datasharetest.DataShare",
    "exported": true
  }
]

Data Consumer Application Development

  1. Import the dependencies.

    import UIAbility from '@ohos.app.ability.UIAbility';
    import dataShare from '@ohos.data.dataShare';
    import dataSharePredicates from '@ohos.data.dataSharePredicates';
    
  2. Define the URI string for communicating with the data provider.

    // Different from the URI defined in the module.json5 file, the URI passed in the parameter has an extra slash (/), because there is a DeviceID parameter between the second and the third slash (/).
    let dseUri = ('datashare:///com.samples.datasharetest.DataShare');
    
  3. Create a DataShareHelper instance.

    let dsHelper;
    let abilityContext;
    
    export default class EntryAbility extends UIAbility {
      onWindowStageCreate(windowStage) {
        abilityContext = this.context;
        dataShare.createDataShareHelper(abilityContext, dseUri, (err, data) => {
          dsHelper = data;
        });
      }
    }
    
  4. Use the APIs provided by DataShareHelper to access the services provided by the provider, for example, adding, deleting, modifying, and querying data.

    // Construct a piece of data.
    let valuesBucket = { 'name': 'ZhangSan', 'age': 21, 'isStudent': false, 'Binary': new Uint8Array([1, 2, 3]) };
    let updateBucket = { 'name': 'LiSi', 'age': 18, 'isStudent': true, 'Binary': new Uint8Array([1, 2, 3]) };
    let predicates = new dataSharePredicates.DataSharePredicates();
    let valArray = ['*'];
    // Insert a piece of data.
    dsHelper.insert(dseUri, valuesBucket, (err, data) => {
      console.info(`dsHelper insert result:${data}`);
    });
    // Update data.
    dsHelper.update(dseUri, predicates, updateBucket, (err, data) => {
      console.info(`dsHelper update result:${data}`);
    });
    // Query data.
    dsHelper.query(dseUri, predicates, valArray, (err, data) => {
      console.info(`dsHelper query result:${data}`);
    });
    // Delete data.
    dsHelper.delete(dseUri, predicates, (err, data) => {
      console.info(`dsHelper delete result:${data}`);
    });