HarmonyOS鸿蒙Next中在用户升级app的时候,rdb访问的sqlite表有了变化如何对这个数据库文件进行修改?另外一个就是,我想获取一个不涉及用户隐私的唯一标识,不知道能获取不

HarmonyOS鸿蒙Next中在用户升级app的时候,rdb访问的sqlite表有了变化如何对这个数据库文件进行修改?另外一个就是,我想获取一个不涉及用户隐私的唯一标识,不知道能获取不 在用户升级app的时候,rdb访问的sqlite表有了变化如何对这个数据库文件进行修改

另外一个就是,我想获取一个不涉及用户隐私的唯一标识,不知道能获取不?

3 回复

– 在用户升级app的时候,rdb访问的sqlite表有了变化如何对这个数据库文件进行修改

通过执行ALERT语句修改表结构,请参考:通过关系型数据库实现数据持久化

注意:不支持一个ALERT语句里操作多个字段,若有多个字段需要增/删/改,需要每个字段对应写一个ALERT语句去执行。

– 获取一个不涉及用户隐私的唯一标识

【背景知识】

常见设备的标识有OAID、ODID、AAID、UDID等,定义和用途如下:

  • OAID(开放匿名设备标识符)一种非永久性设备标识符,基于OAID,可在保护用户个人数据隐私安全的前提下,媒体App、广告平台、三方监测平台等开发者,可获取设备上的OAID,进行个性化广告推荐或广告转化归因分析。
  • ODID(开发者匿名设备标识符):用于识别同一设备上运行的同一个开发者的应用,标识应用身份。帮助开发者更好地理解用户在不同应用间的行为,从而提供更个性化的服务和推荐。
  • AAID(应用匿名标识符):标识应用的身份,主要用于应用的消息推送。
  • UDID(设备唯一标识符):标识设备的属性,可作为设备唯一识别码。

综上所述,只有UDID才能作为设备的唯一标识符,不会随设备重置或应用卸载而发生变化,但UDID只允许系统应用及企业定制应用申请特殊权限才能获取。当前设备重置时还无法保证标识符不发生改变,但有方案可以实现应用卸载时标识符不发生改变。

【解决方案】

  1. OAID的获取方法。

    OAID主要用于个性化广告推荐或广告转化归因分析,可通过identifier.getOAID()获取OAID,示例:

import { identifier } from '@kit.AdsKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

identifier.getOAID().then((data) => {
  const oaid: string = data;
  hilog.info(0x0000, 'testTag', `Succeeded in getting oaid. Oaid is ${oaid}`);
}).catch((err: BusinessError) => {
  hilog.error(0x0000, 'testTag', `Failed to get oaid. Code is ${err.code}, message is ${err.message}`);
})

注意:获取OAID需要申请权限ohos.permission.APP_TRACKING_CONSENT权限,该权限是user_grant权限,需要弹窗授权用户允许后才可以获取。如果未定义该权限或者"跨应用关联访问权限"为"禁止",获取的OAID将为全0。具体可参考广告标识服务

OAID是设备级标识符,同一台设备上不同的App获取到的OAID值一样,且在应用卸载后不会变化,但在以下场景会发生改变:

  • 用户手机恢复出厂设置。
  • 用户手动操作重置OAID:打开系统设置–隐私和安全–跨应用关联页面,把所有应用的跟踪权限关了,再任意打开一个,即可触发OAID的重置。
  1. ODID的获取方法。

    可通过Basic Services Kit的deviceInfo.ODID接口获取ODID,示例:

import { deviceInfo } from '@kit.BasicServicesKit';

let odid: string = deviceInfo.ODID;
// 输出结果:the value of the ODID is :1234a567-XXXX-XXXX-XXXX-XXXXXXXXXXXX
console.info('the value of the deviceInfo odid is :' + odid);

注意:ODID是用于标识同一设备上同一开发者的应用,是开发者级的标识符。同一台设备上运行的同一个开发者的应用,ODID相同。同一台设备上不同开发者的应用,ODID不同。ODID在以下场景重新生成:

  • 设备恢复出厂设置。
  • 同一设备上同一个开发者的应用全部卸载后重新安装时。
  1. AAID的获取方法。

    可通过getAAID()获取AAID,示例:

import { AAID } from '@kit.PushKit';
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

export default class EntryAbility extends UIAbility {
  // 入参want与launchParam并未使用,为初始化项目时自带参数
  async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
    // 获取AAID
    try {
      const aaid: string = await AAID.getAAID();
      hilog.info(0x0000, 'testTag', 'Succeeded in getting AAID.');
    } catch (err) {
      let e: BusinessError = err as BusinessError;
      hilog.error(0x0000, 'testTag', 'Failed to get AAID: %{public}d %{public}s', e.code, e.message);
    }
  }
}

注意:AAID和已有的任何标识符都不关联,并且每个应用只能访问自己的AAID,是应用级的标识符。只有该应用实例才能访问该标识符,它只存在于应用的安装期,适用于应用的消息推送。AAID会在以下场景中发生变化:

  • 应用卸载重装。
  • 应用调用删除AAID接口。
  • 用户恢复出厂设置。
  • 用户清除应用数据。
  1. UDID的获取方法。

    可通过Basic Services Kit的deviceInfo.udid接口获取UDID,示例:

