2013-02-14 36 views
6

Khi nói về ID Android duy nhất, tôi chắc chắn mọi người đã thấy this, tuy nhiên tôi cũng đang cố gắng tìm ra giải pháp để nhận dạng duy nhất mọi thiết bị Android. Tôi rất vui khi sử dụng một lớp học được phát hành công khai nhưng tôi vẫn chưa tìm được.Tạo Mã định danh Android Toàn cầu Độc đáo

Trong trường hợp của tôi, yêu cầu là có thể xác định duy nhất bất kỳ thiết bị nào có kết nối internet (chẳng hạn như GPRS hoặc Wi-Fi) và chạy trên API cấp 8 (v2.2 Froyo). Tôi không biết bất kỳ thiết bị nào không có Wi-Fi hoặc SIM nên hãy cho tôi biết nếu có bất kỳ thiết bị nào!

Chúng tôi đã giải quyết sự cố này trong iOS bằng cách sử dụng hàm băm của địa chỉ mac Wi-Fi vì tất cả các thiết bị iOS phải đều có tính năng này. Tuy nhiên đối với Android, các kỹ thuật (chẳng hạn như câu trả lời cho bài đăng SO được tham chiếu ở trên) tham khảo lớp TelephonyManager có thể trả lại null (chẳng hạn như khi thiết bị không có kết nối SIM, như với Nexus 7) hoặc getContext().getContentResolver(), Secure.ANDROID_ID đến here không đáng tin cậy 100% đối với các phiên bản trước Froyo (điều này thật may mắn cho tôi). Tuy nhiên, nó không có bất kỳ vấn đề gì sau Froyo, nếu có, hãy cho tôi biết! Tôi cũng đã đọc điều này có thể trả về null. Theo here, nó có thể thay đổi khi khôi phục cài đặt gốc nhưng đó không phải là mối quan tâm chính.

Vì vậy, tôi kết hợp điều này để tạo ra một hy vọng-duy nhất-GUID: [Phương pháp này chưa hoàn tất!]

public static String GetDeviceId(Context context) 
{ 
    // Custom String Hash 1 
    StringBuilder stringBuilder = new StringBuilder(); 
    stringBuilder.append("someRandomData"); // Not really needed, but means the stringBuilders value won't ever be null 

    // TM Device String 
    final TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
    String tmDeviceId = tm.getDeviceId(); // Could well be set to null! 
    LogMsg.Tmp("TM Device String [" + tmDeviceId + "]"); 

    // Custom String Hash 2 
    stringBuilder.append(tmDeviceId); 
    int customHash = stringBuilder.toString().hashCode(); 
    LogMsg.Tmp("Custom String hash [" + customHash + "]"); 

    // Device ID String 
    String androidIDString = android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); 
    LogMsg.Tmp("Device ID String [" + androidIDString + "]"); 

    // Combined hashes as GUID 
    UUID deviceUuid = new UUID(androidIDString.hashCode(), ((long)customHash << 32)); 
    LogMsg.Tmp("Combined hashes as GUID [" + deviceUuid.toString() + "]"); 

    return deviceUuid.toString(); 
} 

Vì vậy, bạn có thể tìm thấy tmDeviceId được thiết lập để null, trong trường hợp này các customHash sẽ giống nhau không phụ thuộc vào thiết bị nhưng sau đó này kết hợp với androidIDString phải là duy nhất trên toàn cầu. Tôi nghĩ. Rõ ràng tôi sẽ cần phải làm việc ra nếu tmDeviceIdandroidIDString không có sẵn và ném một ngoại lệ ở đó.

Vì vậy ... đây có phải là quá mức cần thiết không? Nếu vậy, có an toàn khi chỉ sử dụng context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID không?

+1

