যখন এমুলেটরটিতে অ্যান্ড্রয়েড অ্যাপ্লিকেশন চলছে তখন আমি কীভাবে সনাক্ত করতে পারি?


313

ডিভাইসে চলার চেয়ে এমুলেটরটিতে চলার সময় আমার কোডটি কিছুটা আলাদাভাবে চালানো চাই। ( উদাহরণস্বরূপ , কোনও ডেভলপমেন্ট সার্ভারের বিরুদ্ধে স্বয়ংক্রিয়ভাবে চালানোর জন্য পাবলিক URL এর পরিবর্তে 10.0.2.2 ব্যবহার করা)) এমুলেটরটিতে কোনও অ্যান্ড্রয়েড অ্যাপ্লিকেশন চলার সময় সনাক্ত করার সর্বোত্তম উপায় কী?


2
তাকিয়ে থাকতে পারে android.os.Build
ইয়াঞ্চেঙ্কো

11
আমাকে অবাক করে দিন ... গুগলের কাছে এটি করার একটি স্ট্যান্ডার্ড উপায় থাকা উচিত?
পাউডার366

@ ক্রেকার কী সমস্যা তা আপনি বিদ্যমান সমাধানে মুখোমুখি?
খেমরাজ

@ খেলাজ জালিয়াতির বিষয়। দুষ্ট লোকটি কিছু সেন্সরকে উপহাস করতে পারে এবং আসল ডিভাইসের ভান করার জন্য কিছু স্ট্রিং পরিবর্তন করতে পারে
kreker

উত্তর:


158

এই সমাধান সম্পর্কে কীভাবে:

    fun isProbablyAnEmulator() = Build.FINGERPRINT.startsWith("generic")
            || Build.FINGERPRINT.startsWith("unknown")
            || Build.MODEL.contains("google_sdk")
            || Build.MODEL.contains("Emulator")
            || Build.MODEL.contains("Android SDK built for x86")
            || Build.BOARD == "QC_Reference_Phone" //bluestacks
            || Build.MANUFACTURER.contains("Genymotion")
            || Build.HOST.startsWith("Build") //MSI App Player
            || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
            || "google_sdk" == Build.PRODUCT

মনে রাখবেন যে কিছু ইমুলেটরগুলি আসল ডিভাইসের নকল সঠিক চশমা তৈরি করে, তাই এটি সনাক্ত করা অসম্ভব হতে পারে।

এখানে APK এর বিভিন্ন জিনিস দেখানোর জন্য আপনি একটি ছোট ছোট স্নিপেট তৈরি করতে পারেন, যাতে আপনি নিজের বিধিগুলি যুক্ত করতে পারেন:

        textView.text = "FINGERPRINT:${Build.FINGERPRINT}\n" +
                "MODEL:${Build.MODEL}\n" +
                "MANUFACTURER:${Build.MANUFACTURER}\n" +
                "BRAND:${Build.BRAND}\n" +
                "DEVICE:${Build.DEVICE}\n" +
                "BOARD:${Build.BOARD}\n" +
                "HOST:${Build.HOST}\n" +
                "PRODUCT:${Build.PRODUCT}\n"

9
প্রতিক্রিয়া-নেটিভ
ভাইদেন

@ অ্যালাদামের উত্তরটি বেশ কিছুক্ষণ ব্যবহার করার পরে আমাকে আপডেট করতে হয়েছিল (এটি আমার পক্ষে কাজ করা বন্ধ করে দিয়েছে)।
ckbhodge

@ সিড এটির জন্য কী যুক্ত করা উচিত?
অ্যান্ড্রয়েড বিকাশকারী

2
@ সিড আপনি কি সেখানে বিভিন্ন বিল্ড ক্লাস ভেরিয়েবল ছাপিয়েছেন? বিশেষ কিছু মনে হচ্ছে না? আপনি কি এটি চেষ্টা করেছেন: github.com/framgia/android-emulator-detector ?
অ্যান্ড্রয়েড বিকাশকারী

1
@ ডিআরডিও আপনি বিল্ডকনফিগ.ডিবিউজি ব্যবহার করে বর্তমান বিল্ডের একটি চেক যোগ করতে পারেন, বা আপনার নিজস্ব কাস্টম ভেরিয়েবলের সাহায্যে নিজের বিল্ড তৈরি করতে পারেন। আপনি এই ফাংশনটিকে সর্বদা মিথ্যা বা অন্য কিছুতে ফিরে যেতে প্রগার্ডটি ব্যবহার করতে সক্ষম হতে পারেন (উদাহরণস্বরূপ, আপনি এখানে লগগুলি মুছে ফেলতে পারেন: मध्यम.com / tixdo-labs/… , তাই সম্ভবত এটিও সম্ভব)
অ্যান্ড্রয়েড বিকাশকারী

118

একটি সাধারণ এক হতে হবে Build.FINGERPRINT.contains("generic")


এটি গ্যালাক্সি ট্যাব এমুলেটরের সাথেও কাজ করে। শীর্ষ পছন্দ মত উত্তর দেয় নি।
বাফার স্ট্যাক

10
"জেনেরিক" সম্বলিত একটি আঙুলের ছাপ হয় কোনও এমুলেটর বা ডিভাইস কিনা তা দয়া করে উল্লেখ করুন। সেই তথ্যটি মূল তবে সরবরাহ করা হয়নি।
জেমস ক্যামেরন

2
এমুলেটর - আপনার আগে মন্তব্যে বিচার করে :)
ডরি

