在Android裝置上使用極光推送id重複的原因分析和解決辦法

祕密小房間的呆屁發表於2019-12-23

引言

在使用極光推送時,用於區分推送裝置最重要的就是RegistrationID,如果出現相同的ID推送就會出問題

原因分析

RegistrationID是由裝置的IMEI 、 serial_number 、deviceID三個引數決定的,出現相同的RegistrationID首先應該檢查這三個引數是否為空,或出現值相同的情況。
後臺儲存 uid 的方式是根據 appkey_dvcid->uid ,appkey_imei_mac->uid, appkey_serial->uid 這三種儲存方式,左邊的這三種key只要檢測到一個匹配,就會把存的 uid 返回給前端
如果 IMEI一樣,當取到的serial_number 或 mac 地址又為空,那就有可能很多裝置拿到相同 RegistrationID 值

解決辦法

方法一: 重燒 IMEI ,刷機或者進行如下步驟:

  • 步驟一:把這個檔案清掉:Environment.getExternalStorageDirectory().getPath() + “/data/.push_deviceid”;
  • 步驟二:同步清除掉 setting 裡面的,方法如下:Settings.System.putString(context.getContentResolver(), “devcie_id_generated”, “”);
  • 步驟三:還有把快取也清理下;
  • 然後再重灌 App。
    ◦上述操作是系統方法,如果操作未果,則說明你使用的是自己的定製裝置,匯出你的資料庫資訊檢視一下 device ID 資訊,不要將該資訊固定為同一個值。

方法二: 原始碼中修改或設定serial_number 的取值
檔案位置:/system/core/init/init.cpp
這裡以我遇到的問題為例(極光取到的serial_number 為空導致概率出現RegistrationID相同的情況)
系統會使用ro.serialno的值作為序列號(SN號),若能使每臺裝置的ro.serialno值唯一可以解決這個問題,由於我們每臺裝置都會燒錄購買的獨立mac號,這裡舉例將mac的值作為ro.serialno的值。

static void export_kernel_boot_props() {
    struct {
        const char *src_prop;
        const char *dst_prop;
        const char *default_value;
    } prop_map[] = {
        { "ro.boot.serialno",   "ro.serialno",   "", },
        { "ro.boot.mode",       "ro.bootmode",   "unknown", },
        { "ro.boot.baseband",   "ro.baseband",   "unknown", },
        { "ro.boot.bootloader", "ro.bootloader", "unknown", },
        { "ro.boot.hardware",   "ro.hardware",   "unknown", },
        { "ro.boot.revision",   "ro.revision",   "0", },
        { "ro.boot.firstboot",  "ro.firstboot",  "0", },
    };
    for (size_t i = 0; i < ARRAY_SIZE(prop_map); i++) {
		//add
		if(i == 0){
			char serialno[20];
			import_kernel_cmdline(false, [&](const std::string& key, const std::string& value, bool in_qemu) {
				if (key == "androidboot.mac") {
					strcpy(serialno,value.c_str());
					NOTICE("ADD serialno mac is %s...\n", value.c_str());
				}
			});
			
			NOTICE("ADD serialno mac 2 is %s...\n", serialno);
            property_set(prop_map[i].dst_prop, serialno);
		}else
		{
			std::string value = property_get(prop_map[i].src_prop);
			property_set(prop_map[i].dst_prop, (!value.empty()) ? value.c_str() : prop_map[i].default_value);
		}
		//add end
		/* disabled
        std::string value = property_get(prop_map[i].src_prop);
        property_set(prop_map[i].dst_prop, (!value.empty()) ? value.c_str() : prop_map[i].default_value);*/
    }
}

相關文章