Unique Id for my android app - android

I want to create a unique ID for my android app so that my server can identify from which device the request has come and send messages to the app accordingly. I read that ANDROID_ID is not safe to use as a unique identifier as it can be compromised on a rooted device. And also some manufacturer don't even provide it.
Is UUID safe to use for my porpose ? Is it really the globally unique id for the app ? If yes, I am planning to store it using the keystore so that I can keep it until the app uninstalls. Is it the right approach. Please suggest.

Its actually safe to use UUID, this is a helper function I created to get the UUID myself,keep it in Helper.java , so you will call it :
Helper.getDeviceId(context);
also don forget the change String sharedPrefDbName variable to your sharef db name, also you can store the UUID in DB or local file incase app is uninstalled like you said.
//uuid
static String deviceId;
static String sharedPrefDbName = "MyAPPDB";
/**
* getDeviceId
* #param context
* #return String
*/
public static String getDeviceId(Context context){
//lets get device Id if not available, we create and save it
//means device Id is created once
//if the deviceId is not null, return it
if(deviceId != null){
return deviceId;
}//end
//shared preferences
SharedPreferences sharedPref = context.getSharedPreferences(sharedPrefDbName,context.MODE_PRIVATE);
//lets get the device Id
deviceId = sharedPref.getString("device_id",null);
//if the saved device Id is null, lets create it and save it
if(deviceId == null) {
//generate new device id
deviceId = generateUniqueID();
//Shared Preference editor
SharedPreferences.Editor sharedPrefEditor = sharedPref.edit();
//save the device id
sharedPrefEditor.putString("device_id",deviceId);
//commit it
sharedPrefEditor.commit();
}//end if device id was null
//return
return deviceId;
}//end get device Id
/**
* generateUniqueID - Generate Device Id
* #return
*/
public static String generateUniqueID() {
String id = UUID.randomUUID().toString();
return id;
}//end method

Related

How to get unique device numer in Android?

I have tried to these methods such as IMEI,MEID,mac address,android_id, but all not OK.
How to get unique device numer in Android?
There are several Unique Identifiers available for Android devices
IMEI
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String imei = TelephonyMgr.getDeviceId();
permission
android.permission.READ_PHONE_STATE
WLAN MAC Address
WifiManager wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String wanMAC = wifi .getConnectionInfo().getMacAddress();
permission
android.permission.ACCESS_WIFI_STATE
Bluetooth MAC Address
BluetoothAdapter bluetoothAdapter =BluetoothAdapter.getDefaultAdapter();
String bluetoothMAC = bluetoothAdapter .getAddress();
permission
android.permission.BLUETOOTH
Android ID
String androidID = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
As the requirement for most of the applications is to identify a particular installation and not a physical device, a good solution to get the unique id for a user if to use UUID class. The following solution has been presented by Reto Meier from Google in a Google I/O presentation :
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;
}
UUID.randomUUID() method generates an unique identifier for a specific installation. You have just to store that value and your user will be identified at the next launch of your application. You can also try to associate this solution with Android Backup service to keep the information available to the user even if he installs your application on the other device.
You can explore more at https://medium.com/#ssaurel/how-to-retrieve-an-unique-id-to-identify-android-devices-6f99fd5369eb
In Android 10 you can't have access to non resettable device ids, like IMEI ,MEID etc.
So I think your best chance is creating a UUID. You can do that using the code below and saving this UUID into database or preference file.
String uniqueID = UUID.randomUUID().toString();
As a random number, everytime you call this method it'll return a different code, and I think is not you are looking for.
To get a "unique ID" from UUID, the best choise is the code below.It will work fine, but the documentation ask to avoid using Android_ID too.
String androidId = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ANDROID_ID);
UUID androidId_UUID = UUID
.nameUUIDFromBytes(androidId.getBytes("utf8"));
This code will give you a almost unique code because if the user do a factory reset, this number would be changed.
I'm looking for another way to get a unique ID but, until now, I couldn't find.
Here ar some Android Developers documentation that should be usefull.
Good pratices to define a unique ID
https://developer.android.com/training/articles/user-data-ids
How to define a unique Id based in you use case:
https://developer.android.com/training/articles/user-data-ids#common-use-cases
I hope this could help someone.
Below code is I used in my project
To get Unique Android Id
static String androidID = Settings.Secure.getString(MyApplication.getContext().getContentResolver(), Settings.Secure.ANDROID_ID);
I used this as a global so i can use anywhere in my project
To retrieve the unique ID associated to your device, you can use the following code :
import android.telephony.TelephonyManager;
import android.content.Context;
// ...
TelephonyManager telephonyManager;
telephonyManager = (TelephonyManager) getSystemService(Context.
TELEPHONY_SERVICE);
/*
* getDeviceId() returns the unique device ID.
* For example,the IMEI for GSM and the MEID or ESN for CDMA phones.
*/
String deviceId = telephonyManager.getDeviceId();
/*
* getSubscriberId() returns the unique subscriber ID,
* For example, the IMSI for a GSM phone.
*/
String subscriberId = telephonyManager.getSubscriberId();
Secure Android ID
String androidId = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ANDROID_ID);