7
এটি সায়ানোজেনমড চলমান আমার ডিভাইসগুলিতে সত্য ফিরে আসে তাই সাবধান হন।
দেবদেব

8
অ্যান্ড্রয়েড ডকুমেন্টেশন বলেছে তুমি ব্যাখ্যা করার চেষ্টা করা উচিত নয় FINGERPRINTমান।
gnuf

64

ওয়েল অ্যান্ড্রয়েড আইডি আমার পক্ষে কাজ করে না, আমি বর্তমানে ব্যবহার করছি:

"google_sdk".equals( Build.PRODUCT );

35
এটি পড়ার যে কেউ জানতে আগ্রহী হতে পারে যে এই স্ট্রিংটি 'google_sdk' এর পরিবর্তে 'sdk' এ পরিবর্তিত হয়েছে বলে মনে হচ্ছে।
ড্যানিয়েল স্লোফ

15
@ ড্যানিয়েল: আমি গুগল এপিআইয়ের সাথে 2.3.3 ব্যবহার করি এবং এটি 'google_sdk' বলে। দেখে মনে হচ্ছে এটি গুগল এপিডির সাথে এভিডির জন্য 'google_sdk' এবং সাধারণের জন্য 'এসডিকে'।
র‌্যান্ডি সুগিয়ান্তো 'ইউকু'

3
ইন্টেল এমুলেটর "ফুল_এক্স 86" রিটার্ন করে তাই আমি এই পদ্ধতির উপর নির্ভর করি না।
ইউজার 46292982

3
@ গ্লেনমায়নার্ড বিপরীত রূপটি কুরুচিপূর্ণ, তবে ব্যবহারিক: বিল্ড.প্রডাক্টটি বাতিল হতে পারে যেখানে "google_sdk" পারে না, সুতরাং এই ফর্মটি একটি সম্ভাব্য নাল রেফারেন্স ত্রুটি এড়িয়ে চলে।
রূপার্ট রাউন্সলে

4
আরও কেস সহ: "google_sdk"। প্রয়োজনীয় (বিল্ড.প্রডাক্ট) || "sdk" .Equals (বিল্ড.প্রডাক্ট) || "sdk_x86"। সমকাল (বিল্ড.প্রডাক্ট) || "vbox86p" .সম্পাদনা (বিল্ড.প্রডাক্ট)
আলবার্তো আলোনসো

31

অন্যান্য উত্তরের ইঙ্গিতগুলির ভিত্তিতে, এটি সম্ভবত সবচেয়ে মজাদার উপায়:

isEmulator = "goldfish".equals(Build.HARDWARE)


হ্যাঁ. বিল্ড.প্রডাক্টের বিপরীতে, বিল্ড.হার্ডওয়ার (সোনার ফিশ) সরকারী এসডিকে এবং এওএসপির ক্ষেত্রে একই same এপিআই 8 এর পূর্বে আপনাকে হার্ডওয়ার ক্ষেত্রটি পেতে প্রতিবিম্বটি ব্যবহার করতে হবে।
ডেভিড চ্যান্ডলার

4
আমি সাথে যেতেisEmulator = Build.HARDWARE.contains("golfdish")
holmes

7
@ হোমস: টাইপো, এস / বি "গোল্ডফিশ"
নোহ

7
অ্যান্ড্রয়েড 5.1 x86_64 চিত্রের (এবং সম্ভবত আরও সাম্প্রতিক bit৪ বিট চিত্র) এর জন্য যা "গোল্ডফিশ" এর পরিবর্তে "রানচু" হবে।
ওয়ারবি

28

ডিভাইসটি এমুলেটর কিনা তা নির্ধারণ করতে গুগল ফ্লটার থেকে ডিভাইস-তথ্য প্লাগইনে এই কোডটি ব্যবহার করে :

private boolean isEmulator() {
    return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
        || Build.FINGERPRINT.startsWith("generic")
        || Build.FINGERPRINT.startsWith("unknown")
        || Build.HARDWARE.contains("goldfish")
        || Build.HARDWARE.contains("ranchu")
        || Build.MODEL.contains("google_sdk")
        || Build.MODEL.contains("Emulator")
        || Build.MODEL.contains("Android SDK built for x86")
        || Build.MANUFACTURER.contains("Genymotion")
        || Build.PRODUCT.contains("sdk_google")
        || Build.PRODUCT.contains("google_sdk")
        || Build.PRODUCT.contains("sdk")
        || Build.PRODUCT.contains("sdk_x86")
        || Build.PRODUCT.contains("vbox86p")
        || Build.PRODUCT.contains("emulator")
        || Build.PRODUCT.contains("simulator");
}

20

আপনার অ্যাপ্লিকেশনটি ডিবাগ কীতে স্বাক্ষরিত হয়েছে কি না তা নীচের কোডের মতো কীভাবে বলা যায়? এটি এমুলেটর সনাক্ত করছে না তবে এটি আপনার উদ্দেশ্যে কাজ করতে পারে?

public void onCreate Bundle b ) {
   super.onCreate(savedInstanceState);
   if ( signedWithDebugKey(this,this.getClass()) ) {
     blah blah blah
   }

  blah 
    blah 
      blah

}

static final String DEBUGKEY = 
      "get the debug key from logcat after calling the function below once from the emulator";    