import { deviceInfo } from '@kit.BasicServicesKit';

let udid: string = deviceInfo.udid;
// 输出结果:the value of the udid is :9D6AABD147XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXE5536412
console.info('the value of the deviceInfo udid is :' + udid);

UDID需要申请ohos.permission.sec.ACCESS_UDID权限才能获取,该权限当前只允许系统应用及企业定制应用才能申请。因此,UDID虽然是设备级的唯一标识符,但对三方应用不开放,一般用于本地HAP包的调试。

  1. 实现获取的标识在应用卸载也不发生变化。

    为了保证及时在应用卸载后仍能有效的确保获取的设备标识符不发生变化,间接达到"唯一标识符"的目的,华为提供了关键资产存储服务,开发者可以将设备标识符放在asset里,设置IS_PERSISTENT为true,实现在应用卸载时保留关键资产,达到标识符不清除的效果。如获取ODID后配合使用Asset Store Kit能力,保持ODID不变的效果,示例代码如下:

import { asset } from '@kit.AssetStoreKit';
import util from '@ohos.util';
import { deviceInfo } from '@kit.BasicServicesKit';

function stringToArray(str: string): Uint8Array {
  let textEncoder = new util.TextEncoder();
  return textEncoder.encodeInto(str);
}

function setAttr(id: string) {
  let attr: asset.AssetMap = new Map();
  attr.set(asset.Tag.SECRET, stringToArray(id));
  attr.set(asset.Tag.ALIAS, stringToArray('demo_device_id'));
  attr.set(asset.Tag.IS_PERSISTENT, true);
  try {
    asset.add(attr).then(() => {
      console.info(`Asset added successfully.`);
    }).catch(() => {
      console.error(`Failed to add Asset.`);
    })
  } catch (error) {
    console.error(`Failed to add Asset.`);
  }
}

function arrayToString(arr: Uint8Array): string {
  let textDecoder = util.TextDecoder.create("utf-8", { ignoreBOM: true });
  let str = textDecoder.decodeWithStream(arr, { stream: false })
  return str;
}

async function getAttr(): Promise<string> {
  let query: asset.AssetMap = new Map();
  query.set(asset.Tag.ALIAS, stringToArray('demo_device_id')); // 指定了关键资产别名,最多查询到一条满足条件的关键资产
  query.set(asset.Tag.RETURN_TYPE, asset.ReturnType.ALL); // 此处表示需要返回关键资产的所有信息,即属性+明文
  try {
    const res: Array<asset.AssetMap> = await asset.query(query)
    // 解析密钥
    let secret: Uint8Array = res[0].get(asset.Tag.SECRET) as Uint8Array;
    // 将uint8array解析为字符串
    let secretStr: string = arrayToString(secret);
    return secretStr;
  } catch (error) {
    console.error(`Failed to query Asset.`);
    return '';
  }
}

@Entry
@Component
struct AttrTest {
  build() {
    Column() {
      Button('获取设备ID').onClick(async (event: ClickEvent) => {
        let deviceId: string = await getAttr();
        if (deviceId === undefined || deviceId === null || deviceId.length === 0) {
          deviceId = deviceInfo.ODID;
          setAttr(deviceId);
        }
        console.log('设备ID为:' + deviceId)
      })
        .height(100)
        .width('100%')
    }
  }
}

注意,如果要设置IS_PERSISTENT属性,需要申请ohos.permission.STORE_PERSISTENT_DATA权限。

更多关于HarmonyOS鸿蒙Next中在用户升级app的时候,rdb访问的sqlite表有了变化如何对这个数据库文件进行修改?另外一个就是,我想获取一个不涉及用户隐私的唯一标识,不知道能获取不的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对数据库升级:在HarmonyOS Next中需实现RdbStoreOpenCallback的onUpgrade方法,通过执行ALTER TABLE语句或版本控制完成表结构变更。升级逻辑需在应用更新时自动触发。

关于设备标识:可调用getUdid()方法获取系统分配的UDID,该标识符经匿名化处理且同一应用内保持唯一,符合隐私保护要求。需在应用配置文件中声明相应权限。

针对你的两个问题,以下是HarmonyOS Next中的解决方案:

1. 数据库表结构升级处理 当应用升级时,如果SQLite表结构发生变化,需要通过RDB的升级机制来处理:

  • RdbStoreConfig中设置正确的数据库版本号
  • 实现RdbOpenCallbackonUpgrade方法
  • onUpgrade中执行ALTER TABLE等SQL语句来修改表结构
  • 使用executeSql方法执行具体的表结构变更操作
  • 确保在数据迁移过程中处理好旧数据到新结构的转换

2. 获取非隐私唯一标识 HarmonyOS Next提供了以下安全标识方案:

  • 使用getUDID()方法获取设备唯一标识符
  • 该标识符由系统生成,不包含个人隐私信息
  • 同一应用在不同设备上获取的UDID不同
  • 同一设备上不同应用获取的UDID也不同
  • 系统会自动管理标识符的生成和存储,开发者无需处理隐私合规问题

这两种方案都能很好地满足你的需求,同时符合HarmonyOS Next的安全和隐私保护规范。

回到顶部