"Trong trường hợp của tôi, yêu cầu là để có thể xác định duy nhất mọi thiết bị" - nếu bạn cần điều này để trang trải người dùng thiết bị gốc, điều này là không thể AFAIK. Chắc chắn, bất kỳ phần nào mà bạn đang sử dụng có thể được sửa đổi bởi ai đó có quyền root. "Tôi không biết bất kỳ thiết bị nào không có Wi-Fi hoặc SIM nên hãy cho tôi biết nếu có bất kỳ thiết bị nào!" - Các thiết bị Google TV có thể không có WiFi, đi kèm với Ethernet. Nếu bạn phân phối ngoài Cửa hàng Play, có thể có các thiết bị khác không có dữ liệu di động hoặc WiFi. – CommonsWare

+0

@CommonsWare cảm ơn phản hồi của bạn. Suy nghĩ ban đầu của tôi là không hỗ trợ thiết bị nếu các phương thức mà tôi đã nói đến trong câu hỏi đều trả về 'null'. Bạn có nghĩ rằng nó an toàn để sử dụng 'Secure.ANDROID_ID' trên bất cứ thứ gì từ Froyo? Ngoài ra, tôi không nghĩ rằng một thiết bị bắt nguồn từ là một mối quan tâm lớn. Tôi đoán nó sẽ cho phép ai đó giả mạo một thiết bị khác của người khác, ít nhất, nếu họ biết họ đang làm gì, nhưng tôi đã nghĩ rằng bằng cách thêm một khóa (nơi tôi có 'stringBuilder.append (" someRandomData ");') sẽ khiến việc tạo ID thiết bị trả lại cuối cùng trở nên khó khăn. –

+0

"Bạn có nghĩ rằng an toàn khi sử dụng Secure.ANDROID_ID trên bất kỳ thứ gì từ Froyo?" - người dùng thiết bị gốc có thể thay đổi thiết bị và các thiết bị không hợp pháp có Cửa hàng Play trên đó có thể không có giá trị duy nhất. – CommonsWare

Trả lời

3

Tại sao bạn không nhận được địa chỉ MAC của thiết bị như bạn đã thực hiện trong iOS? Điều này có thể được thực hiện trong các thiết bị Android.

tôi sẽ cung cấp một đoạn mã mà có được địa chỉ mac của thiết bị ..

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 

public class HardwareUtil { 

    public static String getMacAddress() 
    { 
     try{ 
      Process process = Runtime.getRuntime().exec("cat /sys/class/net/eth0/address"); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 
      int read; 
      char[] buffer = new char[4096]; 
      StringBuffer output = new StringBuffer(); 
      while ((read = reader.read(buffer)) > 0){ 
       output.append(buffer, 0, read); 
      } 
      reader.close(); 
      process.waitFor(); 
      String hwaddr = output.toString(); 
      return hwaddr; 
     }catch (IOException e) { 
      e.printstacktrace(); 
     }catch (InterruptedException e){ 
      e.printstacktrace(); 
     } 
    } 

} 

HardwareUtil.getMacAddress() sẽ trở lại địa chỉ mac của thiết bị.

CHỈNH SỬA: Nếu địa chỉ mac không phù hợp với trường hợp của bạn. Sau đây có thể hữu ích!

public static String getDeviceId(Context context) { 
    final String deviceId = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId(); 
    if (deviceId != null) { 
     return deviceId; 
    } else { 
     return android.os.Build.SERIAL; 
    } 
} 

Đừng quên để thêm quyền sau vào tập tin AndoridManifest.xml của bạn nếu bạn sử dụng phương pháp getDeviceId.

<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
+0

Đây là những gì tôi đã làm cuối cùng, vấn đề là tôi tin rằng bạn có thể giả mạo địa chỉ MAC nếu bạn có quyền truy cập root. –

+0

Vâng, bạn hoàn toàn đúng. Nếu bạn có thiết bị gốc, bạn có thể làm điều đó. Bạn đã thử android.os.Build.SERIAL chưa? Bạn có thể nhận được số sê-ri phần cứng bằng cách sử dụng này? Kiểm tra điều này ra [link] (http://developer.android.com/reference/android/os/Build.html#SERIAL) Nó có thể hữu ích cho bạn. – gokhanakkurt

+0

Cảm ơn, tôi sẽ kiểm tra điều đó. Có phải 'android.os.Build.SERIAL' đã được đảm bảo tồn tại? –

Các vấn đề liên quan