public static boolean signedWithDebugKey(Context context, Class<?> cls) 
{
    boolean result = false;
    try {
        ComponentName comp = new ComponentName(context, cls);
        PackageInfo pinfo = context.getPackageManager().getPackageInfo(comp.getPackageName(),PackageManager.GET_SIGNATURES);
        Signature sigs[] = pinfo.signatures;
        for ( int i = 0; i < sigs.length;i++)
        Log.d(TAG,sigs[i].toCharsString());
        if (DEBUGKEY.equals(sigs[0].toCharsString())) {
            result = true;
            Log.d(TAG,"package has been signed with the debug key");
        } else {
            Log.d(TAG,"package signed with a key other than the debug key");
        }

    } catch (android.content.pm.PackageManager.NameNotFoundException e) {
        return false;
    }

    return result;

} 

1
এই কোডের জন্য আপনাকে ধন্যবাদ। আমি যাচাই করে দেখেছি এবং এটি কাজ করছে, দীর্ঘ ডিবাগ কীটি চাপানোয় বেদনাদায়ক হতে পারে তবে এটি একবারেই করা হয়ে গেছে। এটিই একমাত্র নির্ভরযোগ্য সমাধান, কারণ অন্যান্য সমস্ত উত্তর ওএস বিল্ড ইনফরমেশন স্ট্রিংয়ের কিছু অংশকে একটি স্ট্যাটিক স্ট্রিংয়ের সাথে তুলনা করে, এবং এটি অ্যান্ড্রয়েড এসডিকে সংস্করণে পরিবর্তিত হতে পারে এবং কাস্টম অ্যান্ড্রয়েড বিল্ডগুলিও জালিয়াতি করতে পারে।
জোল্টানএফ

আমি মনে করি এটিই একমাত্র নির্ভরযোগ্য সমাধান। যাইহোক, ডিবাগ কীটি আমাদের চেয়ে বেশি দ্রুত পরিবর্তন করতে পারে।
আরডিএস

2
এটি করার একটি আরও ভাল উপায় BuildConfig.DEBUG
মাইগড

13

এই কোডটি আমার পক্ষে কাজ করে

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String networkOperator = tm.getNetworkOperatorName();
if("Android".equals(networkOperator)) {
    // Emulator
}
else {
    // Device
}

যদি সেই ডিভাইসে সিম কার্ড না থাকে তবে এটি খালি স্ট্রিং পুনরায় চালু করে: ""

যেহেতু অ্যান্ড্রয়েড এমুলেটর সর্বদা নেটওয়ার্ক অপারেটর হিসাবে "অ্যান্ড্রয়েড" পুনরায় সংযুক্ত করে, আমি উপরের কোডটি ব্যবহার করি।


3
সিম কার্ডবিহীন কোনও ডিভাইস (যেমন ট্যাবলেট) কী ফিরে আসে?
আরডিএস

অ্যান্ড্রয়েড 2.1 এর জন্য এমুলেটর চলছে। এই কোডটি আমার পক্ষে কাজ করছিল, তবে কর্ডোভাকে ২..0.০ তে উন্নীত করার পরে, প্রসঙ্গের ভেরিয়েবলটি অপরিজ্ঞাত বা কিছু হিসাবে প্রতীয়মান হয়েছে। এডিটি-তে আমি যে ত্রুটিটি পেয়েছি তা এখানে: "প্রসঙ্গটি কোনও ভেরিয়েবলের সাথে সমাধান করা যায় না।" এছাড়াও, উপরের মতামত অনুসারে, এটি একটি নির্ভরযোগ্য পদ্ধতি নয় (যদিও আমি আসলে এটি নিজেকে ব্যর্থ করি নি)।
রুস্তাভোর

2
@ আরডিএস ডিভাইসগুলির সিম কার্ড নেই যা খালি স্ট্রিং দেয় ("")
জেজে কিম

এমুলেটর সহ এই মান রাখার কোনও উপায় নেই? কারণ আমি যদি সমস্ত ব্যবহারকারীদের কাছে কোনও সিম কার্ড না থাকে তবে আমি তাদের ব্লক করতে চাই।
সি-

11

নিম্নলিখিত দুটিই "google_sdk" এ সেট করা আছে:

Build.PRODUCT
Build.MODEL

সুতরাং নিম্নলিখিত লাইনগুলির যে কোনও একটির ব্যবহার করা যথেষ্ট।

"google_sdk".equals(Build.MODEL)

অথবা

"google_sdk".equals(Build.PRODUCT)

উইন্ডোজে এক্স 86 এমুলেটর চালানোর সময়, বিল্ড.প্রডাক্ট হয় sdk_x86
এডওয়ার্ড ব্রে

PRODUCT এর সাথে চেক করা ভাল পছন্দ নয় কারণ এটি বিভিন্ন
অনুকরণকারী

11

আমি বেশ কয়েকটি কৌশল চেষ্টা করেছিলাম, তবে নীচের মতো বিল্ড.প্রডাক্ট পরীক্ষা করে দেখার জন্য কিছুটা সংশোধিত সংস্করণে স্থির হয়েছি। এটি এমুলেটর থেকে এমুলেটর পর্যন্ত বেশ খানিকটা পরিবর্তিত হয় বলে মনে হয়, আমার কাছে বর্তমানে আমার কাছে 3 টি চেক রয়েছে। আমার ধারণা আমি কেবল প্রোডাক্ট কনটেনস ("এসডিকে") চেক করতে পারতাম তবে নীচের চেকটি কিছুটা নিরাপদ বলে মনে করেছি।

