ඇන්ඩ්රොයිඩ් උපාංගවලට අද්විතීය හැඳුනුම්පතක් තිබේද, එසේ නම්, ජාවා භාවිතයෙන් එයට ප්රවේශ වීමට සරල ක්රමයක් කුමක්ද?
ඇන්ඩ්රොයිඩ් උපාංගවලට අද්විතීය හැඳුනුම්පතක් තිබේද, එසේ නම්, ජාවා භාවිතයෙන් එයට ප්රවේශ වීමට සරල ක්රමයක් කුමක්ද?
Answers:
Settings.Secure#ANDROID_ID
සෑම පරිශීලකයෙකුටම 64-බිට් හෙක්ස් නූලක් සඳහා ඇන්ඩ්රොයිඩ් හැඳුනුම්පත අද්විතීය ලෙස ලබා දෙයි .
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
යාවත්කාලීන කිරීම : ඇන්ඩ්රොයිඩ් හි මෑත සංස්කරණ වලදී, බොහෝ ගැටලු ANDROID_ID
විසඳා ඇති අතර, මෙම ප්රවේශය තවදුරටත් අවශ්ය නොවන බව මම විශ්වාස කරමි. කරුණාකර ඇන්තනිගේ පිළිතුර දෙස බලන්න .
පූර්ණ අනාවරණය: මගේ යෙදුම ප්රවේශය පහත මුලින් මෙම ප්රවේශය භාවිතා කිරීම සහ අපි දැන් ගෙනහැර දක්වන ප්රවේශය භාවිතා භාවිතා එහෙත් තවදුරටත් Android සංවර්ධක බ්ලොග් ඇතුල්කල emmby පිළිතුර (එනම්, උත්පාදක සහ ඉතිරිය සබැඳි UUID#randomUUID()
).
මෙම ප්රශ්නයට බොහෝ පිළිතුරු ඇත, ඒවායින් බොහොමයක් ක්රියාත්මක වන්නේ “සමහරක්” කාලය පමණක් වන අතර අවාසනාවකට එය ප්රමාණවත් නොවේ.
මගේ උපාංගවල පරීක්ෂණ මත පදනම්ව (සියලුම දුරකථන, අවම වශයෙන් එකක්වත් සක්රිය කර නැත):
TelephonyManager.getDeviceId()
TelephonyManager.getSimSerialNumber()
getSimSerialNumber()
(අපේක්ෂා කළ පරිදි)ANDROID_ID
ANDROID_ID
අතර TelephonyManager.getDeviceId()
- සැකසීමේදී ගූගල් ගිණුමක් එකතු කර ඇති තාක් කල් .එබැවින් ඔබට උපාංගයටම ආවේණික යමක් අවශ්ය නම් එය ප්රමාණවත් TM.getDeviceId()
විය යුතුය. නිසැකවම සමහර පරිශීලකයින් අනෙක් අයට වඩා ව්යාකූල වේ, එබැවින් මෙම හඳුනාගැනීම් 1 ක් හෝ වැඩි ගණනක් හැෂ් කිරීම ප්රයෝජනවත් විය හැකිය, එවිට නූල තවමත් උපාංගයට අද්විතීය වන නමුත් පරිශීලකයාගේ සැබෑ උපාංගය පැහැදිලිව හඳුනා නොගනී. උදාහරණයක් ලෙස, String.hashCode()
UUID සමඟ ඒකාබද්ධව භාවිතා කිරීම :
final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
මෙවැනි දෙයකට හේතු විය හැක: 00000000-54b3-e7c7-0000-000046bffd97
එය මට හොඳට වැඩ කරයි.
රිචඩ් පහත සඳහන් පරිදි, TelephonyManager
ගුණාංග කියවීමට ඔබට අවසර අවශ්ය බව අමතක නොකරන්න , එබැවින් මෙය ඔබේ මැනිෆෙස්ටයට එක් කරන්න:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
තොග ආනයනය කරන්න
import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
මැනිෆෙස්ට් ගොනුවට එක් කිරීමට මතක තබා ගන්න . දත්ත සමුදායක ගබඩා කරන්නේ නම්, ආපසු ලබා දුන් නූල අක්ෂර 36 කි.
අද්විතීය හැඳුනුම්පතක්, ගූගල් සංවර්ධක බ්ලොගය සහ ඇන්ඩ්රොයිඩ් ලියකියවිලි නිර්මාණය කිරීම පිළිබඳ සෑම ස්ටැක් පිටාර ගැලීම් පෝස්ට් එකක්ම කියවීමෙන් පසු, 'ව්යාජ හැඳුනුම්පත' හොඳම විකල්පය ලෙස මට හැඟේ.
Psuedo කේතය:
if API >= 9/10: (99.5% of devices)
return unique ID containing serial id (rooted devices may be different)
else
return the unique ID of build information (may overlap data - API < 9)
අපගේ සියලු විකල්පයන් පළ කිරීම සඳහා anstansult ට ස්තූතියි (මෙම සිරස් පිටාර ගැලීමේ ප්රශ්නයේ).
පරිශීලක විද්යුත් තැපෑල - මෘදුකාංග
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
හෝ<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
( ඇන්ඩ්රොයිඩ් උපාංගයේ ප්රාථමික විද්යුත් තැපැල් ලිපිනය ලබා ගන්නේ කෙසේද )පරිශීලක දුරකථන අංකය - මෘදුකාංගය
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
IMEI - දෘඩාංග (දුරකථන, අවශ්යතා පමණි android.permission.READ_PHONE_STATE
)
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
ඇන්ඩ්රොයිඩ් හැඳුනුම්පත - දෘඩාංග (ශුන්ය විය හැකිය, කර්මාන්තශාලා යළි පිහිටුවීමෙන් වෙනස් විය හැකිය, මුල් බැසගත් උපාංගයක් මත වෙනස් කළ හැකිය)
WLAN MAC ලිපිනය - දෘඩාංග (අවශ්යතා android.permission.ACCESS_WIFI_STATE
)
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
බ්ලූටූත් MAC ලිපිනය - දෘඩාංග (බ්ලූටූත් සහිත උපාංග, අවශ්යතා android.permission.BLUETOOTH
)
<uses-permission android:name="android.permission.BLUETOOTH "/>
ව්යාජ අද්විතීය හැඳුනුම්පත - මෘදුකාංගය (සියලුම ඇන්ඩ්රොයිඩ් උපාංග සඳහා)
අවසර භාවිතා නොකර අද්විතීය හැඳුනුම්පතක් ලබා ගැනීමේ 'පරිපූර්ණ' ක්රමයක් නොමැති බව මම දනිමි; කෙසේ වෙතත්, සමහර විට අපට අවශ්ය වන්නේ උපාංග ස්ථාපනය නිරීක්ෂණය කිරීමයි. අද්විතීය හැඳුනුම්පතක් සෑදීමේදී, අමතර අවසරයන් භාවිතා නොකර ඇන්ඩ්රොයිඩ් ඒපීඅයි අපට ලබා දෙන තොරතුරු වලින් බැහැරව අපට ව්යාජ අද්විතීය හැඳුනුම්පතක් නිර්මාණය කළ හැකිය. මේ ආකාරයෙන්, අපට පරිශීලක ගෞරවය පෙන්විය හැකි අතර හොඳ පරිශීලක අත්දැකීමක් ලබා දීමට උත්සාහ කළ හැකිය.
ව්යාජ අද්විතීය හැඳුනුම්පතක් සමඟ, ඔබ සැබවින්ම දුවන්නේ සමාන උපාංග ඇති බව මත පදනම්ව අනුපිටපත් තිබිය හැකිය. එය වඩාත් අද්විතීය කිරීම සඳහා ඔබට ඒකාබද්ධ ක්රමය වෙනස් කළ හැකිය; කෙසේ වෙතත්, සමහර සංවර්ධකයින්ට උපාංග ස්ථාපනයන් නිරීක්ෂණය කිරීමට අවශ්ය වන අතර මෙය සමාන උපාංග මත පදනම්ව උපක්රම හෝ ක්රියාකාරිත්වය සිදු කරයි.
ඔවුන්ගේ ඇන්ඩ්රොයිඩ් උපාංගය API 9 හෝ ඊට වැඩි නම්, 'Build.SERIAL' ක්ෂේත්රය නිසා මෙය අද්විතීය බව සහතික වේ.
මතක තබා ගන්න , ඔබ තාක්ෂණිකව මඟ හැරී ඇත්තේ API <9 ඇති පරිශීලකයින්ගෙන් 0.5% ක් පමණි . එබැවින් ඔබට ඉතිරිය කෙරෙහි අවධානය යොමු කළ හැකිය: මෙය පරිශීලකයින්ගෙන් 99.5% කි!
පරිශීලකයාගේ ඇන්ඩ්රොයිඩ් උපාංගය API 9 ට වඩා අඩු නම්; ඔවුන් කර්මාන්තශාලා යළි පිහිටුවීම සිදු කර නොමැති අතර ඔවුන්ගේ 'Secure.ANDROID_ID' සුරැකෙනු ඇත හෝ 'ශුන්ය' නොවේ. ( http://developer.android.com/about/dashboards/index.html බලන්න )
අනෙක් සියල්ල අසමත් වුවහොත්, පරිශීලකයාට API 9 ට වඩා අඩු (ජින්ජර් බ්රෙඩ් වලට වඩා අඩු), ඔවුන්ගේ උපාංගය නැවත සකසා තිබේ නම් හෝ 'ආරක්ෂිත. Isions ට්ටන සිදුවිය හැකි ස්ථානය මෙයයි.
වෙනස්කම්:
කරුණාකර පහත ක්රමය දෙස බලන්න:
/**
* Return pseudo unique ID
* @return ID
*/
public static String getUniquePsuedoID() {
// If all else fails, if the user does have lower than API 9 (lower
// than Gingerbread), has reset their device or 'Secure.ANDROID_ID'
// returns 'null', then simply the ID returned will be solely based
// off their Android device information. This is where the collisions
// can happen.
// Thanks http://www.pocketmagic.net/?p=1662!
// Try not to use DISPLAY, HOST or ID - these items could change.
// If there are collisions, there will be overlapping data
String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);
// Thanks to @Roman SL!
// https://stackoverflow.com/a/4789483/950427
// Only devices with API >= 9 have android.os.Build.SERIAL
// http://developer.android.com/reference/android/os/Build.html#SERIAL
// If a user upgrades software or roots their device, there will be a duplicate entry
String serial = null;
try {
serial = android.os.Build.class.getField("SERIAL").get(null).toString();
// Go ahead and return the serial for api => 9
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
// String needs to be initialized
serial = "serial"; // some value
}
// Thanks @Joe!
// https://stackoverflow.com/a/2853253/950427
// Finally, combine the values we have found by using the UUID class to create a unique identifier
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
ගූගල් ප්ලේ සංවර්ධකගේ කොන්සෝලයෙන්:
2014 අගෝස්තු 1 වන දින සිට, ගූගල් ප්ලේ සංවර්ධක වැඩසටහන් ප්රතිපත්තියට ඕනෑම වෙළඳ ප්රචාරණ අරමුණු සඳහා වෙනත් නිරන්තර හඳුනාගැනීම් වෙනුවට වෙළඳ දැන්වීම් හැඳුනුම්පත භාවිතා කිරීම සඳහා සියලු නව යෙදුම් උඩුගත කිරීම් සහ යාවත්කාලීන කිරීම් අවශ්ය වේ. වැඩිදුර ඉගෙන ගන්න
ක්රියාත්මක කිරීම :
අවසර:
<uses-permission android:name="android.permission.INTERNET" />
කේතය:
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import java.io.IOException;
...
// Do not call this function from the main thread. Otherwise,
// an IllegalStateException will be thrown.
public void getIdThread() {
Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
} catch (IOException exception) {
// Unrecoverable error connecting to Google Play services (e.g.,
// the old version of the service doesn't support getting AdvertisingId).
} catch (GooglePlayServicesAvailabilityException exception) {
// Encountered a recoverable error connecting to Google Play services.
} catch (GooglePlayServicesNotAvailableException exception) {
// Google Play services is not available entirely.
}
final String id = adInfo.getId();
final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
}
මූලාශ්රය / ලියකියවිලි:
http://developer.android.com/google/play-services/id.html http://developer.android.com/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html
ගූගල් ප්ලේ සේවා ලබා ගත හැකි විට වෙළඳ දැන්වීම් හැඳුනුම්පත වෙළඳ දැන්වීම් සඳහා දැනට පවතින වෙනත් හඳුනාගැනීම් භාවිතය සම්පූර්ණයෙන්ම ප්රතිස්ථාපනය කිරීමට අදහස් කරයි (සැකසීම් වල ANDROID_ID භාවිතා කිරීම වැනි. ගූගල් ප්ලේ සේවා ලබා ගත නොහැකි අවස්ථා GooglePlayServicesNotAvailableException මගින් getAdvertisingIdInfo () විසින් විසි කරනු ලැබේ.
http://en.kioskea.net/faq/34732-android-reset-your-ad advertising-id
මම තොරතුරු ලබාගත් සෑම සබැඳියක්ම යොමු කිරීමට උත්සාහ කර ඇත. ඔබ අතුරුදහන් වී ඇත්නම් ඇතුළත් කිරීමට අවශ්ය නම් කරුණාකර අදහස් දක්වන්න!
Build
මෙහෙයුම් පද්ධතිය යාවත්කාලීන කිරීම මත පන්ති වෙනස්? විශේෂයෙන් API යාවත්කාලීන වී ඇත්නම්? එසේ නම්, මෙය අද්විතීය යැයි ඔබ සහතික කරන්නේ කෙසේද? (ඔබ ලියූ ක්රමය ගැන කතා කිරීම)
ඩේව් වෙබ් සඳහන් කළ පරිදි, ඇන්ඩ්රොයිඩ් සංවර්ධක බ්ලොග් අඩවියේ මෙය ආවරණය වන ලිපියක් ඇත. ඔවුන්ගේ ප්රියතම විසඳුම වන්නේ උපාංගවලට වඩා යෙදුම් ස්ථාපනයන් නිරීක්ෂණය කිරීමයි, එය බොහෝ භාවිත අවස්ථා සඳහා හොඳින් ක්රියා කරයි. බ්ලොග් පෝස්ට් මඟින් එම කාර්යය කිරීමට අවශ්ය කේතය ඔබට පෙන්වනු ඇති අතර එය පරීක්ෂා කර බැලීමට මම ඔබට නිර්දේශ කරමි.
කෙසේ වෙතත්, බ්ලොග් පෝස්ට් ඔබට යෙදුම් ස්ථාපන හඳුනාගැනීමට වඩා උපාංග හඳුනාගැනීමක් අවශ්ය නම් විසඳුම් සාකච්ඡා කරයි. ඔබට එසේ කිරීමට අවශ්ය වූ විට අයිතම කිහිපයක් පිළිබඳව අමතර පැහැදිලි කිරීමක් ලබා ගැනීමට මම ගූගල්හි කෙනෙකු සමඟ කතා කළෙමි. ඉහත සඳහන් බ්ලොග් සටහනේ සඳහන් නොවන උපාංග හඳුනාගැනීම් ගැන මා සොයාගත් දේ මෙන්න:
ගූගල්ගේ නිර්දේශ මත පදනම්ව, මම සෑම උපාංගයක් සඳහාම අද්විතීය UUID ජනනය කරන පන්තියක් ක්රියාත්මක කළෙමි, සුදුසු අවස්ථාවන්හිදී ANDROID_ID භාවිතා කරමින්, අවශ්ය පරිදි TelephonyManager.getDeviceId () වෙත ආපසු යමි, එය අසමත් වුවහොත් අහඹු ලෙස ජනනය කරන ලද අද්විතීය UUID වෙත යොමු වන්න. යෙදුම් නැවත ආරම්භ කිරීම හරහා එය දිගටම පවතී (නමුත් යෙදුම් නැවත ස්ථාපනය කිරීම නොවේ).
උපාංගය ID මත fallback කිරීමට ඇති බව උපාංග සඳහා, අනුපම ID බව සටහන ඇත කර්මාන්ත ඵ්රකෘති හරහා ශරීරය. මෙය දැනුවත් විය යුතු දෙයකි. කර්මාන්තශාලා යළි පිහිටුවීම ඔබගේ අද්විතීය හැඳුනුම්පත යළි පිහිටුවනු ඇති බවට ඔබට සහතික වීමට අවශ්ය නම්, උපාංග හැඳුනුම්පත වෙනුවට අහඹු UUID වෙත කෙලින්ම වැටීම සලකා බැලීමට ඔබට අවශ්ය විය හැකිය.
නැවතත්, මෙම කේතය උපාංග හැඳුනුම්පතක් සඳහා මිස යෙදුම් ස්ථාපන හැඳුනුම්පතක් සඳහා නොවේ. බොහෝ අවස්ථාවන් සඳහා, යෙදුම් ස්ථාපන හැඳුනුම්පත බොහෝ විට ඔබ සොයන දෙයයි. නමුත් ඔබට උපාංග හැඳුනුම්පතක් අවශ්ය නම්, පහත කේතය ඔබ වෙනුවෙන් වැඩ කරනු ඇත.
import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
public class DeviceUuidFactory {
protected static final String PREFS_FILE = "device_id.xml";
protected static final String PREFS_DEVICE_ID = "device_id";
protected volatile static UUID uuid;
public DeviceUuidFactory(Context context) {
if (uuid == null) {
synchronized (DeviceUuidFactory.class) {
if (uuid == null) {
final SharedPreferences prefs = context
.getSharedPreferences(PREFS_FILE, 0);
final String id = prefs.getString(PREFS_DEVICE_ID, null);
if (id != null) {
// Use the ids previously computed and stored in the
// prefs file
uuid = UUID.fromString(id);
} else {
final String androidId = Secure.getString(
context.getContentResolver(), Secure.ANDROID_ID);
// Use the Android ID unless it's broken, in which case
// fallback on deviceId,
// unless it's not available, then fallback on a random
// number which we store to a prefs file
try {
if (!"9774d56d682e549c".equals(androidId)) {
uuid = UUID.nameUUIDFromBytes(androidId
.getBytes("utf8"));
} else {
final String deviceId = (
(TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE))
.getDeviceId();
uuid = deviceId != null ? UUID
.nameUUIDFromBytes(deviceId
.getBytes("utf8")) : UUID
.randomUUID();
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
// Write the value out to the prefs file
prefs.edit()
.putString(PREFS_DEVICE_ID, uuid.toString())
.commit();
}
}
}
}
}
/**
* Returns a unique UUID for the current android device. As with all UUIDs,
* this unique ID is "very highly likely" to be unique across all Android
* devices. Much more so than ANDROID_ID is.
*
* The UUID is generated by using ANDROID_ID as the base key if appropriate,
* falling back on TelephonyManager.getDeviceID() if ANDROID_ID is known to
* be incorrect, and finally falling back on a random UUID that's persisted
* to SharedPreferences if getDeviceID() does not return a usable value.
*
* In some rare circumstances, this ID may change. In particular, if the
* device is factory reset a new device ID may be generated. In addition, if
* a user upgrades their phone from certain buggy implementations of Android
* 2.2 to a newer, non-buggy version of Android, the device ID may change.
* Or, if a user uninstalls your app on a device that has neither a proper
* Android ID nor a Device ID, this ID may change on reinstallation.
*
* Note that if the code falls back on using TelephonyManager.getDeviceId(),
* the resulting ID will NOT change after a factory reset. Something to be
* aware of.
*
* Works around a bug in Android 2.2 for many devices when using ANDROID_ID
* directly.
*
* @see http://code.google.com/p/android/issues/detail?id=10603
*
* @return a UUID that may be used to uniquely identify your device for most
* purposes.
*/
public UUID getDeviceUuid() {
return uuid;
}
}
පරිශීලකයා සඳහා අද්විතීය හැඳුනුම්පතක් ලබා ගැනීම සඳහා මේ වසරේ ගූගල් අයි / ඕ ඉදිරිපත් කිරීමේ දී රෙටෝ මයර් භාවිතා කළ කේතය මෙන්න :
private static String uniqueID = null;
private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
public synchronized static String id(Context context) {
if (uniqueID == null) {
SharedPreferences sharedPrefs = context.getSharedPreferences(
PREF_UNIQUE_ID, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
if (uniqueID == null) {
uniqueID = UUID.randomUUID().toString();
Editor editor = sharedPrefs.edit();
editor.putString(PREF_UNIQUE_ID, uniqueID);
editor.commit();
}
}
return uniqueID;
}
වලාකුළට මනාපයන් යැවීම සඳහා උපස්ථ උපාය මාර්ගයක් සමඟ ඔබ මෙය යුවළක් නම් (රෙටෝගේ කතාවේ ද විස්තර කර ඇත , ඔබට පරිශීලකයෙකු සමඟ සම්බන්ධ වන හැඳුනුම්පතක් තිබිය යුතු අතර උපාංගය අතුගා දැමීමෙන් පසුව හෝ ප්රතිස්ථාපනය කිරීමෙන් පසුවද රැඳී සිටිය යුතුය. මම මෙය භාවිතා කිරීමට අදහස් කරමි විශ්ලේෂණ ඉදිරියට යන විට (වෙනත් වචන වලින් කිවහොත්, මම තවම එය කර නැත :).
ඔබට Wi-Fi ඇඩැප්ටරයේ MAC ලිපිනයද සලකා බැලිය හැකිය. සම්ප්රවේශය මේ ආකාරයට:
WifiManager wm = (WifiManager)Ctxt.getSystemService(Context.WIFI_SERVICE);
return wm.getConnectionInfo().getMacAddress();
android.permission.ACCESS_WIFI_STATE
මැනිෆෙස්ටයේ අවසරය අවශ්යයි .
Wi-Fi සම්බන්ධ නොවූ විට පවා ලබා ගත හැකි බවට වාර්තා වේ. ඉහත පිළිතුරෙන් ජෝ මේ සඳහා ඔහුගේ බොහෝ උපාංගයන් උත්සාහ කර බැලුවහොත් එය හොඳයි.
සමහර උපාංගවල, Wi-Fi අක්රිය කළ විට එය ලබාගත නොහැක.
සටහන: Android 6.x වෙතින්, එය ස්ථාවර ව්යාජ මැක් ලිපිනයක් ලබා දෙයි:02:00:00:00:00:00
android.permission.ACCESS_WIFI_STATE
02:00:00:00:00:00
මෙහි තරමක් ප්රයෝජනවත් තොරතුරු තිබේ .
එය විවිධ හැඳුනුම් වර්ග පහක් ආවරණය කරයි:
android.permission.READ_PHONE_STATE
)android.permission.ACCESS_WIFI_STATE
)android.permission.BLUETOOTH
)නිල ඇන්ඩ්රොයිඩ් සංවර්ධකයින්ගේ බ්ලොග් අඩවියේ දැන් යෙදුම් ස්ථාපනයන් හදුනා ගැනීම පිළිබඳ සම්පූර්ණ ලිපියක් ඇත .
දී ගූගල් I / O Reto Meier ස්ථාපනය හරහා භාවිතා කරන්නන් නිරීක්ෂණය කිරීමට බොහෝ ඉදිකරන්නන්ට අවශ්යතා සපුරාලීමට යුතු මෙම යොමුවීම සඳහා ශක්තිමත් පිළිතුර නිකුත් කරන ලදී. ඇන්තනි නොලන් ඔහුගේ පිළිතුරේ දිශාව පෙන්වයි, නමුත් මම සිතුවේ සම්පූර්ණ ප්රවේශය ලිවීමට මම සිතුවෙමි එවිට අනෙක් අයට එය කරන්නේ කෙසේදැයි පහසුවෙන් දැක ගත හැකි වනු ඇත (විස්තර දැන ගැනීමට මට යම් කාලයක් ගත විය).
මෙම ප්රවේශය මඟින් ඔබට නිර්නාමික, ආරක්ෂිත පරිශීලක හැඳුනුම්පතක් ලබා දෙනු ඇති අතර එය පරිශීලකයාට විවිධ උපාංග හරහා (ප්රාථමික ගූගල් ගිණුම මත පදනම්ව) සහ ස්ථාපනයන් හරහා නොනැසී පවතිනු ඇත. මූලික ප්රවේශය වන්නේ අහඹු පරිශීලක හැඳුනුම්පතක් ජනනය කිරීම සහ යෙදුම්වල හවුල් මනාපයන් තුළ මෙය ගබඩා කිරීමයි. ඉන්පසු ඔබ ගූගල් ගිණුමට සම්බන්ධිත හවුල් මනාපයන් වලාකුළෙහි ගබඩා කිරීමට ගූගල්හි උපස්ථ නියෝජිතයා භාවිතා කරයි.
අපි සම්පූර්ණ ප්රවේශය හරහා යමු. පළමුව, අපි ඇන්ඩ්රොයිඩ් උපස්ථ සේවාව භාවිතා කරමින් අපගේ SharedPreferences සඳහා උපස්ථයක් සෑදිය යුතුය. ඔබගේ යෙදුම ලියාපදිංචි කිරීමෙන් ආරම්භ කරන්නhttp://developer.android.com/google/backup/signup.html
.
මැනිෆෙස්ටයට එකතු කිරීමට අවශ්ය උපස්ථ සේවා යතුරක් ගූගල් ඔබට ලබා දෙනු ඇත. පහත දැක්වෙන පරිදි BackupAgent භාවිතා කිරීමට ඔබ යෙදුමට පැවසිය යුතුය:
<application android:label="MyApplication"
android:backupAgent="MyBackupAgent">
...
<meta-data android:name="com.google.android.backup.api_key"
android:value="your_backup_service_key" />
</application>
එවිට ඔබට උපස්ථ නියෝජිතයා සෑදිය යුතු අතර හවුල් මනාපයන් සඳහා සහායක නියෝජිතයා භාවිතා කිරීමට එය කියන්න:
public class MyBackupAgent extends BackupAgentHelper {
// The name of the SharedPreferences file
static final String PREFS = "user_preferences";
// A key to uniquely identify the set of backup data
static final String PREFS_BACKUP_KEY = "prefs";
// Allocate a helper and add it to the backup agent
@Override
public void onCreate() {
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS);
addHelper(PREFS_BACKUP_KEY, helper);
}
}
උපස්ථය සම්පූර්ණ කිරීම සඳහා ඔබේ ප්රධාන ක්රියාකාරකම තුළ BackupManager හි උදාහරණයක් නිර්මාණය කළ යුතුය:
BackupManager backupManager = new BackupManager(context);
අවසාන වශයෙන් පරිශීලක හැඳුනුම්පතක් සාදන්න, එය දැනටමත් නොපවතී නම්, එය SharedPreferences හි ගබඩා කරන්න:
public static String getUserID(Context context) {
private static String uniqueID = null;
private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
if (uniqueID == null) {
SharedPreferences sharedPrefs = context.getSharedPreferences(
MyBackupAgent.PREFS, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
if (uniqueID == null) {
uniqueID = UUID.randomUUID().toString();
Editor editor = sharedPrefs.edit();
editor.putString(PREF_UNIQUE_ID, uniqueID);
editor.commit();
//backup the changes
BackupManager mBackupManager = new BackupManager(context);
mBackupManager.dataChanged();
}
}
return uniqueID;
}
පරිශීලකයා උපාංගය ගෙන ගියත්, මෙම User_ID දැන් ස්ථාපනයන් හරහා නොනැසී පවතිනු ඇත.
මෙම ප්රවේශය පිළිබඳ වැඩි විස්තර සඳහා රෙටෝගේ කතාව බලන්න .
උපස්ථ නියෝජිතයා ක්රියාත්මක කරන්නේ කෙසේද යන්න පිළිබඳ සම්පූර්ණ විස්තර සඳහා දත්ත උපස්ථ බලන්න . උපස්ථය ක්ෂණිකව සිදු නොවන බැවින් පරීක්ෂා කිරීම සඳහා පතුලේ ඇති කොටස මම විශේෂයෙන් නිර්දේශ කරමි. එබැවින් පරීක්ෂා කිරීමට ඔබට උපස්ථය බල කළ යුතුය.
අද්විතීය හැඳුනුම්පතක් සඳහා ඇටසැකිල්ලක් තැනීමේ ගිනි නිවීමේ ක්රමයක් මෙය යැයි මම සිතමි ... එය පරීක්ෂා කරන්න.
සියලුම ඇන්ඩ්රොයිඩ් උපාංගවල ක්රියා කරන ව්යාජ-අද්විතීය හැඳුනුම්පත සමහර උපාංගවලට දුරකථනයක් නොමැත (උදා: ටැබ්ලට්) හෝ යම් හේතුවක් නිසා ඔබට READ_PHONE_STATE අවසරය ඇතුළත් කිරීමට අවශ්ය නැත. ඔබට තවමත් ROM අනුවාදය, නිෂ්පාදකයාගේ නම, CPU වර්ගය සහ වෙනත් දෘඩාංග විස්තර වැනි තොරතුරු කියවිය හැකිය, ඔබට අනුක්රමික යතුරු පරීක්ෂණයක් සඳහා හෝ වෙනත් පොදු අරමුණු සඳහා හැඳුනුම්පත භාවිතා කිරීමට අවශ්ය නම් එය හොඳින් ගැලපේ. මේ ආකාරයෙන් ගණනය කරන ලද හැඳුනුම්පත අද්විතීය නොවනු ඇත: එකම හැඳුනුම්පතක් සහිත උපාංග දෙකක් (එකම දෘඩාංග හා ROM රූපය මත පදනම්ව) සොයාගත හැකි නමුත් සැබෑ ලෝකයේ යෙදුම්වල වෙනස්කම් නොසැලකිය. මේ සඳහා ඔබට ගොඩනැගීමේ පන්තිය භාවිතා කළ හැකිය:
String m_szDevIDShort = "35" + //we make this look like a valid IMEI
Build.BOARD.length()%10+ Build.BRAND.length()%10 +
Build.CPU_ABI.length()%10 + Build.DEVICE.length()%10 +
Build.DISPLAY.length()%10 + Build.HOST.length()%10 +
Build.ID.length()%10 + Build.MANUFACTURER.length()%10 +
Build.MODEL.length()%10 + Build.PRODUCT.length()%10 +
Build.TAGS.length()%10 + Build.TYPE.length()%10 +
Build.USER.length()%10 ; //13 digits
බිල්ඩ් සාමාජිකයින්ගෙන් බොහෝ දෙනෙක් නූල් වේ, අප මෙහි කරන්නේ ඔවුන්ගේ දිග ගෙන එය මොඩියුලෝ හරහා ඉලක්කම් වලින් පරිවර්තනය කිරීමයි. අපට එවැනි ඉලක්කම් 13 ක් ඇති අතර IMEI (ඉලක්කම් 15) හා සමාන ප්රමාණයේ හැඳුනුම්පතක් ලබා ගැනීම සඳහා අපි තවත් දෙකක් (35) ඉදිරියෙන් තබමු. මෙහි වෙනත් හැකියාවන් ඇත, මෙම නූල් දෙස බලන්න. වැනි දෙයක් ලබා දෙයි 355715565309247
. විශේෂ අවසරයක් අවශ්ය නොවන අතර මෙම ප්රවේශය ඉතා පහසු කරයි.
(අමතර තොරතුරු: ඉහත දක්වා ඇති තාක්ෂණය පොකට් මැජික් පිළිබඳ ලිපියකින් පිටපත් කරන ලදි .)
පහත කේතය සැඟවුණු ඇන්ඩ්රොයිඩ් API භාවිතා කරමින් උපාංග අනුක්රමික අංකය ලබා දෙයි. නමුත්, මෙම කේතය සැම්සුන්ග් ගැලැක්සි ටැබ් එකෙහි ක්රියා නොකරන්නේ මෙම උපාංගයේ "ro.serialno" සකසා නොමැති බැවිනි.
String serial = null;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
}
catch (Exception ignored) {
}
ro.serialno
ජනනය කිරීමට භාවිතා කරන xda සංවර්ධකයේ කියෙව්වා Settings.Secure.ANDROID_ID
. එබැවින් ඒවා මූලික වශයෙන් එකම අගයේ වෙනස් නිරූපණයන් වේ.
ANDROID_ID
ගනී.
android.os.Build.SERIAL
android.os.Build.SERIAL
ඇන්ඩ්රොයිඩ් ඕ හි ඉවත් කරනු ලැබේ, android-developers.googleblog.com/2017/04/…
එය සරල පිළිතුරක් නොමැතිව සරල ප්රශ්නයකි.
ඊටත් වඩා, මෙහි පවතින සියලුම පිළිතුරු යල්පැනගිය හෝ විශ්වාස කළ නොහැකි ඒවා ය.
එබැවින් ඔබ 2020 දී විසඳුමක් සොයන්නේ නම් .
මතක තබා ගත යුතු කරුණු කිහිපයක් මෙන්න:
සියලුම දෘඩාංග පාදක හඳුනාගැනීම් (SSAID, IMEI, MAC, ආදිය) ගූගල් නොවන උපාංග සඳහා විශ්වාස කළ නොහැකි ය (පික්සෙල් සහ නෙක්සස් හැර සියල්ල), ඒවා ලොව පුරා ක්රියාකාරී උපාංගවලින් 50% කට වඩා වැඩිය. එබැවින් නිල ඇන්ඩ්රොයිඩ් හඳුනාගැනීම් හොඳම භාවිතයන් පැහැදිලිව සඳහන් කරයි:
SSAID (Android ID), IMEI, MAC ලිපිනය වැනි දෘඩාංග හඳුනාගැනීම් භාවිතා කිරීමෙන් වළකින්න ...
එමඟින් ඉහත පිළිතුරු බොහෝමයක් අවලංගු වේ. විවිධ ඇන්ඩ්රොයිඩ් ආරක්ෂණ යාවත්කාල කිරීම් හේතුවෙන්, ඒවායින් සමහරක් සඳහා නව සහ දැඩි ධාවන කාල අවසරයන් අවශ්ය වන අතර ඒවා පරිශීලකයාට ප්රතික්ෂේප කළ හැකිය.
උදාහරණයක් ලෙස CVE-2018-9489
ඉහත සඳහන් කළ සියලුම WIFI පදනම් කරගත් ශිල්පීය ක්රමවලට බලපාන .
එමගින් එම හඳුනාගැනීම් විශ්වාස කළ නොහැකි පමණක් නොව බොහෝ අවස්ථාවන්හිදී ප්රවේශ විය නොහැක.
එබැවින් සරල වචන වලින්: එම ශිල්පීය ක්රම භාවිතා නොකරන්න .
මෙහි ඇති තවත් බොහෝ පිළිතුරු යෝජනා කරන්නේ AdvertisingIdClient
, එය නොගැලපෙන බැවින් එහි සැලසුම අනුව දැන්වීම් පැතිකඩ සඳහා පමණක් භාවිතා කළ යුතු බවයි. එය නිල සඳහනෙහි ද සඳහන් වේ
පරිශීලක පැතිකඩ සඳහා දැන්වීම් දැන්වීම් හැඳුනුම්පතක් පමණක් භාවිතා කරන්න
එය උපාංග හඳුනා ගැනීම සඳහා විශ්වාසදායක නොවනවා පමණක් නොව, දැන්වීම් ලුහුබැඳීමේ ප්රතිපත්තිය සම්බන්ධයෙන් ඔබ පරිශීලකගේ පෞද්ගලිකත්වය අනුගමනය කළ යුතුය , එයින් පැහැදිලිව සඳහන් වන්නේ ඕනෑම මොහොතක එය නැවත සැකසීමට හෝ අවහිර කිරීමට පරිශීලකයාට හැකි බවයි.
එබැවින් එය භාවිතා නොකරන්න .
ඔබට අපේක්ෂිත ස්ථිතික ගෝලීය අද්විතීය සහ විශ්වාසදායක උපාංග හඳුනාගැනීමක් තිබිය නොහැකි බැවින්. ඇන්ඩ්රොයිඩ් හි නිල සඳහන යෝජනා කරන්නේ:
ගෙවීම් වංචා වැළැක්වීම සහ දුරකථන ඇමතුම් හැර අනෙකුත් සියලුම භාවිත අවස්ථා සඳහා හැකි සෑම විටම ෆයර්බේස් ඉන්ස්ටැන්ස් අයිඩ් හෝ පුද්ගලිකව ගබඩා කර ඇති GUID භාවිතා කරන්න.
උපාංගයේ යෙදුම් ස්ථාපනය සඳහා එය අද්විතීය වේ, එබැවින් පරිශීලකයා යෙදුම අස්ථාපනය කරන විට - එය අතුගා දමනු ලැබේ, එබැවින් එය 100% විශ්වාසදායක නොවේ, නමුත් එය ඊළඟ හොඳම දේ වේ.
භාවිතා FirebaseInstanceId
කිරීමට ඔබගේ ශ්රේණියට නවතම ෆයර්බේස්-පණිවිඩ යැපීම එක් කරන්න
implementation 'com.google.firebase:firebase-messaging:20.2.0'
පසුබිම් නූලක පහත කේතය භාවිතා කරන්න:
String reliableIdentifier = FirebaseInstanceId.getInstance().getId();
ඔබගේ දුරස්ථ සේවාදායකයේ උපාංග හඳුනාගැනීම ගබඩා කිරීමට ඔබට අවශ්ය නම්, එය (සරල පෙළ) මෙන් ගබඩා නොකරන්න, නමුත් ලුණු සහිත හැෂ් .
අද එය හොඳම භාවිතයක් පමණක් නොව, දළ දේශීය නිෂ්පාදිතයට අනුව නීතියෙන් එය කළ යුතුය - හඳුනාගැනීම් සහ ඒ හා සමාන රෙගුලාසි.
පහත කේතය භාවිතා කරමින්, ඔබට ඇන්ඩ්රොයිඩ් ඕඑස් උපාංගයක අද්විතීය උපාංග හැඳුනුම්පත නූලක් ලෙස ලබා ගත හැකිය.
deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID);
සඳහා අනුක්රමික ක්ෂේත්රයක් එක් කරන ලදිBuild
API මට්ටමේ 9 (ඇන්ඩ්රොයිඩ් 2.3 - ජින්ජර් බ්රෙඩ්) පන්තියට . ප්රලේඛනය පවසන්නේ එය දෘඩාංග අනුක්රමික අංකය නියෝජනය කරන බවයි. මේ අනුව එය උපාංගයේ තිබේ නම් එය අද්විතීය විය යුතුය.
ඒපීඅයි මට්ටම> = 9 සහිත සියලුම උපාංග මගින් එය සැබවින්ම සහය දක්වයිදැයි මම නොදනිමි.
මම එකතු කරන එක් දෙයක් - මට එවැනි සුවිශේෂී අවස්ථාවන්ගෙන් එකක් තිබේ.
භාවිතා කිරීම:
deviceId = Secure.getString(this.getContext().getContentResolver(), Secure.ANDROID_ID);
මගේ Viewsonic G ටැබ්ලටය ශුන්ය නොවන DeviceID එකක් වාර්තා කළද, සෑම G ටැබ්ලටයක්ම එකම සංඛ්යාවක් වාර්තා කරයි.
"අද්විතීය" DeviceID මත පදනම්ව යමෙකුගේ ගිණුමට ක්ෂණික ප්රවේශයක් ලබා දෙන "පොකට් එම්පයර්ස්" සෙල්ලම් කිරීම සිත්ගන්නාසුළු කරයි.
මගේ උපාංගයට සෛල රේඩියෝවක් නොමැත.
9774d56d682e549c
?
ඔබේ යෙදුම ස්ථාපනය කර ඇති සෑම ඇන්ඩ්රොයිඩ් උපාංගයක් සඳහාම අනන්යතා හඳුනාගැනීමක් ලබා ගන්නේ කෙසේද යන්න පිළිබඳ සවිස්තරාත්මක උපදෙස් සඳහා, නිල ඇන්ඩ්රොයිඩ් සංවර්ධකයින්ගේ බ්ලොග් පෝස්ට් බලන්න යෙදුම් ස්ථාපනය හඳුනා ගැනීම .
ස්ථාපනයෙන් පසු ඔබම උත්පාදනය කර යෙදුම නැවත දියත් කළ විට එය කියවීම හොඳම ක්රමය බව පෙනේ.
මම පෞද්ගලිකව මෙය පිළිගත හැකි නමුත් පරමාදර්ශී නොවේ. බොහෝ විට දුරකථනයේ ගුවන්විදුලි තත්වයන් මත රඳා පවතින බැවින් ඇන්ඩ්රොයිඩ් විසින් සපයන ලද කිසිදු හඳුනාගැනීමක් ක්රියා නොකරයි (Wi-Fi සක්රිය / අක්රීය, සෙලියුලර් සක්රිය / අක්රිය, බ්ලූටූත් සක්රිය / අක්රිය). අනෙක් Settings.Secure.ANDROID_ID
ඒවා නිෂ්පාදකයා විසින් ක්රියාත්මක කළ යුතු අතර ඒවා අද්විතීය බව සහතික නොවේ.
පහත දැක්වෙන්නේ ස්ථාපනය දේශීයව සුරකින වෙනත් දත්ත සමඟ ගබඩා කරන ස්ථාපන ගොනුවකට දත්ත ලිවීමේ උදාහරණයකි .
public class Installation {
private static String sID = null;
private static final String INSTALLATION = "INSTALLATION";
public synchronized static String id(Context context) {
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists())
writeInstallationFile(installation);
sID = readInstallationFile(installation);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
return sID;
}
private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}
private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}
පන්ති ගොනුවේ පහත කේතය එක් කරන්න:
final TelephonyManager tm = (TelephonyManager) getBaseContext()
.getSystemService(SplashActivity.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
Log.v("DeviceIMEI", "" + tmDevice);
tmSerial = "" + tm.getSimSerialNumber();
Log.v("GSM devices Serial Number[simcard] ", "" + tmSerial);
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(),
android.provider.Settings.Secure.ANDROID_ID);
Log.v("androidId CDMA devices", "" + androidId);
UUID deviceUuid = new UUID(androidId.hashCode(),
((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
Log.v("deviceIdUUID universally unique identifier", "" + deviceId);
String deviceModelName = android.os.Build.MODEL;
Log.v("Model Name", "" + deviceModelName);
String deviceUSER = android.os.Build.USER;
Log.v("Name USER", "" + deviceUSER);
String devicePRODUCT = android.os.Build.PRODUCT;
Log.v("PRODUCT", "" + devicePRODUCT);
String deviceHARDWARE = android.os.Build.HARDWARE;
Log.v("HARDWARE", "" + deviceHARDWARE);
String deviceBRAND = android.os.Build.BRAND;
Log.v("BRAND", "" + deviceBRAND);
String myVersion = android.os.Build.VERSION.RELEASE;
Log.v("VERSION.RELEASE", "" + myVersion);
int sdkVersion = android.os.Build.VERSION.SDK_INT;
Log.v("VERSION.SDK_INT", "" + sdkVersion);
AndroidManifest.xml හි එක් කරන්න:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
TelephonyManager
සහ ANDROID_ID
ලබා ගන්නේ:String deviceId;
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId();
}
else {
deviceId = Secure.getString(
getApplicationContext().getContentResolver(),
Secure.ANDROID_ID);
}
නමුත් ගූගල් විසින් යෝජනා කරන ලද ක්රමවේදයක් මම තරයේ නිර්දේශ කරමි, යෙදුම් ස්ථාපනය හඳුනා ගැනීම බලන්න .
වාසි සහ අවාසි සමඟ එම ANDROID_ID
ගැටළු විසඳීම සඳහා විවිධ ප්රවේශයන් රාශියක් ඇත ( null
සමහර විට හෝ නිශ්චිත ආකෘතියක උපාංග සෑම විටම එකම හැඳුනුම්පත ලබා දෙයි):
ඇන්ඩ්රොයිඩ් සඳහා දැනට පවතින OpenUDID ක්රියාත්මක කිරීමක් භාවිතා කිරීමට මම කැමැත්තෙමි ( https://github.com/ylechelle/OpenUDID බලන්න ) ( https://github.com/vieux/OpenUDID බලන්න ). ඒකාබද්ධ කිරීම පහසු වන අතර ANDROID_ID
ඉහත සඳහන් කර ඇති ගැටළු සඳහා පසුබෑම සමඟ භාවිතා කරයි .
කොහොමද IMEI ගැන . එය ඇන්ඩ්රොයිඩ් හෝ වෙනත් ජංගම උපාංග සඳහා අද්විතීය වේ.
මෙන්න මම අද්විතීය හැඳුනුම්පත ජනනය කරන්නේ කෙසේද:
public static String getDeviceId(Context ctx)
{
TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
String tmDevice = tm.getDeviceId();
String androidId = Secure.getString(ctx.getContentResolver(), Secure.ANDROID_ID);
String serial = null;
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) serial = Build.SERIAL;
if(tmDevice != null) return "01" + tmDevice;
if(androidId != null) return "02" + androidId;
if(serial != null) return "03" + serial;
// other alternatives (i.e. Wi-Fi MAC, Bluetooth MAC, etc.)
return null;
}
මගේ ශත දෙක - සැ.යු: මෙය උපාංගයක් (වැරදි) අද්විතීය හැඳුනුම්පතක් සඳහා ය - ඇන්ඩ්රොයිඩ් සංවර්ධකයින්ගේ බ්ලොග් අඩවියේ සාකච්ඡා කර ඇති පරිදි ස්ථාපනය නොවේ .
නෝට්ටුවේ බව විසඳුමක් @emmby විසින් සපයන නැවත එක් එක් අයදුම්පත හැඳුනුම්පත යෙදෙන (දකින SharedPreferences ක්රියාවලිය හරහා සමමුහුර්ත නොමැත ලෙස මෙහි හා මෙහි ). ඒ නිසා මම මෙය සම්පූර්ණයෙන්ම මග හැරියෙමි.
ඒ වෙනුවට, මම (උපාංග) හැඳුනුම්පතක් ලබා ගැනීම සඳහා විවිධ උපක්රම උපයෝගී කර ගතිමි - එනුම් නියතයන්ගේ අනුපිළිවෙල වෙනස් කිරීම හැඳුනුම්පත ලබා ගැනීමේ විවිධ ක්රමවල ප්රමුඛතාවයට බලපායි. පළමු ශුන්ය නොවන හැඳුනුම්පත ආපසු ලබා දීම හෝ ව්යතිරේකයක් විසි කිරීම (ශුන්ය අර්ථයක් ලබා නොදීමේ හොඳ ජාවා භාවිතයන්ට අනුව). උදාහරණයක් ලෙස මට පළමුව ටෙලිෆෝනය තිබේ - නමුත් හොඳ පෙරනිමි තේරීමක් වනුයේ ANDROID_ID බීටා:
import android.Manifest.permission;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;
// TODO : hash
public final class DeviceIdentifier {
private DeviceIdentifier() {}
/** @see http://code.google.com/p/android/issues/detail?id=10603 */
private static final String ANDROID_ID_BUG_MSG = "The device suffers from "
+ "the Android ID bug - its ID is the emulator ID : "
+ IDs.BUGGY_ANDROID_ID;
private static volatile String uuid; // volatile needed - see EJ item 71
// need lazy initialization to get a context
/**
* Returns a unique identifier for this device. The first (in the order the
* enums constants as defined in the IDs enum) non null identifier is
* returned or a DeviceIDException is thrown. A DeviceIDException is also
* thrown if ignoreBuggyAndroidID is false and the device has the Android ID
* bug
*
* @param ctx
* an Android constant (to retrieve system services)
* @param ignoreBuggyAndroidID
* if false, on a device with the android ID bug, the buggy
* android ID is not returned instead a DeviceIDException is
* thrown
* @return a *device* ID - null is never returned, instead a
* DeviceIDException is thrown
* @throws DeviceIDException
* if none of the enum methods manages to return a device ID
*/
public static String getDeviceIdentifier(Context ctx,
boolean ignoreBuggyAndroidID) throws DeviceIDException {
String result = uuid;
if (result == null) {
synchronized (DeviceIdentifier.class) {
result = uuid;
if (result == null) {
for (IDs id : IDs.values()) {
try {
result = uuid = id.getId(ctx);
} catch (DeviceIDNotUniqueException e) {
if (!ignoreBuggyAndroidID)
throw new DeviceIDException(e);
}
if (result != null) return result;
}
throw new DeviceIDException();
}
}
}
return result;
}
private static enum IDs {
TELEPHONY_ID {
@Override
String getId(Context ctx) {
// TODO : add a SIM based mechanism ? tm.getSimSerialNumber();
final TelephonyManager tm = (TelephonyManager) ctx
.getSystemService(Context.TELEPHONY_SERVICE);
if (tm == null) {
w("Telephony Manager not available");
return null;
}
assertPermission(ctx, permission.READ_PHONE_STATE);
return tm.getDeviceId();
}
},
ANDROID_ID {
@Override
String getId(Context ctx) throws DeviceIDException {
// no permission needed !
final String andoidId = Secure.getString(
ctx.getContentResolver(),
android.provider.Settings.Secure.ANDROID_ID);
if (BUGGY_ANDROID_ID.equals(andoidId)) {
e(ANDROID_ID_BUG_MSG);
throw new DeviceIDNotUniqueException();
}
return andoidId;
}
},
WIFI_MAC {
@Override
String getId(Context ctx) {
WifiManager wm = (WifiManager) ctx
.getSystemService(Context.WIFI_SERVICE);
if (wm == null) {
w("Wifi Manager not available");
return null;
}
assertPermission(ctx, permission.ACCESS_WIFI_STATE); // I guess
// getMacAddress() has no java doc !!!
return wm.getConnectionInfo().getMacAddress();
}
},
BLUETOOTH_MAC {
@Override
String getId(Context ctx) {
BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
if (ba == null) {
w("Bluetooth Adapter not available");
return null;
}
assertPermission(ctx, permission.BLUETOOTH);
return ba.getAddress();
}
}
// TODO PSEUDO_ID
// http://www.pocketmagic.net/2011/02/android-unique-device-id/
;
static final String BUGGY_ANDROID_ID = "9774d56d682e549c";
private final static String TAG = IDs.class.getSimpleName();
abstract String getId(Context ctx) throws DeviceIDException;
private static void w(String msg) {
Log.w(TAG, msg);
}
private static void e(String msg) {
Log.e(TAG, msg);
}
}
private static void assertPermission(Context ctx, String perm) {
final int checkPermission = ctx.getPackageManager().checkPermission(
perm, ctx.getPackageName());
if (checkPermission != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Permission " + perm + " is required");
}
}
// =========================================================================
// Exceptions
// =========================================================================
public static class DeviceIDException extends Exception {
private static final long serialVersionUID = -8083699995384519417L;
private static final String NO_ANDROID_ID = "Could not retrieve a "
+ "device ID";
public DeviceIDException(Throwable throwable) {
super(NO_ANDROID_ID, throwable);
}
public DeviceIDException(String detailMessage) {
super(detailMessage);
}
public DeviceIDException() {
super(NO_ANDROID_ID);
}
}
public static final class DeviceIDNotUniqueException extends
DeviceIDException {
private static final long serialVersionUID = -8940090896069484955L;
public DeviceIDNotUniqueException() {
super(ANDROID_ID_BUG_MSG);
}
}
}
මෙහි පිළිතුරු 30+ ක් ඇති අතර සමහර ඒවා සමාන වන අතර සමහර ඒවා අද්විතීය වේ. මෙම පිළිතුර පදනම් වී ඇත්තේ එම පිළිතුරු කිහිපයක් මත ය. ඔවුන්ගෙන් එක් කෙනෙක් @ ලෙන් ඩොලිංගේ පිළිතුර.
එය හැඳුනුම්පත් 3 ක් ඒකාබද්ධ කර ඉලක්කම් 32 ක හෙක්ස් නූලක් නිර්මාණය කරයි. එය මට ඉතා හොඳින් වැඩ කර ඇත.
හැඳුනුම්පත් 3 ක්:
ව්යාජ හැඳුනුම්පත - එය ජනනය කරනු ලබන්නේ භෞතික උපාංග පිරිවිතර මත පදනම්ව
ANDROID_ID - Settings.Secure.ANDROID_ID
බ්ලූටූත් ලිපිනය - බ්ලූටූත් ඇඩැප්ටර ලිපිනය
එය මෙවැනි දෙයක් නැවත ලබා දෙනු ඇත: 551F27C060712A72730B0A0F734064B1
සටහන: ඔබට සෑම විටම නූලට තවත් හැඳුනුම්පත් එකතු කළ හැකිය longId
. උදාහරණයක් ලෙස, අනුක්රමික #. wifi ඇඩැප්ටර ලිපිනය. IMEI. මේ ආකාරයෙන් ඔබ එය එක් උපාංගයකට වඩා සුවිශේෂී කරයි.
@SuppressWarnings("deprecation")
@SuppressLint("HardwareIds")
public static String generateDeviceIdentifier(Context context) {
String pseudoId = "35" +
Build.BOARD.length() % 10 +
Build.BRAND.length() % 10 +
Build.CPU_ABI.length() % 10 +
Build.DEVICE.length() % 10 +
Build.DISPLAY.length() % 10 +
Build.HOST.length() % 10 +
Build.ID.length() % 10 +
Build.MANUFACTURER.length() % 10 +
Build.MODEL.length() % 10 +
Build.PRODUCT.length() % 10 +
Build.TAGS.length() % 10 +
Build.TYPE.length() % 10 +
Build.USER.length() % 10;
String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String btId = "";
if (bluetoothAdapter != null) {
btId = bluetoothAdapter.getAddress();
}
String longId = pseudoId + androidId + btId;
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(longId.getBytes(), 0, longId.length());
// get md5 bytes
byte md5Bytes[] = messageDigest.digest();
// creating a hex string
String identifier = "";
for (byte md5Byte : md5Bytes) {
int b = (0xFF & md5Byte);
// if it is a single digit, make sure it have 0 in front (proper padding)
if (b <= 0xF) {
identifier += "0";
}
// add number to string
identifier += Integer.toHexString(b);
}
// hex string to uppercase
identifier = identifier.toUpperCase();
return identifier;
} catch (Exception e) {
Log.e("TAG", e.toString());
}
return "";
}
longId
එය ගොනුවක ගබඩා කිරීමෙන් එය වඩාත් සුවිශේෂී හඳුනාගැනීමක් බවට පත් වනු ඇත:String uuid = UUID.randomUUID().toString();
longId
. මේ ආකාරයට එක පේළියක් වෙනස් කරන්න: String longId = pseudoId + androidId + btId + UUID.randomUUID().toString();
ජනනය කරන ලද හැඳුනුම්පත අද්විතීය වනු ඇති බවට මෙය සහතික වේ.
තවත් ක්රමයක් නම් /sys/class/android_usb/android0/iSerial
කිසිදු අවසරයකින් තොරව යෙදුමක භාවිතා කිරීමයි.
user@creep:~$ adb shell ls -l /sys/class/android_usb/android0/iSerial
-rw-r--r-- root root 4096 2013-01-10 21:08 iSerial
user@creep:~$ adb shell cat /sys/class/android_usb/android0/iSerial
0A3CXXXXXXXXXX5
ජාවා හි මෙය සිදු කිරීම සඳහා iSerial ගොනුව විවෘත කර අක්ෂර කියවීමට FileInputStream භාවිතා කළ යුතුය. සෑම උපාංගයකම මෙම ගොනුව නොමැති නිසා ඔබ එය ව්යතිරේක හසුරුවක ඔතා ඇති බවට වග බලා ගන්න.
අවම වශයෙන් පහත දැක්වෙන උපාංගයන් මෙම ගොනුව ලෝකයට කියවිය හැකි බව දන්නා කරුණකි:
ඔබට මගේ බ්ලොග් සටහන ද දැක ගත හැකිය ඇන්ඩ්රොයිඩ් දෘඩාංග අනුක්රමික අංකය නුසුදුසු යෙදුම් වලට කාන්දු වීම, එහිදී තොරතුරු සඳහා ඇති වෙනත් ලිපිගොනු මොනවාදැයි සාකච්ඡා කරමි.
TelephonyManger.getDeviceId () අද්විතීය උපාංග හැඳුනුම්පත ලබා දෙයි, නිදසුනක් ලෙස, GSM සඳහා IMEI සහ CDMA දුරකථන සඳහා MEID හෝ ESN.
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String myAndroidDeviceId = mTelephony.getDeviceId();
නමුත් මම භාවිතා කිරීමට නිර්දේශ කරමි:
Settings.Secure.ANDROID_ID , ඇන්ඩ්රොයිඩ් හැඳුනුම්පත අද්විතීය 64-බිටු හෙක්ස් නූලක් ලෙස ලබා දෙයි.
String myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID);
සමහර විට TelephonyManger.getDeviceId () අහෝසි වනු ඇත, එබැවින් අද්විතීය හැඳුනුම්පතක් සහතික කිරීම සඳහා ඔබ මෙම ක්රමය භාවිතා කරනු ඇත:
public String getUniqueID(){
String myAndroidDeviceId = "";
TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null){
myAndroidDeviceId = mTelephony.getDeviceId();
}else{
myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID);
}
return myAndroidDeviceId;
}
විශේෂිත ඇන්ඩ්රොයිඩ් උපාංගයක දෘඩාංග හඳුනා ගැනීම සඳහා ඔබට MAC ලිපින පරීක්ෂා කළ හැකිය.
ඔබට එය එසේ කළ හැකිය:
AndroidManifest.xml හි
<uses-permission android:name="android.permission.INTERNET" />
දැන් ඔබේ කේතයේ:
List<NetworkInterface> interfacesList = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface interface : interfacesList) {
// This will give you the interface MAC ADDRESS
interface.getHardwareAddress();
}
සෑම ඇන්ඩ්රොයිඩ් උපාංගයකම අවම වශයෙන් "wlan0" අතුරුමුහුණත් මායාකාරිය වන්නේ WI-FI චිපයයි. WI-FI සක්රිය කර නොමැති විටදී පවා මෙම කේතය ක්රියාත්මක වේ.
PS ඒවා MACS අඩංගු ලැයිස්තුවෙන් ඔබට ලැබෙන වෙනත් අතුරුමුහුණත් සමූහයකි, නමුත් මෙය දුරකථන අතර වෙනස් විය හැකිය.
මම පහත කේතය IMEI
භාවිතා කරන්නේ හෝ ලබා ගැනීම සඳහාය . ANDROID_ID
විකල්පයක් ලෙස, උපාංගයට දුරකථන හැකියාවන් නොමැති විට:
String identifier = null;
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE));
if (tm != null)
identifier = tm.getDeviceId();
if (identifier == null || identifier .length() == 0)
identifier = Secure.getString(activity.getContentResolver(),Secure.ANDROID_ID);
වඩාත් විශේෂිතව, Settings.Secure.ANDROID_ID
. මෙය උපාංගය පළමු වරට ආරම්භ වන විට ජනනය කර ගබඩා කරන බිට් 64 ප්රමාණයකි. උපාංගය අතුගා දැමූ විට එය නැවත සකසනු ලැබේ.
ANDROID_ID
අද්විතීය උපාංග හඳුනාගැනීමක් සඳහා හොඳ තේරීමක් ලෙස පෙනේ. අවාසි ඇත: පළමුව, 2.2 ට පෙර ඇන්ඩ්රොයිඩ් නිකුත් කිරීමේදී එය 100% විශ්වාසදායක නොවේ. (“Froyo”).
එසේම, ප්රධාන නිෂ්පාදකයෙකුගේ ජනප්රිය ජංගම දුරකථනයක අවම වශයෙන් පුළුල් ලෙස නිරීක්ෂණය කරන ලද දෝෂයක්වත් තිබේ, සෑම අවස්ථාවකම එකම ANDROID_ID ඇත.
ඇන්ඩ්රොයිඩ් උපාංගවල ඇති අද්විතීය අයිඩී තේරුම් ගැනීමට. මෙම නිල මාර්ගෝපදේශය භාවිතා කරන්න.
අද්විතීය හඳුනාගැනීම් සඳහා හොඳම භාවිතයන්:
උපාංග සත්යාපනය සඳහා IMEI, මැක් ලිපින, නිදර්ශන හැඳුනුම්පත, GUIDs, SSAID, ප්රචාරණ හැඳුනුම්පත, ආරක්ෂිත ජාල API.
https://developer.android.com/training/articles/user-data-ids
ගූගල් නිදර්ශන හැඳුනුම්පත
I / O 2015 දී නිකුත් කරන ලදී; ඇන්ඩ්රොයිඩ් හි ක්රීඩා සේවා අවශ්ය වේ 7.5.
https://developers.google.com/instance-id/
https://developers.google.com/instance-id/guides/android-implementation
InstanceID iid = InstanceID.getInstance( context ); // Google docs are wrong - this requires context
String id = iid.getId(); // blocking call
ඇන්ඩ්රොයිඩ්, ක්රෝම් සහ iOS හරහා ස්ථාපනයන් හඳුනා ගැනීමට ගූගල් මෙම හැඳුනුම්පත භාවිතා කිරීමට අදහස් කරන බව පෙනේ.
එය ස්ථාපනයක් වෙනුවට උපාංගයක් හඳුනා ගනී, නමුත් නැවතත්, ANDROID_ID (එය පිළිගත් පිළිතුරයි) දැන් උපාංග හඳුනා නොගනී. ARC ධාවන කාලය සමඟ සෑම නව ස්ථාපනයකටම නව ANDROID_ID ජනනය වේ ( මෙහි විස්තර ), මෙම නව නිදර්ශන හැඳුනුම්පත මෙන්. එසේම, අප බොහෝ දෙනා සැබවින්ම සොයන්නේ ස්ථාපනයන් (උපාංග නොවේ) හඳුනා ගැනීමයි.
නිදර්ශන හැඳුනුම්පතේ වාසි
ගූගල් එය මේ සඳහා භාවිතා කිරීමට අදහස් කරන බව මට පෙනේ (ඔබේ ස්ථාපනයන් හඳුනා ගැනීම), එය හරස් වේදිකාවක් වන අතර වෙනත් අරමුණු සඳහා භාවිතා කළ හැකිය (ඉහත සබැඳි බලන්න).
ඔබ GCM භාවිතා කරන්නේ නම්, GCM ටෝකනය ලබා ගැනීම සඳහා ඔබට එය අවශ්ය බැවින් (පැරණි GCM ලියාපදිංචි හැඳුනුම්පත ප්රතිස්ථාපනය කරයි) ඔබට අවසානයේ මෙම නිදර්ශන හැඳුනුම්පත භාවිතා කිරීමට අවශ්ය වනු ඇත.
අවාසි / ගැටළු
වත්මන් ක්රියාවට නැංවීමේදී (ජීපීඑස් 7.5) ඔබගේ යෙදුම ඉල්ලූ විට නිදර්ශන හැඳුනුම්පත සේවාදායකයකින් ලබා ගනී. මෙයින් අදහස් කරන්නේ ඉහත ඇමතුම අවහිර කරන ඇමතුමක් බවයි - මගේ විද්යාත්මක නොවන පරීක්ෂණයේදී උපාංගය මාර්ගගතව ඇත්නම් තත්පර 1-3 ක් සහ නොබැඳි නම් තත්පර 0.5 - 1.0 ක් ගතවේ (අනුමාන වශයෙන් මෙය අත්හැරීමට හා උත්පාදනය කිරීමට පෙර කොපමණ කාලයක් බලා සිටිය යුතුද? අහඹු හැඳුනුම්පත). මෙය උතුරු ඇමරිකාවේ නෙක්සස් 5 හි ඇන්ඩ්රොයිඩ් 5.1.1 සහ ජීපීඑස් 7.5 සමඟ අත්හදා බලන ලදී.
ඔවුන් අදහස් කරන අරමුණු සඳහා ඔබ හැඳුනුම්පත භාවිතා කරන්නේ නම් - උදා. යෙදුම් සත්යාපනය, යෙදුම් හඳුනාගැනීම, GCM - මෙම තත්පර 1-3 ක කරදරයක් විය හැකි යැයි මම සිතමි (ඔබගේ යෙදුම අනුව, ඇත්ත වශයෙන්ම).
ANDROID_ID
කියවීමට වග බලා ගන්න .