Skip to content
This repository has been archived by the owner on Nov 2, 2018. It is now read-only.

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
vieux committed Sep 9, 2011
0 parents commit f80dfee
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 0 deletions.
196 changes: 196 additions & 0 deletions OpenUDID_manager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package com.OpenUDID;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.Settings.Secure;
import android.util.Log;


public class OpenUDID_manager implements ServiceConnection{
public final static String PREF_KEY = "openudid";
public final static String PREFS_NAME = "openudid_prefs";
public final static String TAG = "OpenUDID";

private final static boolean LOG = true; //Display or not debug message

private final Context mContext; //Application context
private List<ResolveInfo> mMatchingIntents; //List of available OpenUDID Intents
private Map<String, Integer> mReceivedOpenUDIDs; //Map of OpenUDIDs found so far

private final SharedPreferences mPreferences; //Preferences to store the OpenUDID
private final Random mRandom;

private OpenUDID_manager(Context context) {
mPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
mContext = context;
mRandom = new Random();
mReceivedOpenUDIDs = new HashMap<String, Integer>();
}

@Override
public void onServiceConnected(ComponentName className, IBinder service) {
//Get the OpenUDID from the remote service
try {
//Send a random number to the service
android.os.Parcel data = android.os.Parcel.obtain();
data.writeInt(mRandom.nextInt());
android.os.Parcel reply = android.os.Parcel.obtain();
service.transact(1, android.os.Parcel.obtain(), reply, 0);
if (data.readInt() == reply.readInt()) //Check if the service returns us this number
{
final String _openUDID = reply.readString();
if (_openUDID != null) { //if valid OpenUDID, save it
if (LOG) Log.d(TAG, "Received " + _openUDID);

if (mReceivedOpenUDIDs.containsKey(_openUDID)) mReceivedOpenUDIDs.put(_openUDID, mReceivedOpenUDIDs.get(_openUDID) + 1);
else mReceivedOpenUDIDs.put(_openUDID, 1);

}
}
} catch (RemoteException e) {if (LOG) Log.e(TAG, "RemoteException: " + e.getMessage());}
mContext.unbindService(this);

startService(); //Try the next one
}

@Override
public void onServiceDisconnected(ComponentName className) {}

private void storeOpenUDID() {
final Editor e = mPreferences.edit();
e.putString(PREF_KEY, OpenUDID);
e.commit();
}

/*
* Generate a new OpenUDID
*/
private void generateOpenUDID() {
if (LOG) Log.d(TAG, "Generating openUDID");
//Try to get the ANDROID_ID
OpenUDID = Secure.getString(mContext.getContentResolver(), Secure.ANDROID_ID);
if (OpenUDID == null || OpenUDID.equals("9774d56d682e549c") || OpenUDID.length() < 15 ) {
//if ANDROID_ID is null, or it's equals to the GalaxyTab generic ANDROID_ID or bad, generates a new one
final SecureRandom random = new SecureRandom();
OpenUDID = new BigInteger(64, random).toString(16);
}
}


/*
* Start the oldest service
*/
private void startService() {
if (mMatchingIntents.size() > 0) { //There are some Intents untested
if (LOG) Log.d(TAG, "Trying service " + mMatchingIntents.get(0).loadLabel(mContext.getPackageManager()));

final ServiceInfo servInfo = mMatchingIntents.get(0).serviceInfo;
final Intent i = new Intent();
i.setComponent(new ComponentName(servInfo.applicationInfo.packageName, servInfo.name));
mContext.bindService(i, this, Context.BIND_AUTO_CREATE);
mMatchingIntents.remove(0);
} else { //No more service to test

getMostFrequentOpenUDID(); //Choose the most frequent

if (OpenUDID == null) //No OpenUDID was chosen, generate one
generateOpenUDID();
if (LOG) Log.d(TAG, "OpenUDID: " + OpenUDID);

storeOpenUDID();//Store it locally
mInitialized = true;
}
}

private void getMostFrequentOpenUDID() {
if (mReceivedOpenUDIDs.isEmpty() == false) {
final TreeMap<String,Integer> sorted_OpenUDIDS = new TreeMap(new ValueComparator());
sorted_OpenUDIDS.putAll(mReceivedOpenUDIDs);

OpenUDID = sorted_OpenUDIDS.firstKey();
}
}


private static String OpenUDID = null;
private static boolean mInitialized = false;

/**
* The Method to call to get OpenUDID
* @return the OpenUDID
*/
public static String getOpenUDID() {
if (!mInitialized) Log.e("OpenUDID", "Initialisation isn't done");
return OpenUDID;
}

/**
* The Method to call to get OpenUDID
* @return the OpenUDID
*/
public static boolean isInitialized() {
return mInitialized;
}

/**
* The Method the call at the init of your app
* @param context you current context
*/
public static void sync(Context context) {
//Initialise the Manager
OpenUDID_manager manager = new OpenUDID_manager(context);

//Try to get the openudid from local preferences
OpenUDID = manager.mPreferences.getString(PREF_KEY, null);
if (OpenUDID == null) //Not found
{
//Get the list of all OpenUDID services available (including itself)
manager.mMatchingIntents = context.getPackageManager().queryIntentServices(new Intent("com.OpenUDID.GETUDID"), 0);
if (LOG) Log.d(TAG, manager.mMatchingIntents.size() + " services matches OpenUDID");

if (manager.mMatchingIntents != null)
//Start services one by one
manager.startService();

} else {//Got it, you can now call getOpenUDID()
if (LOG) Log.d(TAG, "OpenUDID: " + OpenUDID);
mInitialized = true;
}
}



/*
* Used to sort the OpenUDIDs collected by occurrence
*/
private class ValueComparator implements Comparator {
public int compare(Object a, Object b) {

if(mReceivedOpenUDIDs.get(a) < mReceivedOpenUDIDs.get(b)) {
return 1;
} else if(mReceivedOpenUDIDs.get(a) == mReceivedOpenUDIDs.get(b)) {
return 0;
} else {
return -1;
}
}
}
}