public static boolean isAndroidEmulator() {
    String model = Build.MODEL;
    Log.d(TAG, "model=" + model);
    String product = Build.PRODUCT;
    Log.d(TAG, "product=" + product);
    boolean isEmulator = false;
    if (product != null) {
        isEmulator = product.equals("sdk") || product.contains("_sdk") || product.contains("sdk_");
    }
    Log.d(TAG, "isEmulator=" + isEmulator);
    return isEmulator;
}

এফওয়াইআই - আমি দেখতে পেয়েছি যে আমার কিন্ডেল ফায়ারে বিল্ড রয়েছে BR


10

আমি সন্ধান করছি _sdk, _sdk_বা sdk_, বা এমনকি কিছু sdkঅংশ Build.PRODUCT:

if(Build.PRODUCT.matches(".*_?sdk_?.*")){
  //-- emulator --
}else{
  //-- other device --
}

3
শুধু কেন নয় contains("sdk")? একমাত্র পার্থক্য (দ্রুত হওয়া ছাড়া অন্যটি) এর জন্য এটি matches(".*_?sdk_?.*")প্রয়োজন যে যদি এসডিকে আগে বা পরে কোনও চরিত্র থাকে তবে এটি অবশ্যই একটি আন্ডারস্কোর '_' হওয়া উচিত, যা যাচাই করা সমস্ত গুরুত্বপূর্ণ নয়।
নুলানো

9

আপনি এমুলেটরটিতে আছেন কিনা তা বলার মতো ভাল উপায় আমি কখনও পাইনি।

আপনি যদি কেবল বিকাশের পরিবেশে থাকেন তবে যদি সনাক্ত করতে হয় তবে আপনি এটি করতে পারেন:

     if(Debug.isDebuggerConnected() ) {
        // Things to do in debug environment...
    }

আশা করি এই সাহায্য ....


8

এই ফাংশনটি ব্যবহার করুন:

 public static final boolean isEmulator() {

    int rating = 0;

    if ((Build.PRODUCT.equals("sdk")) || (Build.PRODUCT.equals("google_sdk"))
            || (Build.PRODUCT.equals("sdk_x86")) || (Build.PRODUCT.equals("vbox86p"))) {
        rating++;
    }
    if ((Build.MANUFACTURER.equals("unknown")) || (Build.MANUFACTURER.equals("Genymotion"))) {
        rating++;
    }
    if ((Build.BRAND.equals("generic")) || (Build.BRAND.equals("generic_x86"))) {
        rating++;
    }
    if ((Build.DEVICE.equals("generic")) || (Build.DEVICE.equals("generic_x86")) || (Build.DEVICE.equals("vbox86p"))) {
        rating++;
    }
    if ((Build.MODEL.equals("sdk")) || (Build.MODEL.equals("google_sdk"))
            || (Build.MODEL.equals("Android SDK built for x86"))) {
        rating++;
    }
    if ((Build.HARDWARE.equals("goldfish")) || (Build.HARDWARE.equals("vbox86"))) {
        rating++;
    }
    if ((Build.FINGERPRINT.contains("generic/sdk/generic"))
            || (Build.FINGERPRINT.contains("generic_x86/sdk_x86/generic_x86"))
            || (Build.FINGERPRINT.contains("generic/google_sdk/generic"))
            || (Build.FINGERPRINT.contains("generic/vbox86p/vbox86p"))) {
        rating++;
    }

    return rating > 4;

    }

7

ইমু সনাক্ত করার আরও ভাল উপায় আছে কি না তা জানেন না তবে এমুলেটরটিতে ফাইল থাকবে init.goldfish.rc রুট ডিরেক্টরিতে

এটি এমুলেটর নির্দিষ্ট স্টার্টআপ-স্ক্রিপ্ট, এবং এটি কোনও অ-এমুলেটর বিল্ডে থাকা উচিত নয়।


অ্যান্ড্রয়েড সিস্টেম শুরু করার সময় লিনাক্স কার্নেল প্রথমে প্রক্রিয়াটিকে "init" বলে calls init "/init.rc" এবং "init.device.rc" ফাইলগুলি পড়ে। "init.device.rc" ডিভাইস নির্দিষ্ট, ভার্চুয়াল ডিভাইসে এই ফাইলটিকে "init.goldfish.rc" বলা হয়।
নেট 3

7

এখানে আমার সমাধানটি রয়েছে (এটি কেবলমাত্র আপনি যদি আপনার ডিবাগ মেশিনে একটি ওয়েব সার্ভার চালান তবে তা কাজ করে): আমি একটি পটভূমি টাস্ক তৈরি করেছি যা অ্যাপ্লিকেশন শুরু হওয়ার সাথে সাথে শুরু হয়। এটি http://10.0.2.2 এর সন্ধান করে এবং যদি এটি বিদ্যমান থাকে তবে এটি একটি গ্লোবাল প্যারামিটার (ইসডেবগ) কে সত্যে পরিবর্তন করে। আপনি কোথায় চলছে তা খুঁজে বের করার এক নীরব উপায়।

