检索设备数据指南
Singular 要求在所有 API 请求中包含特定的设备标识符,以便准确归属。这些标识符包括
- 用于 Google Play 设备的 Google 广告 ID (GAID) 和 Google 应用程序集 ID (ASID)
- 非谷歌播放亚马逊设备的亚马逊广告 ID
- 针对中国制造安卓设备的开放广告 ID (OAID)
- 如果上述标识均不可用,则可使用适用于非谷歌播放设备的 Android ID (ANDI)
- 适用于 iOS 设备的广告商标识符(IDFA)和供应商标识符(IDFV)
Singular 还需要一些移动设备参数:
- 地区(如 en_US)
- 设备制造商(如三星)
- 设备型号(如 iPhone 12、三星 Galaxy S21)
- 版本(如 Build/13D15)
Singular 提供了代码片段示例,可帮助您获取这些标识符,请参见下文。
设备信息类示例
标识符
所需的 iOS 标识符
- 所有 S2S 请求都需要 IDFV
- 如果用户提供了应用程序跟踪透明同意,则应提供 IDFA。
- 还需要提供 ATT 授权状态。
检索广告商标识符 (IDFA)
广告商识别码 (IDFA) 可帮助广告商跟踪用户操作(如广告点击、应用程序安装)并将其归属于特定广告系列,从而实现精确的广告定位和广告系列优化。
从 iOS 14.5 开始,用户必须通过应用程序跟踪透明度 (ATT) 框架进行选择,然后应用程序才能访问其 IDFA。如果用户不选择加入,IDFA 将不可用,从而限制了跟踪功能。
检索供应商标识符 (IDFV)
供应商标识符 (IDFV) 是 Apple 分配给设备的唯一标识符,是特定供应商或开发者的专用标识符。该标识符在特定设备上来自同一供应商的所有应用程序中保持一致,允许供应商在其应用程序生态系统中跟踪用户行为和交互,而无需识别用户个人身份。
- 确保在尝试访问 IDFA 之前显示并处理 ATT 提示。
- 如果使用 ATT,请捕获 IDFA 并将其传回服务器,供 Singular API 请求使用。
- 捕获 IDFV 并将其传回服务器,供 Singular API 请求使用。
示例:请求 ATT 授权状态,通过控制台日志检索 IDFA 和 IDFV
下面是通过控制台日志检索 IDFA(广告商标识符)和 IDFV(供应商标识符)的 Objective-C 和 Swift 代码片段。这段代码包括处理应用程序跟踪透明度 (ATT) 权限,从 iOS 14.5 开始,访问 IDFA 需要这些权限。
#import <AdSupport/AdSupport.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <UIKit/UIKit.h>
- (void)retrieveIdentifiers {
// Request ATT authorization (iOS 14.5+)
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
switch (status) {
case ATTrackingManagerAuthorizationStatusAuthorized: {
// ATT authorized, retrieve IDFA
NSUUID *idfa = [[ASIdentifierManager sharedManager] advertisingIdentifier];
NSLog(@"IDFA: %@", [idfa UUIDString]);
break;
}
case ATTrackingManagerAuthorizationStatusDenied:
case ATTrackingManagerAuthorizationStatusRestricted:
case ATTrackingManagerAuthorizationStatusNotDetermined:
// ATT not authorized or not determined
NSLog(@"Tracking not authorized or not determined.");
break;
default:
NSLog(@"Unknown ATT status.");
break;
}
// Retrieve IDFV (always available)
NSUUID *idfv = [[UIDevice currentDevice] identifierForVendor];
if (idfv != nil) {
NSLog(@"IDFV: %@", [idfv UUIDString]);
} else {
NSLog(@"Unable to retrieve IDFV.");
}
});
}];
}
// Call the method to retrieve identifiers
[self retrieveIdentifiers];
import AdSupport
import AppTrackingTransparency
import UIKit
func retrieveIdentifiers() {
// Request ATT authorization (iOS 14.5+)
ATTrackingManager.requestTrackingAuthorization { status in
DispatchQueue.main.async {
switch status {
case .authorized:
// ATT authorized, retrieve IDFA
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
print("IDFA: \(idfa)")
case .denied, .restricted, .notDetermined:
// ATT not authorized or not determined
print("Tracking not authorized or not determined.")
@unknown default:
print("Unknown ATT status.")
}
// Retrieve IDFV (always available)
if let idfv = UIDevice.current.identifierForVendor?.uuidString {
print("IDFV: \(idfv)")
} else {
print("Unable to retrieve IDFV.")
}
}
}
}
// Call the function to retrieve identifiers
retrieveIdentifiers()
- IDFA:从 iOS 14.5+ 开始需要 ATT 授权。未经用户同意,IDFA 将返回所有 0。
- IDFV:始终可用,并应始终在奇异 API 请求中提供。
所需的安卓标识符(Google Play 设备)
- 所有 S2S 请求都需要 ASID
- 如果可用,应提供 AIFA (GAID)。
检索谷歌广告标识符 (GAID)
谷歌广告标识符 (GAID) 也称为 AIFA in Singular 或 Android Advertising ID (AAID),是分配给 Android 设备的唯一、用户可重置的标识符。它可帮助广告商和应用程序开发商跟踪用户在应用程序中的操作(如广告点击、应用程序安装)并将其归属于特定广告系列,从而实现精确的广告定位和广告系列优化,同时维护用户隐私。
确保已在 build.gradle 文件中添加 Google Play Services 所需的依赖关系:
dependencies {
implementation 'com.google.android.gms:play-services-ads-identifier:17.0.0'
}
如果您的应用程序是针对 Android 12/API level 31 或更高版本构建的,请在AndroidManifest.xml 中添加访问 Google Advertising ID 的权限:
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
要使用此方法,只需在活动或应用程序类中调用即可:
AdIdUtils.getGoogleAdId(getApplicationContext());
获取 Google 广告 ID (GAID) 的 Java 代码
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
public class AdIdUtils {
// Method to retrieve the Google Advertising ID (GAID)
public static void getGoogleAdId(Context context) {
// Running the task in a background thread
AsyncTask.execute(new Runnable() {
@Override
public void run() {
try {
// Retrieve the Advertising ID info
Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
// Get the GAID (Google Advertising ID)
String adId = adInfo.getId();
// Check if "Limit Ad Tracking" is enabled by the user
boolean isLimitAdTrackingEnabled = adInfo.isLimitAdTrackingEnabled();
// Log the results
Log.d("GoogleAdID", "Advertising ID: " + adId);
Log.d("GoogleAdID", "Limit Ad Tracking Enabled: " + isLimitAdTrackingEnabled);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
确保已在 build.gradle 文件中添加 Google Play 服务所需的依赖项:
dependencies {
implementation 'com.google.android.gms:play-services-ads-identifier:17.0.0'
}
如果您的应用程序是针对 Android 12/API level 31 或更高版本构建的,请在AndroidManifest.xml 中添加访问 Google Advertising ID 的权限:
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
使用方法
要使用此函数,您需要在一个例程作用域中调用它,例如在 ViewModel 或使用 lifecycleScope 的活动中。下面是一个在活动中调用该函数的示例:
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Launch a coroutine to fetch the Google Ad ID
lifecycleScope.launch {
val googleAdId = AdIdUtils.getGoogleAdId(applicationContext)
Log.d("MainActivity", "Retrieved Google Ad ID: $googleAdId")
}
}
}
检索 Google 广告 ID (GAID) 的 Java 代码
import android.content.Context
import android.util.Log
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
object AdIdUtils {
// Function to retrieve Google Advertising ID (GAID) using coroutines
suspend fun getGoogleAdId(context: Context): String? {
return withContext(Dispatchers.IO) {
try {
// Retrieve the Advertising ID info
val adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context)
// Get the GAID (Google Advertising ID)
val adId = adInfo.id
// Check if "Limit Ad Tracking" is enabled by the user
val isLimitAdTrackingEnabled = adInfo.isLimitAdTrackingEnabled
// Log the results
Log.d("GoogleAdID", "Advertising ID: $adId")
Log.d("GoogleAdID", "Limit Ad Tracking Enabled: $isLimitAdTrackingEnabled")
adId
} catch (e: Exception) {
e.printStackTrace()
null
}
}
}
}
检索应用程序集 ID (ASID)
Android 应用程序集 ID 为开发人员提供了一种以注重隐私的方式在自己的应用程序中跟踪用户的方法。它对分析和防止欺诈特别有用,但不能用于个性化广告或测量等广告目的。
确保已在 build.gradle 文件中添加 Google Play 服务所需的依赖关系:
dependencies {
implementation 'com.google.android.gms:play-services-appset:16.1.0'
}
使用方法
要使用此函数,只需在活动或应用程序类中调用即可:
AppSetIdUtils.getAppSetId(getApplicationContext());
读取应用程序集 ID 的 Java 代码
import android.content.Context;
import android.util.Log;
import com.google.android.gms.appset.AppSet;
import com.google.android.gms.appset.AppSetIdClient;
import com.google.android.gms.appset.AppSetIdInfo;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
public class AppSetIdUtils {
// Method to retrieve the App Set ID
public static void getAppSetId(Context context) {
// Get the AppSetIdClient instance
AppSetIdClient client = AppSet.getClient(context);
// Retrieve the App Set ID information asynchronously
Task<AppSetIdInfo> task = client.getAppSetIdInfo();
task.addOnSuccessListener(new OnSuccessListener<AppSetIdInfo>() {
@Override
public void onSuccess(AppSetIdInfo info) {
// Get the App Set ID and its scope
String appSetId = info.getId();
int scope = info.getScope();
// Log the results
Log.d("AppSetID", "App Set ID: " + appSetId);
Log.d("AppSetID", "Scope: " + (scope == AppSetIdInfo.SCOPE_DEVELOPER ? "Developer" : "App"));
}
}).addOnFailureListener(e -> {
// Handle any errors that occur during retrieval
Log.e("AppSetID", "Failed to retrieve App Set ID", e);
});
}
}
确保已在 build.gradle 文件中添加 Google Play 服务所需的依赖关系:
dependencies {
implementation 'com.google.android.gms:play-services-appset:16.1.0'
}
使用方法
要使用此函数,只需在活动或应用程序类中调用即可:
AppSetIdUtils.getAppSetId(applicationContext)
检索应用程序集 ID 的 Kotlin 代码
import android.content.Context
import android.util.Log
import com.google.android.gms.appset.AppSet
import com.google.android.gms.appset.AppSetIdClient
import com.google.android.gms.tasks.Task
object AppSetIdUtils {
// Function to retrieve the App Set ID
fun getAppSetId(context: Context) {
// Get the AppSetIdClient instance
val client: AppSetIdClient = AppSet.getClient(context)
// Retrieve the App Set ID information asynchronously
val task: Task<AppSetIdInfo> = client.appSetIdInfo
task.addOnSuccessListener { info ->
// Get the App Set ID and its scope
val appSetId: String = info.id
val scope: Int = info.scope
// Log the results
Log.d("AppSetID", "App Set ID: $appSetId")
Log.d("AppSetID", "Scope: ${if (scope == AppSetIdInfo.SCOPE_DEVELOPER) "Developer" else "App"}")
}.addOnFailureListener { exception ->
// Handle any errors that occur during retrieval
Log.e("AppSetID", "Failed to retrieve App Set ID", exception)
}
}
}
所需的安卓标识符(非谷歌播放设备)
如果没有 ASID 或 AIFA:
- 应提供 AMID(亚马逊标识符)。仅限亚马逊设备。
检索亚马逊标识符 (AMID)
要在 Android 应用程序中捕获亚马逊广告标识符,您可以使用 Settings.Secure 类检索标识符并检查用户的广告跟踪偏好。下面是一个基于亚马逊文档所提供信息的简洁代码示例:
确保处理广告 ID 可能不可用的情况(例如,在非 Fire OS 设备或旧版本的 Fire OS 上)。
将此标识符用于广告或分析目的时,始终尊重用户的 "限制广告跟踪 "偏好。根据亚马逊的指导原则,此代码应在运行 Fire OS 5.1 或更高版本的亚马逊 Fire 设备上运行
您可以在您的活动或服务中通过传入 ContentResolver 调用此方法:
// Example usage in an Activity
AdvertisingIdHelper.getAmazonAdvertisingId(getContentResolver());
获取亚马逊广告 ID (AMID) 的 Java 代码
import android.content.ContentResolver;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
public class AdvertisingIdHelper {
public static void getAmazonAdvertisingId(ContentResolver contentResolver) {
String advertisingID = "";
boolean limitAdTracking = false;
try {
// Get user's ad tracking preference
limitAdTracking = (Settings.Secure.getInt(contentResolver, "limit_ad_tracking") == 0) ? false : true;
// Get the Amazon Advertising ID
advertisingID = Settings.Secure.getString(contentResolver, "advertising_id");
// Log the values for demonstration purposes
Log.d("AdvertisingID", "Amazon Advertising ID: " + advertisingID);
Log.d("LimitAdTracking", "Limit Ad Tracking: " + limitAdTracking);
} catch (SettingNotFoundException e) {
// Handle case where settings are not available (e.g., non-Fire OS devices)
Log.e("AdvertisingID", "Advertising ID not supported on this device", e);
}
}
}
您可以通过传入 ContentResolver 从活动或服务中调用此方法:
// Example usage in an Activity
AdvertisingIdHelper.getAmazonAdvertisingId(contentResolver)
检索亚马逊广告 ID (AMID) 的 Kotlin 代码
import android.content.ContentResolver
import android.provider.Settings
import android.util.Log
object AdvertisingIdHelper {
fun getAmazonAdvertisingId(contentResolver: ContentResolver) {
try {
// Get user's ad tracking preference
val limitAdTracking = Settings.Secure.getInt(contentResolver, "limit_ad_tracking") != 0
// Get the Amazon Advertising ID
val advertisingID = Settings.Secure.getString(contentResolver, "advertising_id")
// Log the values for demonstration purposes
Log.d("AdvertisingID", "Amazon Advertising ID: $advertisingID")
Log.d("LimitAdTracking", "Limit Ad Tracking: $limitAdTracking")
} catch (e: Settings.SettingNotFoundException) {
// Handle case where settings are not available (e.g., non-Fire OS devices)
Log.e("AdvertisingID", "Advertising ID not supported on this device", e)
}
}
}
- 应提供 OAID(开放广告标识符)。中国国内设备。
检索开放广告标识符 (OAID)
开放式广告标识符(OAID)是一个唯一的匿名标识符,用于在安卓设备(尤其是中国制造的设备)上发布广告。它是由移动安全联盟(MSA)推出的,作为谷歌广告标识符(GAID)的替代标识符,适用于无法使用或不支持谷歌播放服务的设备,例如在中国市场。
OAID 主要用于在 Google Play 服务受限的环境中进行广告归属和用户跟踪,允许广告商和开发商在保持匿名的同时跟踪用户行为。
大多数中国制造的安卓设备都可以使用 OAID,包括华为、小米等品牌的设备。可以使用MSA SDK或华为移动服务(HMS)访问它。
确保您的 build.gradle 文件包含 MSA SDK 的必要依赖项。
dependencies {
implementation 'com.bun.msa.sdk:msa:1.0.26' // Example version; check for the latest one
}
检索 OAID 的 Java 代码
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import com.bun.msa.sdk.DeviceId;
import com.bun.msa.sdk.DeviceIdSupplier;
import com.bun.msa.sdk.IIdentifierListener;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "OAIDExample";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize and request OAID
getOAID();
}
private void getOAID() {
try {
// Create a DeviceId instance and request OAID asynchronously
DeviceId deviceId = new DeviceId(this);
deviceId.getDeviceIds(new IIdentifierListener() {
@Override
public void onSupport(boolean isSupport, DeviceIdSupplier supplier) {
if (isSupport && supplier != null) {
// Retrieve OAID from supplier
String oaid = supplier.getOAID();
Log.d(TAG, "OAID: " + oaid);
} else {
Log.e(TAG, "OAID not supported on this device");
}
}
});
} catch (Exception e) {
Log.e(TAG, "Error retrieving OAID", e);
}
}
}
将 MSA SDK 添加到项目中:与 Java 版本类似,您需要将 MSA SDK 集成到您的项目中。确保在 build.gradle 文件中有正确的依赖关系:
dependencies {
implementation 'com.bun.msa.sdk:msa:1.0.26' // Example version; check for the latest one
}
检索 OAID 的 Kotlin 代码
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.bun.msa.sdk.DeviceId
import com.bun.msa.sdk.DeviceIdSupplier
import com.bun.msa.sdk.IIdentifierListener
class MainActivity : AppCompatActivity() {
companion object {
private const val TAG = "OAIDExample"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Initialize and request OAID
getOAID()
}
private fun getOAID() {
try {
val deviceId = DeviceId(this)
deviceId.getDeviceIds(object : IIdentifierListener {
override fun onSupport(isSupport: Boolean, supplier: DeviceIdSupplier?) {
if (isSupport && supplier != null) {
// Retrieve OAID from supplier
val oaid = supplier.oAID
Log.d(TAG, "OAID: $oaid")
} else {
Log.e(TAG, "OAID not supported on this device")
}
}
})
} catch (e: Exception) {
Log.e(TAG, "Error retrieving OAID", e)
}
}
}
- 如果没有其他设备标识符,则可以提供 ANDI(Android ID)。
检索安卓 ID(ANDI)
安卓 ID 是安卓操作系统在首次设置设备时生成的唯一 64 位标识符。它在设备的整个生命周期内都是持久的,但在某些情况下可以重置,如出厂重置。
每个设备的 Android ID 都是唯一的,而且从 Android 8.0(奥利奥)开始,每个应用程序和每个用户都有自己的 ID。这意味着同一设备上的不同应用程序将获得不同的 Android ID,除非它们共享相同的签名密钥。
除非设备进行出厂重置或在 OTA(空中下载)更新后卸载并重新安装应用程序,否则 Android ID 将保持不变。
要在 Android 应用程序中检索 Android ID,可以使用以下代码片段:
import android.provider.Settings;
import android.content.Context;
String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
通过传入 ContentResolver,您可以从活动或服务中调用此方法:
import android.os.Bundle
import android.provider.Settings
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Find the TextView in the layout to display the Android ID
val textView: TextView = findViewById(R.id.textView)
// Retrieve the Android ID
val androidId: String = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
}
}
所需网络标识符
- 所有 S2S 请求都需要 SDID
检索奇异网络 SDK 设备 ID (SDID)
说明
必须已实施 Singular Web SDK。
使用方法要使用此方法,只需在 Singular SDK 初始化后从网站代码中调用即可:
window.singularSdk.getSingularDeviceId()
所需移动设备参数
- 在所有 S2S 请求中,都需要提供地域、设备制造商、设备型号和构建参数。
检索位置、设备制造商、型号和构建
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <sys/sysctl.h>
// Retrieve the Locale
NSString *retrieveLocale() {
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
NSLog(@"Locale: %@", locale);
return locale;
}
// Retrieve the Manufacturer
NSString *retrieveManufacturer() {
// Set the Device Make to Apple
return @"Apple";
}
// Retrieve the Device Model
NSString *deviceModel() {
size_t bufferSize = 64;
char model[bufferSize];
int status = sysctlbyname("hw.machine", model, &bufferSize, NULL, 0);
if (status == 0) {
NSString *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
NSLog(@"Device Model: %@", deviceModel);
return deviceModel;
} else {
NSLog(@"Unable to retrieve device model.");
return nil;
}
}
// Retrieve the Build Version
NSString *buildVersion() {
size_t bufferSize = 64;
char build[bufferSize];
int status = sysctlbyname("kern.osversion", build, &bufferSize, NULL, 0);
if (status == 0) {
NSString *buildVersion = [NSString stringWithCString:build encoding:NSUTF8StringEncoding];
NSLog(@"Build Version: %@", buildVersion);
return buildVersion;
} else {
NSLog(@"Unable to retrieve build version.");
return nil;
}
}
// Example usage
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Retrieve Locale
NSString *locale = retrieveLocale();
// Retrieve Device Make
NSString *make = retrieveManufacturer();
// Retrieve Device Model
NSString *model = deviceModel();
// Retrieve Build Version
NSString *build = buildVersion();
// Log results
if (locale) {
NSLog(@"Locale: %@", locale);
}
if (make) {
NSLog(@"Device Make: %@", make);
}
if (model) {
NSLog(@"Device Model: %@", model);
}
if (build) {
NSLog(@"Build Version: %@", build);
}
}
return 0;
}
import Foundation
// Retrieve the Locale
func retrieveLocale() -> String {
let locale = Locale.current.identifier
print("Locale: \(locale)")
return locale
}
// Retrieve the Device Model
import UIKit
func deviceModel() -> String? {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
print("Device Model: \(identifier)")
return identifier
}
// Retrieve the Build Version
func buildVersion() -> String? {
var size: Int = 0
sysctlbyname("kern.osversion", nil, &size, nil, 0)
var build = [CChar](repeating: 0, count: size)
sysctlbyname("kern.osversion", &build, &size, nil, 0)
let buildVersion = String(cString: build)
print("Build Version: \(buildVersion)")
return buildVersion
}
// Example usage:
let locale = retrieveLocale()
print("Locale: \(locale)")
let deviceMake = "Apple"
print("Device Make: \(deviceMake)")
if let model = deviceModel() {
print("Device Model: \(model)")
}
if let build = buildVersion() {
print("Build Version: \(build)")
}
// Locale - lc= query parameter
String locale = Locale.getDefault().toString(); // Converts Locale object to string
// Make - ma= query parameter
String deviceMake = Build.MANUFACTURER; // Gets the device manufacturer name
// Model - mo= query parameter
String deviceModel = Build.MODEL; // Gets the device model
// Build - bd= query parameter
String build = "Build/" + Build.ID; // Gets the build ID and appends it to "Build/"
// Locale - lc= query parameter
val locale: String = Locale.getDefault().toString() // Converts Locale object to string
// Make - ma= query parameter
val deviceMake: String = Build.MANUFACTURER // Gets the device manufacturer name
// Model - mo= query parameter
val deviceModel: String = Build.MODEL // Gets the device model
// Build - bd= query parameter
val build: String = "Build/" + Build.ID // Gets the build ID and appends it to "Build/"