Generate unique ID per user - android

I am developing a cross platform game for which I needs to generate unique identifier (User ID) for each user. I known some platform (Android or iOS) specific approaches to get device related identifiers but I am looking for a solution independent of the device identifiers.
User ID Requirements:
Independent of the device's platform
Offline implementation (no communication with any servers)
Without sign-up process
I have implemented one approach to create User IDs where I store the system time when the game was launched for the first time on the device.
I have following questions:
Are there any other approaches to generate User IDs (which will meet the above requirements)?
What are the common approaches to create unique identifiers with taking any information from the user?
Are there any third party plug-ins to implement User IDs?
I would appreciate any suggestions and thoughts on this topic.
EDIT:
There are lot of responses to use UUID/GUID. Generally, this approach looks fine but I am looking for a solution which can generate same User ID even if the user reinstall the game.

Have you looked at UUID from Java?
https://docs.oracle.com/javase/7/docs/api/java/util/UUID.html
EDIT: The following links might help using UUID for unique identifiers.
Best practices for permissions & Identifiers
Instance ID

When you say user id, are you talking about a public id such as an username, or a database id?
If you are talking about a database id, go for a GUID/UUID. T-sql for example have the NEWID() method that will return a GUID that doesn't exist in the database yet. I am sure that whichever database you go for you will find some way to use a GUID.
https://learn.microsoft.com/en-us/sql/t-sql/functions/newid-transact-sql

As per my opinion your System current time is the best method for generating Unique User Id.
For Android :
System.currentTimeMillis() returns you the unique 13 digit number which can be used as User Id.
But When you get current time in iOS then it is 10 digit number which generates. So you can multiply it by 1000 to make User Id platform Independent.
Happy Coding...

Assuming that your usernames are unique, you could simply takje the md5 hash of your usernames to get an unique ID (string). e.g. in php:
$userID = md5($username);
because m5 hash functions exist in nearly every programming language you should be able to use this ID on all possible plattforms.
And if you arer looking for a numeric ID, you even can calculate a qunique number from md5.
See represent md5-hash as an integer - stack question for more details

Just generate a long string of random characters. For example, generates a 10 long string of alphanumerics ...
private String GetId(){
String[] chars = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9"};
StringBuilder s = new StringBuilder(10);
for(int i = 0;i<10;i++){
int pos = (int) (Math.random() * 62);
String c = "";
if (pos > chars.length-1){
pos = pos - chars.length;
c = chars[pos].toUpperCase();
}else{
c = chars[pos];
}
s.append(c);
}
return s.toString();
}

Related

Timestamp as unique ID

Is there something wrong if i use
Long uniqueId = System.currentTimeMillis()/1000;
String documentName = ""+ uniqueId;
as for example a document name?
Unless the user has a wrong Date it will be always unique right?
Or is there a better way to create always unique number values?
The reason i use Long uniqueId = System.currentTimeMillis()/1000;
is because it has to be unique even if the user generates that document from another device without the same data which means that i cannot create and save unique values and simply add +1 to it.
If you use
System.currentTimeMillis()/1000
then if you save 2 files in the same second you will have 2 identical names for 2 different files.
So i suggest you to use
UUID.randomUUID().toString()

Compare phone number from database in different condition

I'm developing sms APP and want to receive sms from the specific numbers. But number can be changed sometime with country code as +923201234567 or sometime without country code 03201234567 how I can compare number from database? because don't know in which format number is saved in database(with country code or without country code)
public boolean isMember(String phone, long id){
String query = "SELECT * from members where phone = ? AND active = 1 AND gid = ?";
Cursor c = dbActions.rawQuery(query, new String[]{String.valueOf(phone), String.valueOf(id)});
return c.moveToFirst();
}
Suppose if the number is saved in database without country code 03201234567 then my requirement is to get true if I compare it with country code. +923201234567. Country code could be changed.
PhoneNumberUtils.compare(); is not useful because it not compare with database.
If you can't acquire the correct information always; then you need to look into heuristics.
Meaning: you could write your own comparisons; and when you encounter two numbers like:
03201234567
+923201234567
you can figure: their "tail" is equal; the only difference is that the first one starts with 0 (so no country code) and the second one with +92. So it might be reasonable to declare those two numbers to be equal.
So a "solution" would do things like "normalize" your input (remove all non-digit content; except for leading + signs); and to then make such "tail-bound" comparisons.
If that is "too" fuzzy; I guess then you should step back and describe the requirement that you actually try to resolve here. Why are you comparing numbers; and what do you intend to do with the output of that comparison?!
Normalize all of the phone numbers into the same format before you put them into the database. That way you can just do a normal db search.
The other thing I've done for phone numbers is to convert all letters into the appropriate number, then remove all non digits, then just compare the last 7 digits.

Android - How are you dealing with 9774d56d682e549c ? Android ID