public class CheckDebugModeTask extends AsyncTask<String, Void, String> {
public static boolean IsDebug = false;

public CheckDebugModeTask()
{

}

@Override
protected String doInBackground(String... params) {     
  try {
    HttpParams httpParameters = new BasicHttpParams();
    int timeoutConnection = 1000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
    int timeoutSocket = 2000;
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

    String url2 = "http://10.0.2.2";        
          HttpGet httpGet = new HttpGet(url2);
    DefaultHttpClient client = new DefaultHttpClient(httpParameters);

    HttpResponse response2 = client.execute(httpGet);
    if (response2 == null || response2.getEntity() == null || response2.getEntity().getContent() == null)
    return "";

    return "Debug";

} catch (Exception e) {
    return "";
}
}

@Override
protected void onPostExecute (String result)
{       
if (result == "Debug")
{
    CheckDebugModeTask.IsDebug = true;
}
}

অনিয়ন্ত্রিত মূল ক্রিয়াকলাপ থেকে:

CheckDebugModeTask checkDebugMode = new CheckDebugModeTask();
checkDebugMode.execute("");

7

ব্যাটারি থেকে, এমুলেটর: পাওয়ার উত্স সর্বদা এসি চার্জার থাকে। তাপমাত্রা সর্বদা 0

এবং আপনি Build.HOSTহোস্ট মান রেকর্ড করতে ব্যবহার করতে পারেন , বিভিন্ন এমুলেটরের বিভিন্ন হোস্ট মান রয়েছে।


আপনি কীভাবে পাওয়ার উত্স এবং তাপমাত্রা পাবেন?
অ্যান্ড্রয়েড বিকাশকারী

5

আর একটি বিকল্প হ'ল রো। ওয়ার্ডওয়্যার সম্পত্তিটি দেখুন এবং এটি সোনার ফিশে সেট আছে কিনা তা দেখুন। দুর্ভাগ্যক্রমে জাভা থেকে এটি করার সহজ উপায় বলে মনে হয় না তবে সম্পত্তি_গেট () ব্যবহার করে সি থেকে এর তুচ্ছ ।


4
এটি এনডিকে থেকে কাজ করে বলে মনে হচ্ছে। <Sys / system_properties.h> অন্তর্ভুক্ত করুন এবং __ সিস্টেমে_প্রোপার্টি_জেট ("ro.hardware", বুফ) ব্যবহার করুন তারপরে পরীক্ষা করুন যে বুফটি "গোল্ডফিশ"।
নিউস্কুলার

5

জন্য পরীক্ষা করার জন্য উপরের প্রস্তাবিত সমাধান ANDROID_IDআমি আজ অ্যান্ড্রয়েড ২.২ দিয়ে প্রকাশিত সর্বশেষ এসডিকে সরঞ্জামগুলিতে আপডেট না হওয়া পর্যন্ত আমার জন্য কাজ করার জন্য ।

অতএব আমি বর্তমানে নিম্নলিখিত সমাধানটিতে স্যুইচ করেছি যা অসুবিধা সহ এখনও পর্যন্ত কাজ করে তবে আপনাকে PHONE_STATE পড়ার অনুমতি দেওয়া দরকার ( <uses-permission android:name="android.permission.READ_PHONE_STATE"/>)

private void checkForDebugMode() {
    ISDEBUGMODE = false; //(Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID) == null);

    TelephonyManager man = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
    if(man != null){
        String devId = man.getDeviceSoftwareVersion();
        ISDEBUGMODE = (devId == null);
    }
} 

5

সমস্ত উত্তর এক পদ্ধতিতে

static boolean checkEmulator()
{
    try
    {
        String buildDetails = (Build.FINGERPRINT + Build.DEVICE + Build.MODEL + Build.BRAND + Build.PRODUCT + Build.MANUFACTURER + Build.HARDWARE).toLowerCase();

        if (buildDetails.contains("generic") 
        ||  buildDetails.contains("unknown") 
        ||  buildDetails.contains("emulator") 
        ||  buildDetails.contains("sdk") 
        ||  buildDetails.contains("genymotion") 
        ||  buildDetails.contains("x86") // this includes vbox86
        ||  buildDetails.contains("goldfish")
        ||  buildDetails.contains("test-keys"))
            return true;
    }   
    catch (Throwable t) {Logger.catchedError(t);}

    try
    {
        TelephonyManager    tm  = (TelephonyManager) App.context.getSystemService(Context.TELEPHONY_SERVICE);
        String              non = tm.getNetworkOperatorName().toLowerCase();
        if (non.equals("android"))
            return true;
    }
    catch (Throwable t) {Logger.catchedError(t);}

    try
    {
        if (new File ("/init.goldfish.rc").exists())
            return true;
    }
    catch (Throwable t) {Logger.catchedError(t);}

    return false;
}

সুন্দর. init.goldfish.rcশুধুমাত্র অনুকরণকারী মধ্যে বিদ্যমান; বিল্ড ডিটেইলস ছাড়াও এটি আরও ভালভাবে যাচ্ছিল।
Sud007

2
@ Sud007 সেখানে devices /init.goldfish.rc দিয়ে অনেকগুলি ডিভাইস রয়েছে এবং এটি মিথ্যা ইতিবাচক দিকে পরিচালিত করবে। উদাহরণস্বরূপ, অনেক স্যামসং গ্যালাক্সি সিরিজের ডিভাইস।
লাট্টো

@ লাল্টো আপনি আসলে সঠিক ছিলেন। আমি এটি পরে খুঁজে পেয়েছি এবং দুঃখিত যে আমি এটি এখানে আপডেট করতে ভুলে গেছি।
Sud007

টেস্ট-কীগুলি আমার জন্য মিথ্যা ইতিবাচকতা তৈরি করে।
অভি পর্যর্শন

কোন ডিভাইসে তারা মিথ্যা ধনাত্মক উত্পন্ন করছে?
আমান ভার্মা

5

আমি নতুন এমুলেটর পেয়েছি Build.HARDWARE = "ranchu"

তথ্যসূত্র: https://groups.google.com/forum/#!topic/android-emulator-dev/dltBnUW_HzU

এবং আমি এমুলেটরটি কিনা তা যাচাই করার জন্য অ্যান্ড্রয়েড অফিসিয়াল উপায় খুঁজে পেয়েছি I আমি মনে করি এটি আমাদের পক্ষে ভাল রেফারেন্স।

যেহেতু অ্যান্ড্রয়েড এপিআই স্তর 23 [অ্যান্ড্রয়েড 6.0]

package com.android.internal.util;

/**
 * @hide
 */
public class ScreenShapeHelper {
    private static final boolean IS_EMULATOR = Build.HARDWARE.contains("goldfish");
}

আমাদের ScreenShapeHelper.IS_EMULATORপরীক্ষা করতে হবে এমুলেটর কিনা।

যেহেতু অ্যান্ড্রয়েড এপিআই স্তর 24 [অ্যান্ড্রয়েড 7.0]

package android.os;

/**
 * Information about the current build, extracted from system properties.
 */
public class Build {


