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.
Related
Recently I found out from Firebase Crashlytics that some HTC/Fortuneship
devices crashes with the next exception and I can't understand why
val formattedViews: String
get() = String.format(Locale.getDefault(), "%,d %s", viewCount, Util.getString(R.string.views))
I don't get how such exception can happen in this code
Is there something wrong with those devices?
This is a bug in the JDK shipping with Android 7: https://bugs.openjdk.java.net/browse/JDK-8167567
You are passing Locale.getDefault() to format(), which is the same as not specifying a locale at all. The only known workaround appears to be to use a known-good locale to do the formatting (e.g. Locale.US), but of course this means you won't get locale-specific thousands groupings for users outside the US.
Or you could change your format specification to not use groupings (i.e. %d without the comma).
Perhaps you could catch the exception and fall back to US formatting for users who would otherwise crash? That's what these guys did: https://github.com/wordpress-mobile/WordPress-Android/pull/5604/files
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();
}
Thanks for reading this question. I am sure the experts on this site will be able to provide the help I need.
I am trying to write an app which allows users to edit the exif information of the photos on their Android Phone.
As a part of improved user experience, I want to apply data validation where ever possible.
For the Exif Tag - TAG_GPS_PROCESSING_METHOD I am not able to apply the validation correctly.
Here is the part of code that I have applied :
String strGPSProc = etGPSProc.getText().toString();
if(strGPSProc.equalsIgnoreCase("GPS") || strGPSProc.equalsIgnoreCase("CELLID") || strGPSProc.equalsIgnoreCase("WLAN") || strGPSProc.equalsIgnoreCase("MANUAL") ) {
returnValue = true;
}else {
returnValue=false;
showToast("Incorrect value for GPS Processing Method. Correct value options are GPS, CELLID, WLAN or MANUAL.");
etGPSProc.requestFocus();
}
This code checks if the value entered in the EditText meant for GPSProcessingMethod, has any one of the four prescribed value as described in the documentation of EXIF.
But when I try to save this using setAttribute() and saveAttributes() functions, a non catch-able exception appears in logcat.
Unsupported encoding for GPSProcessingMethod
I understand from Exif Documentation that values for GPSProcessingMethod needs to be stored with some header information.
I need some expert advise on how to implement this correctly, with out using any other 3rd part classes.
Accoridng to the Exif specification:
GPSProcessingMethod
A character string recording the name of the method used for location finding. The first byte indicates the character
code used (Table 6、Table 7), and this is followed by the name of the method. Since the Type is not ASCII, NULL
termination is not necessary
Atually, Table 6 lists the character codes as 8 byte sequences, so the above should probably read "The first bytes indicate...". Anyway, the character code designation for ASCII is defined as 41.H, 53.H, 43.H, 49.H, 49.H, 00.H, 00.H, 00.H., Unicode is (unsurprisingly) 55.H, 4E.H, 49.H, 43.H, 4F.H, 44.H, 45.H, 00.H. I guess these should be all you need.
Hope that helps.
EDIT:
Just discovered that ExifInterface.setAttribute() only supports String values... You could try encoding the value at the beginning of your string, but I doubt that would work. Sounds like the encoding should be handled by the setAttribute() or saveAttributes() method. Could it be a bug in the API? I had a look at the source code, but the actual writing of values is done by native code so I stopped digging further.
I need to know the canonical names of a few Default Android applications like Email, Contacts & others. I want to be able to start them using their canonical names.
Like
Intent i = new Intent("com.pacakge.canonicalname");
So any ideas where i could get a list of the canonical package names of default Android apps?
thanks
There's a method in the PackageManager class called currentToCanonicalPackageNames(String[] names), which I suspect could be used to do what you're asking. So something like:
String[] names = {"Email","Contacts"};
try{
String[] canonicalNames = context.getPackageManager().currentToCanonicalPackageNames(names);
//do whatever you want with canonicalNames, e.g. launch the email app,
Intent email = context.getPackageManager().getLaunchIntentForPackage(canonicalNames[0]);
context.startActivity(email);
}catch(NameNotFoundException e){
Log.d("MY ACTIVITY NAME", "Package name(s) not found.");
}
I'm looking into doing this sort of thing myself, but haven't tried this code, so use with caution.
EDIT:
So tried it this evening, the solution may not be what you're looking for. Assuming you're starting with only the display names of these apps (technically referred to as application labels), you may have to actually go through all of the apps installed on the device looking for that application label. I just posted my solution to my blog, so take a look.
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.