What is the best way to get unique ID in Android?

From this thread, it can say that Settings.Secure#ANDROID_ID can be null sometimes. On the other hand, the telephony-based ID can be null too in tablet devices and can be changed if user change the SIM card or flight mode.
Thinking of getting mac address, from this thread, sometimes the mac address cannot be got too.
Is there any solution that I can get Android unique ID that won't change in any condition?
Rendy, the code I used for that is the above (from emmby answer (with minimal modifications) of question Is there a unique Android device ID?):
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;
}
}
To use that in an Activity, do the following:
UUID identifier = new DeviceUuidFactory(this).getDeviceUuid();
The options you mentioned cover pretty much all the different scenarios to get a unique ID, there's also a unique ID value provided by the OS which has been proved was incorrectly implemented by some vendors and it returns the same value for all the devices of that specific vendor, so No, there's no 1 and only best way to do it, usually you need to combine and validate if one or another exist, for example in our project:
First we go for TelephonyManager and if it exist we take it from there
If not( as is the case in most tablets), then we go for MAC address
If not, then we use the Android unique ID provided in Settings.
Hope it helps!
Regards!

How can I save user-created objects to storage in android?

In my app, I have flashcard objects that the user creates themselves. Users can create as many flashcards as they want, but when they exit the app and return they need to be able to see the flashcards that they previously created and be able to delete them. I have it set up so that they can create/delete, but if they exit the app they will all delete automatically. What is the best way to save the information for a flashcard? It has at least 3 strings currently, the title, the front and the back.
I looked at a few, but am not sure how I would include all three strings in the saving options that are on the android developer site.
For example shared preferences, looks like you can only save certain settings, but it allows the user to change those settings.
The internal/external storage, although very different throw up the same problem, how to have unlimited number of objects and especially how to save all three strings separately.
This is the internal storage is shown below.
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
I don't see how you can save multiple number of objects or 3 different strings.
Does anyone see a solution to my problem?
SharedPreferences seem like the simplest way for you to achieve it, and I think you've misunderstood their usage, or confused the name with a 'Preferences' screen, as you can use the SharedPreferences methods to save anything (well, any basic datatype) persistently.
For example, I use it to save my app's JSON data (which might be a decent way for you to go in terms of saving you users' flashcards in a JSONArray).
/**
* Retrieves data from sharedpreferences
* #param c the application context
* #param pref the preference to be retrieved
* #return the stored JSON-formatted String containing the data
*/
public static String getStoredJSONData(Context c, String pref) {
if (c != null) {
SharedPreferences sPrefs = c.getSharedPreferences("AppPreferences", Context.MODE_PRIVATE);
return sPrefs.getString(pref, null);
}
return null;
}
/**
* Stores the most recent data into sharedpreferences
* #param c the application context
* #param pref the preference to be stored
* #param policyData the data to be stored
*/
public static void setStoredJSONData(Context c, String pref, String policyData) {
if (c != null) {
SharedPreferences sPrefs = c.getSharedPreferences("AppPreferences", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sPrefs.edit();
editor.putString(pref, policyData);
editor.commit();
}
}
Where the string 'pref' is a tag used to refer to that specific piece of data, so for example: "taylor.matt.data1" would refer to a piece of data and could be used to retrieve or store it from SharedPreferences

Storing an arraylist for retrieval in Android

I'm currently working on an Android application that is going to be somewhat like a student planner. My backend is all java and I am currently stuck because i am storing the objects that i create from my backend to arraylist. Being java, these objects dissapear as soon as the programs terminate. Whats the easiest way that i can store my java objects for retrieval the next time i boot my application? Any help is much appreciated! Im developing on 2.3 and eclipse(juno).
One of the data storage options listed in the Android developer tutorial will be the easiest thing to do. Which is the best fit will depend on how much data you're storing and how you need to access it. As the page says, the SharedPreferences class is best for a handful of items; for larger data sets, you could use Java serialization or some other way to write them to a file on the phone's storage; and if your data are large and/or you need structured access to them, an SQLite database is your best bet.
You can use Shared Preferences to store your data. The SharedPreferences lets you persist key-value pairs of primitive data types in you application. You can't store an entire ArrayList with a single key, but you can iterate over the array and systematically generate a key for each value in the list. I usually do something like this:
public class SomeActivity extends Activity {
private ArrayList<Data> list; //We'll persist this array
/* snip */
//These strings can be anything - you just need something you can use to systematically generate distinct keys
public static final String LIST_KEY = "SomeActivity_List";
public static final String LIST_LENGTH_KEY = "SomeActivity_ListLength";
/**
* How this method works: It starts by getting a SharedPreferences object,
* which offers an API for persisting data. It then systematically generates
* Strings like "SomeActivity_List1", "SomeActivity_List2", "SomeActivity_List3",
* and so on to use as keys fot the 1st, 2nd, 3rd, etc. elements in the list. Then
* it Data.saveData(), a method defined below in the Data class, in order to give
* each Data object in the ArrayList an opportunity to persist its primitive
* members in the SharedPreferences.
*
* SomeActivity.restoreList() works similarly.
*/
public void saveList() {
SharedPreferences prefs = getPreferences(); //This method is part of the Activity class
SharedPreferences.Editor editor = prefs.getEditor();
//Save the length of the list so that when we restore it, we know how many
//Data objects to recreate.
editor.putInt(LIST_LENGTH_KEY, list.size());
editor.commit();
//This for loop is important - note how we concatenate i to each of the keys to give each element in list a distinct key
for(int i = 0; i < list.size(); i++)
{
String identifier = LIST_KEY + Integer.toString(i); //generate distinct keys
list.get(i).saveData(identifier, prefs);
}
}
public void restoreList() {
SharedPreferences prefs = getPreferences();
int length = prefs.getInt(LIST_LENGTH_KEY);
for(int i = 0; i < length; i++)
{
String identifier = LIST_KEY + Integer.toString(i); //re-generate distinct keys
Data data = new Data();
data.restoreData(identifier, prefs);
list.addLast(data);
}
}
public static class Data {
private int i;
private double j;
private String s;
public static final String I_KEY = "Data_I"
public static final String J_KEY = "Data_J" //strings can really be whatever, as long as they're distinct.
public static final String S_KEY = "Data_K"
/**
* How this method works: The SomeActivity.saveList() method generates a
* unique String ("identifier") for each of the Data objects it contains.
* This method uses that distinct string and makes some more distinct keys
* to store each of Data's primitive members.
*
* restoreData() works similarly when it rebuilds Data objects
*/
public saveData(String identifier, SharedPreferences prefs) {
SharedPreferences.Editor editor = prefs.getEditor();
editor.putInt(I_KEY + identifier, i);
editor.putDouble(J_KEY + identifier, j);
editor.putString(S_KEY + identifier, s);
editor.commit();
}
public restoreData(String identifier, SharedPreferences prefs) {
i = prefs.getInt(I_KEY + identifier);
j = prefs.getDouble(J_KEY + identifier);
s = prefs.getString(S_KEY + identifier);
}
}
}
This approach work recursively. If Data had an ArrayList as one of its fields, for example, it could systematically store all of the values in that list in SharedPreferences as well.
FYI: One of the implications of using SharedPreferences is that if the user uninstalls your app or clears the app data, the stored list will be deleted. Depending on the nature of your data, you may or may not want this behavior.

Constant Contact Id

Is there any kind of contact variable that is persistent between ROM flashes or factory resets ? I created an app that looks for the contacts id but apparently that changes when there is a sync from a factory reset or new ROM (and between devices). I need to store a unique identifier. Please help. Thank you.
If you are talking about sim data maybe you might figure out something. But if you are talking about an unique identifier the only efficient way i know is generating a UUID key and storing it locally and externally, as suggested by Reto Meier at Google I/O 2011. Here is my snippet (Don't mind my javadoc style ^^);
/**
* This is just a local solution. For world-wide usage,
* backup on a cloud is encouraged.
*
* #reference Reto Meier - Google I/O 2011
*
* #param context for accessing related shared preferences file
* #return unique id
*/
public synchronized static String getUniqueId(Context context)
{
String uniqueID;
//Open shared preferences file for PREF_UNIQUE_ID
SharedPreferences sharedPrefs = context.getSharedPreferences(PREF_UNIQUE_ID, Context.MODE_PRIVATE);
//Fetch id, if any.
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
//If no id saved into shared preferences before generate new one
if(uniqueID == null)
{
uniqueID = UUID.randomUUID().toString();
Editor editor = sharedPrefs.edit();
editor.putString(PREF_UNIQUE_ID, uniqueID);
editor.commit();
}
return uniqueID;
}

Categories

Resources