    /**
     * Whether this build was for an emulator device.
     * @hide
     */
    public static final boolean IS_EMULATOR = getString("ro.kernel.qemu").equals("1");

}

আমাদের Build.IS_EMULATORপরীক্ষা করতে হবে এমুলেটর কিনা।

এমুলেটরটি নতুন নয় এবং সম্ভবত পর্যাপ্ত নয় কিনা তা যাচাইয়ের জন্য কর্মকর্তাও উপরের উত্তরগুলিও উল্লেখ করেছেন।

তবে এটি সম্ভবত আমাদের দেখান যে অফিসারটি এমুলেটর রয়েছে কিনা তা যাচাই করার জন্য আধিকারিককে কর্মকর্তার উপায় সরবরাহ করবে।

উল্লিখিত সমস্ত উপায়ে উল্লিখিত হিসাবে, এখনই আমরা এমুলেটরটি পরীক্ষা করতে দুটি উপায়ও ব্যবহার করতে পারি।

কীভাবে com.android.internalপ্যাকেজ অ্যাক্সেস করবেন এবং@hide

এবং অফিসিয়াল ওপেন এসডিকে অপেক্ষা করুন।


5

আমার সুপারিশ:

চেষ্টা এই GitHub থেকে।

অ্যান্ড্রয়েড এমুলেটর সনাক্ত করা সহজ