So, I thought I was being clever and using various hashes and permutations of Android's secure unique ID to identify my users....
But it turns out that 9774d56d682e549c is a magic ID returned by
Secure.getString(getContentResolver(), Secure.ANDROID_ID);
for a good number of devices... It appears every emulator I build has the same ID, and many of other peoples phones (lots of moto droids!) and flashed OS mods tend to return this same repeating value. Non-MotoDroid / Non-Flashed handsets seem to all give me a unique string back. But this one is in my DB about 60 times!
I'm going to be optimizing my app to check for that string before registering, but what would be a recommended way of handling it to get another unique value?
My current thought is to check for it, generate an EXTREMELY LARGE random value, hash it, then store than in SharedPreferences and then either use the ANDROID_ID or the one stored in sharedprefs (if the users phone is giving the value). Anyone have any better ideas, or does this seem solid enough to mitigate this crazy bug?
Take a look at the Identifying app installations article. You can't rely on ANDROID_ID.
The best solution is to generate a custom id with:
String id = UUID.randomUUID().toString();
If you want to create one with the same format as real ANDROID_IDs, you can use the same method they use here:
private static String generateAndroidId() {
String generated = null;
try {
final SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed( (System.nanoTime() + new SecureRandom().nextLong()).getBytes() );
generated = Long.toHexString(random.nextLong());
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "Unexpected exception", e);
}
return generated;
}
Outputs: 9e7859438099538e
Though not ideal, things like the Google AdMob SDK use the permission android.permission.READ_PHONE_STATE to read the device's phone number, etc.
There's some useful, related information in the following blog post: http://strazzere.com/blog/?p=116
This phenomenon and also this Stackoverflow thread were talked about at the summercon 2012 by Oberheide and Miller, who recently dissected Google's Bouncer: http://jon.oberheide.org/files/summercon12-bouncer.pdf
Maybe you can extract some more useful info for your project.

how to get the localized label of the phone types?

When changing the custom locale the label of the phone types change to the appropriate language. Does anybody know how to get the localized label of the phone types?
I pick a contact in my app to get its phone number and if there is more then one number I use an AlertDialog to let the user select the currect one. In this pick list, I want to show the label of the type, so it's easier for the user to select. Since they labels are somewhere in the Android system, it must be possible to get the localized label. Unfortunately, the Phone.LABEL is null when reading the phone number.
I know this is a bit old, but this:
Phone.getTypeLabel(this.getResources(), cursor.getInt(typeIdx), "");
worked for me
Yes, you can get localized phone type string with the code:
int phoneNumberType = (int)pCur.getInt(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(), phoneNumberType , "")
but for custom phone types you should cosider phone label, not only phone type:
String phoneLabel = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL));
Inferno's answer is a valid answer, and I was happy to find this answer because it was similar to what I was looking for. However, if you're dealing with phones installed with API Level 5 (Android 2.0) or newer, there is one small problem with this: android.R.array.phoneTypes only returns the list of phone types that were present prior to when ContactsContract class replaced the Contacts interface as of API Level 5. I verified the labels listed when creating a new contact on emulators running these Android versions (API Levels): 1.6 (4), 2.1-update 1 (7), and 2.2 (8).
When printed out, android.R.array.phoneTypes contains these valid phone types:
Home, Mobile, Work, Work Fax, Home Fax, Pager, Other, Custom
These are the valid phone types, present for phones with Android 2.0+ installed, that are missing from that same Array:
Callback, Car, Company Main, ISDN, Main, Other Fax, Radio, Telex, TTY TDD, Work Mobile, Work Pager, Assistant, MMS
Unfortunately, I have not been able to find something like android.R.array.phoneTypes that'll list all of these valid phone types for phones Android 2.0+. Has anyone come across such yet?
References
android.R.array.phoneTypes defined: http://developer.android.com/reference/android/R.array.html#phoneTypes
Note: I'm posting my other two reference links in separate answers, as I can't seem to post more than one hyperlink per post at this time.
i am using this piece of code
public void getPhoneType(){
int res;
for(int i=0;i<=20;i++){
res = ContactsContract.CommonDataKinds.Phone.getTypeLabelResource(i);
Log.d(TAG,"i: "+ i +" type: " + context.getString(res));
}
}
didn't found any place to get the actual count of valid types but http://developer.android.com/reference/android/provider/ContactsContract.CommonDataKinds.Phone.html#getTypeLabelResource%28int%29 says it will always give a valid res so, you can iterate until it start giving repeated values... to me after 20 gives me the custom res.

Are string resource ID values guaranteed to be consistent over different projects?

I have some messages being passed back from my server through php. The problem is that the messages are in English and if the user is using another language they will still get the message in English.
So I had an idea that maybe instead of passing back the message I would instead pass the String resource Id from the android app, that way the app will get the correct string id for their language. I will use this in a number of apps so I just want to know if the string id is guaranteed to be the same across different android projects?
No.
The string resource IDs are likely not even guaranteed to be the same between re-compilations of the same application (e.g. differences between versions of aapt).
Christopher is right, but you can pass a parameter to your server like http://example.com/script.php?lang=en or lang=fr ....
This way the php scripts can use this parameter to return messages in the relevant locale.
You can get the resource ID from a string:
int resID = getResources().getIdentifier("org.my.package:strings/my_string", null, null);
// or
int resID = getResources().getIdentifier("my_string", "strings", "org.my.package");

Categories

Resources