37 changes: 37 additions & 0 deletions OpenUDID_service.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.OpenUDID;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.IBinder;


/*
* You have to add this in your manifest
<service android:name="com.OpenUDID.OpenUDID_service">
<intent-filter>
<action android:name="com.OpenUDID.GETUDID" />
</intent-filter>
</service>
*/


public class OpenUDID_service extends Service{
@Override
public IBinder onBind(Intent arg0) {
return new Binder() {
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) {
final SharedPreferences preferences = getSharedPreferences(OpenUDID_manager.PREFS_NAME, Context.MODE_PRIVATE);

reply.writeInt(data.readInt()); //Return to the sender the input random number
reply.writeString(preferences.getString(OpenUDID_manager.PREF_KEY, null));
return true;
}
};
}
}
26 changes: 26 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

_/_/ _/ _/ _/_/_/ _/_/_/ _/_/_/
_/ _/ _/_/_/ _/_/ _/_/_/ _/ _/ _/ _/ _/ _/ _/
_/ _/ _/ _/ _/_/_/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/
_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/
_/_/ _/_/_/ _/_/_/ _/ _/ _/_/ _/_/_/ _/_/_/ _/_/_/
_/
_/

// Created by Victor Vieux on 9/9/11.
// Copyright 2011 OpenUDID.com
//
Synopsis: an open source project to provide a universal and persistent
Unique Device IDentifier (UDID) solution for Android

Usage:
* Add this to your manifest:
<service android:name="org.openudid.OpenUDID_service">
<intent-filter>
<action android:name="org.openudid.GETUDID" />
</intent-filter>
</service>

* Call `void OpenUDID_manager.sync(Context yourContext);` to initialize the OpenUDID
* Call `boolean OpenUDID_manager.isInitialized();` to check if the initialization is over (it's asynchronous)
* Call `String OpenUDID_manager.getOpenUDID();` to retrieve your OpenUDID

0 comments on commit f80dfee

Please sign in to comment.