  • ডিভাইস ফার্মে বাস্তব ডিভাইসে চেক করা হয়েছে ( https://aws.amazon.com/device-farm/ )
  • BlueStacks
  • Genymotion
  • অ্যান্ড্রয়েড এমুলেটর
  • অ্যান্ডি 46.2.207.0
  • মেমু খেলি
  • নক্স অ্যাপ প্লেয়ার
  • Koplayer
  • .....

উদাহরণ দিয়ে কীভাবে ব্যবহার করবেন:

EmulatorDetector.with(this)
                .setCheckTelephony(true)
                .addPackageName("com.bluestacks")
                .setDebug(true)
                .detect(new EmulatorDetector.OnEmulatorDetectorListener() {
                    @Override
                    public void onResult(boolean isEmulator) {

                    }
                });

4

আপনি IMEI # পরীক্ষা করতে পারেন, http://developer.android.com/references/android/telephony/TelephonyManager.html#getDeviceId ২৯%

যদি আমি এমুলেটরটি এই রিটার্নটি 0 এ প্রত্যাহার করি তবে যাইহোক, এমন কোনও ডকুমেন্টেশন নেই যা আমি নিশ্চিত হতে পারি। যদিও এমুলেটরটি সর্বদা 0 ফেরত না আসে তবে এটি নিরাপদ বলে মনে হয় যে নিবন্ধিত ফোনটি 0 ফিরে আসবে না a কোনও ফোনটি অ্যান্ড্রয়েড ডিভাইসে কী ঘটবে, অথবা সিম কার্ডবিহীন একটি বা বর্তমানে যা নিবন্ধিত নেই অন্তর্জাল?

মনে হয় এটি একটি খারাপ ধারণা হতে চাই, তার উপর নির্ভর করে।

এর অর্থ হ'ল আপনাকে ফোনের স্থিতি পড়ার জন্য অনুমতি চাইতে হবে, এটি যদি আপনার অন্যর জন্য ইতিমধ্যে প্রয়োজন না হয় তবে তা খারাপ।

যদি তা না হয়, তবে আপনি অবশেষে আপনার স্বাক্ষরিত অ্যাপ্লিকেশনটি তৈরি করার আগে সর্বদা কিছুটা ফ্লিপ হয়।


5
আইএমইআই সম্ভবত 0একটি অ্যান্ড্রয়েড ট্যাবলেট বা সিম কার্ড ছাড়াই কোনও ফোনে ফিরে আসতে পারে ।
পল ল্যামার্তসমা

আমরা এমুলেটরটিতে আইএমইআই সম্পাদনা করতে পারি। সুতরাং এটি উদ্দেশ্যটি পরিবেশন করতে পারে না। এছাড়াও, API 29 থেকে শুরু করে আমরা IMEI অ্যাক্সেস করতে পারি না।
অনন্ত

4
Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")

অ্যাপ্লিকেশনটি কোনও এমুলেটরটিতে চলমান থাকলে এটি সত্য হওয়া উচিত return

আমাদের যে বিষয়ে সাবধানতা অবলম্বন করা উচিত সেগুলি সমস্ত অনুকরণকারীকে সনাক্তকরণ নয় কারণ সেখানে কেবল বেশ কয়েকটি পৃথক এমুলেটর রয়েছে। এটি যাচাই করা সহজ। আমাদের নিশ্চিত করতে হবে যে প্রকৃত ডিভাইসগুলি এমুলেটর হিসাবে সনাক্ত করা যায় নি।

আমি " অ্যান্ড্রয়েড ডিভাইস তথ্য ভাগ " নামে অ্যাপটি ব্যবহার করেছি পরীক্ষা করতে " ।

এই অ্যাপ্লিকেশনটিতে, আপনি অনেকগুলি ডিভাইসের বিভিন্ন ধরণের তথ্য দেখতে পাবেন (সম্ভবত বিশ্বের বেশিরভাগ ডিভাইস; আপনি যে ডিভাইসটি ব্যবহার করছেন সেটি যদি তালিকা থেকে অনুপস্থিত থাকে, তবে এটি স্বয়ংক্রিয়ভাবে যুক্ত হয়ে যাবে)।


আমার জিনমোশনটিতে একটি ম্যাক বিল্ডে চলছে DE DEVICE = vbox86p
lxknvlk

3

প্রকৃতপক্ষে, ২.২ এ ANDROID_ID সর্বদা 9774D56D682E549C এর সমান ( এই থ্রেড + আমার নিজের পরীক্ষাগুলি অনুসারে)।

সুতরাং, আপনি এই জাতীয় কিছু পরীক্ষা করতে পারেন:

String androidID = ...;
if(androidID == null || androidID.equals("9774D56D682E549C"))
    do stuff;

সবচেয়ে সুন্দর নয়, তবে এটি কাজটি করে।


8
এই ভয়াবহ বাগের কারণে আমি তার সাথে সতর্ক থাকব
ব্র্যান্ডন

3

এটি আমার পক্ষে কাজ করে

public boolean isEmulator() {
    return Build.MANUFACTURER.equals("unknown");
}

3
আমাদের ঘরে থাকা ফার্মওয়্যার ইঞ্জিনিয়ার এটি আপডেট করেনি; আমাদের হার্ডওয়্যারে বিল্ড। ম্যানুফ্যানচারার পেয়ে "অজানা" ফিরে এসেছে। ফিঙ্গারপ্রিন্টটি আরও ভাল উপায় বলে মনে হচ্ছে।
কেউ কোথাও

3

এমুলেটরের ফাইল সিস্টেমে একটি ফাইল রাখুন; যেহেতু ফাইলটি আসল ডিভাইসে থাকবে না তাই এটি স্থিতিশীল, নির্ভরযোগ্য এবং ব্রেকিংয়ের পরে ঠিক করা সহজ হওয়া উচিত।


3

আমি এই প্রশ্নের সমস্ত উত্তর সংগ্রহ করেছি এবং অ্যান্ড্রয়েড কোনও ভিএম / এমুলেটরটিতে চলছে কিনা তা সনাক্ত করতে ফাংশন নিয়ে এসেছি:

public boolean isvm(){


        StringBuilder deviceInfo = new StringBuilder();
        deviceInfo.append("Build.PRODUCT " +Build.PRODUCT +"\n");
        deviceInfo.append("Build.FINGERPRINT " +Build.FINGERPRINT+"\n");
        deviceInfo.append("Build.MANUFACTURER " +Build.MANUFACTURER+"\n");
        deviceInfo.append("Build.MODEL " +Build.MODEL+"\n");
        deviceInfo.append("Build.BRAND " +Build.BRAND+"\n");
        deviceInfo.append("Build.DEVICE " +Build.DEVICE+"\n");
        String info = deviceInfo.toString();


        Log.i("LOB", info);


        Boolean isvm = false;
        if(
                "google_sdk".equals(Build.PRODUCT) ||
                "sdk_google_phone_x86".equals(Build.PRODUCT) ||
                "sdk".equals(Build.PRODUCT) ||
                "sdk_x86".equals(Build.PRODUCT) ||
                "vbox86p".equals(Build.PRODUCT) ||
                Build.FINGERPRINT.contains("generic") ||
                Build.MANUFACTURER.contains("Genymotion") ||
                Build.MODEL.contains("Emulator") ||
                Build.MODEL.contains("Android SDK built for x86")
                ){
            isvm =  true;
        }


        if(Build.BRAND.contains("generic")&&Build.DEVICE.contains("generic")){
            isvm =  true;
        }

        return isvm;
    }

এমুলেটর, জিনমোশন এবং ব্লুস্ট্যাকগুলিতে পরীক্ষিত (1 অক্টোবর 2015)।


3

উত্তরগুলি পরীক্ষা করে, লিপড্রয়েড, ড্রয়েড 4 এক্স বা অ্যান্ডি এমুলেটর ব্যবহার করার সময় তাদের কেউই কাজ করেনি,

সমস্ত ক্ষেত্রে কী কাজ করে তা নিম্নলিখিত:

 private static String getSystemProperty(String name) throws Exception {
    Class systemPropertyClazz = Class.forName("android.os.SystemProperties");
    return (String) systemPropertyClazz.getMethod("get", new Class[]{String.class}).invoke(systemPropertyClazz, new Object[]{name});
}

public boolean isEmulator() {
    boolean goldfish = getSystemProperty("ro.hardware").contains("goldfish");
    boolean emu = getSystemProperty("ro.kernel.qemu").length() > 0;
    boolean sdk = getSystemProperty("ro.product.model").equals("sdk");
    return goldfish || emu || sdk;
}


Andy_46.16_48 বিল্ডের জন্য "অ্যান্ডি" ফেরায় AR হার্ডওয়ার
ডগ ভস

স্যামসাং জে সিরিজের ডিভাইসের জন্য মিথ্যা ইতিবাচক নেতৃত্ব দিন। ব্যবহৃত এমুলেটর সনাক্ত করতে নিম্নলিখিত: github.com/gingo/android-emulator-detector
bluetoothfx

2

যেহেতু জিনমোশনটির অন্তর্নিহিত এমুলেশন ইঞ্জিনটি ভার্চুয়ালবক্স এবং এটি খুব শীঘ্রই কোনও সময় পরিবর্তন করতে যাচ্ছে না আমি নিম্নলিখিত কোডটি সবচেয়ে নির্ভরযোগ্য পেয়েছি:

   public static boolean isGenymotion() {
        return Build.PRODUCT != null && Build.PRODUCT.contains("vbox");
}

2

যেটা আপনি যে কোডটি এমুলেটর সনাক্তকরণ করতে ব্যবহার করেন, আমি অত্যন্ত সব আবরণ ইউনিট পরীক্ষা লেখার বলতে চাই Build.FINGERPRINT, Build.HARDWAREএবং Build.MANUFACTURERমান আপনি উপর নির্ভর করে করা হয়। এখানে কয়েকটি উদাহরণ পরীক্ষা দেওয়া হল:

@Test
public void testIsEmulatorGenymotion() throws Exception {
    assertThat(
            DeviceUtils.isRunningOnEmulator(
                    "generic/vbox86p/vbox86p:4.1.1/JRO03S/eng.buildbot.20150217.102902:userdebug/test-keys",
                    "vbox86", "Genymotion")).isTrue();

    assertThat(
            DeviceUtils.isRunningOnEmulator(
                    "generic/vbox86p/vbox86p:5.1/LMY47D/buildbot06092001:userdebug/test-keys", "vbox86",
                    "Genymotion")).isTrue();
}

@Test
public void testIsEmulatorDefaultAndroidEmulator() throws Exception {
    assertThat(
            DeviceUtils.isRunningOnEmulator(
                    "generic_x86/sdk_google_phone_x86/generic_x86:5.0.2/LSY66H/1960483:eng/test-keys", "goldfish",
                    "unknown")).isTrue();

    assertThat(
            DeviceUtils.isRunningOnEmulator(
                    "Android/sdk_google_phone_x86_64/generic_x86_64:6.0/MASTER/2469028:userdebug/test-keys",
                    "ranchu", "unknown")).isTrue();
}

@Test
public void testIsEmulatorRealNexus5() throws Exception {
    assertThat(
            DeviceUtils.isRunningOnEmulator("google/hammerhead/hammerhead:6.0.1/MMB29K/2419427:user/release-keys",
                    "hammerhead", "LGE")).isFalse();
}

... এবং এখানে আমাদের কোড (সংক্ষিপ্ততার জন্য ডিবাগ লগ এবং মন্তব্যগুলি সরানো হয়েছে):

public static boolean isRunningOnEmulator() {
    if (sIsRunningEmulator == null) {
        sIsRunningEmulator = isRunningOnEmulator(Build.FINGERPRINT, Build.HARDWARE, Build.MANUFACTURER);
    }

    return sIsRunningEmulator;
}

static boolean isRunningOnEmulator(String fingerprint, String hardware, String manufacturer) {
    boolean isEmulatorFingerprint = fingerprint.endsWith("test-keys");
    boolean isEmulatorManufacturer = manufacturer.equals("Genymotion")
            || manufacturer.equals("unknown");

    if (isEmulatorFingerprint && isEmulatorManufacturer) {
        return true;
    } else {
        return false;
    }
}

2

অন্য বিকল্পটি হ'ল আপনি ডিবাগ মোডে বা উত্পাদন মোডে আছেন কিনা তা পরীক্ষা করা:

if (BuildConfig.DEBUG) { Log.i(TAG, "I am in debug mode"); }

সহজ এবং নির্ভরযোগ্য।

পুরোপুরি প্রশ্নের উত্তর নয় তবে বেশিরভাগ ক্ষেত্রে আপনি আপনার ব্যবহারকারীর বেসের ডিবাগিং / টেস্ট সেশন এবং লাইফ সেশনগুলির মধ্যে পার্থক্য করতে চাইতে পারেন।

আমার ক্ষেত্রে আমি গুগল অ্যানালিটিকাগুলি শুকনুনে সেট করে () যখন ডিবাগ মোডে থাকি তাই এই পদ্ধতিরটি আমার পক্ষে সম্পূর্ণ সূক্ষ্মভাবে কাজ করে।


আরও উন্নত ব্যবহারকারীদের জন্য আরও একটি বিকল্প রয়েছে। গ্রেড বিল্ড রূপগুলি:

আপনার অ্যাপ্লিকেশানের গ্রেড ফাইলটিতে একটি নতুন রূপ যুক্ত করুন:

buildTypes {
    release {
        // some already existing commands
    }
    debug {
        // some already existing commands
    }
    // the following is new
    test {
    }
}

আপনার কোডে বিল্ড টাইপ পরীক্ষা করুন:

if ("test".equals(BuildConfig.BUILD_TYPE)) { Log.i(TAG, "I am in Test build type"); }
 else if ("debug".equals(BuildConfig.BUILD_TYPE)) { Log.i(TAG, "I am in Debug build type"); }

এখন আপনার কাছে আপনার অ্যাপ্লিকেশনটির 3 টি বিভিন্ন ধরণের তৈরি করার সুযোগ রয়েছে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.