واجهة برمجة التطبيقات SafetyNetVerify Apps API

تتيح واجهة برمجة التطبيقات SafetyNet Verify Apps API، وهي مكتبة مستندة إلى خدمات Google Play، لتطبيقك التفاعل آليًا مع ميزة التحقّق من التطبيقات على الجهاز، ما يحمي الجهاز من التطبيقات التي يُحتمل أن تكون ضارة.

إذا كان تطبيقك يعالج بيانات حسّاسة للمستخدمين، مثل المعلومات المالية، من المهم التأكّد من أنّ جهاز المستخدم محمي من التطبيقات الضارة وأنّه لا يحتوي على أي تطبيقات يمكنها انتحال هوية تطبيقك أو تنفيذ إجراءات ضارة أخرى. إذا كانت أمان الجهاز لا تستوفي الحد الأدنى من إجراءات الأمان، يمكنك إيقاف الوظائف في تطبيقك للحد من الخطر الذي يواجهه المستخدم.

في إطار التزامها المستمر بجعل منظومة Android المتكاملة آمنة قدر الإمكان، تتتبّع Google سلوك تطبيقات Android وتصنّفه. إذا رصدت ميزة التحقّق من التطبيقات تطبيقًا يُحتمل أن يكون خطيرًا، يتم إرسال إشعار إلى كل المستخدمين الذين ثبَّتوا التطبيق وننصحك بالبدء في إزالته على الفور. وتحمي هذه العملية أمان هؤلاء المستخدمين وخصوصيتهم.

تتيح لك SafetyNet Verify Apps API الاستفادة من هذه الميزة لحماية بيانات تطبيقك. باستخدام واجهة برمجة التطبيقات هذه، يمكنك تحديد ما إذا كان جهاز المستخدم محميًا من خلال ميزة "التحقّق من التطبيقات"، وتشجيع المستخدمين الذين لا يستخدمون الميزة على تفعيل الحماية، وتحديد أي تطبيقات معروفة قد تتسبّب بضرر تم تثبيتها على الجهاز.

بنود الخدمة الإضافية

عند الوصول إلى واجهات برمجة تطبيقات SafetyNet أو استخدامها، يعني ذلك أنّك توافق على بنود خدمة Google APIs وبنود خدمة واجهة برمجة التطبيقات Verify Apps API التالية. يُرجى قراءة وفهم جميع البنود والسياسات السارية قبل الوصول إلى واجهات برمجة التطبيقات.

بنود خدمة Verify Apps API

قد تؤدي تحليلات التطبيقات التي ترصد التطبيقات التي يُحتمل أن تكون ضارة إلى نتائج إيجابية خاطئة وسلبية خاطئة. يتم تقديم النتائج (أو عدم وجودها) الناتجة من مجموعة واجهة برمجة التطبيقات هذه على أفضل وجه حسب فهمنا. أنت تقرّ وتفهم أنّه لا يمكن ضمان دقة النتائج التي تعرضها مجموعة واجهة برمجة التطبيقات SafetyNet API في جميع الأوقات.

إضافة التبعية لواجهة برمجة التطبيقات SafetyNet

قبل استخدام واجهة برمجة التطبيقات لميزة "التحقق من التطبيقات"، أضِف SafetyNet API إلى مشروعك. إذا كنت تستخدم "استوديو Android"، أضِف هذه التبعية إلى ملف Gradle على مستوى التطبيق. لمزيد من المعلومات، يُرجى الاطّلاع على إعداد واجهة برمجة التطبيقات SafetyNet API.

تفعيل ميزة "إثبات ملكية التطبيق"

توفّر واجهة برمجة التطبيقات SafetyNet Verify Apps API طريقتَين لتفعيل ميزة إثبات ملكية التطبيقات. يمكنك معرفة ما إذا كان ميزة التحقّق من التطبيقات مفعّلة باستخدام isVerifyAppsEnabled()، ويمكنك طلب تفعيل ميزة التحقّق من التطبيقات باستخدام enableVerifyApps().

والفرق بين هاتين الطريقتين هو أنّه على الرغم من أنّ ميزة "isVerifyAppsEnabled()" تُبلِغ عن الحالة الحالية لميزة "التحقق من التطبيقات"، تطلب ميزة "enableVerifyApps()" صراحةً من المستخدم الموافقة على استخدام هذه الميزة. إذا أردت أن يكون تطبيقك على دراية بحالة الميزة فقط لاتخاذ قرار يستند إلى الأمان، يجب أن يستدعي تطبيقك isVerifyAppsEnabled(). ومع ذلك، إذا كنت تريد التأكّد من أنّ تطبيقك يمكنه إدراج التطبيقات المثبَّتة التي يُحتمل أن تكون ضارّة، يجب الاتصال برقم enableVerifyApps() بدلاً من ذلك.

تحديد ما إذا كان خيار "التحقّق من التطبيقات" مفعّلاً

تسمح طريقة isVerifyAppsEnabled() غير المتزامنة لتطبيقك بتحديد ما إذا كان المستخدم مسجّلاً في ميزة "التحقق من التطبيقات". تعرض هذه الوسيلة عنصرًا من النوع VerifyAppsUserResponse يحتوي على معلومات بشأن جميع الإجراءات التي اتّخذها المستخدم في ما يتعلّق بميزة "التحقّق من التطبيقات"، بما في ذلك تفعيلها.

يوضِّح مقتطف الرمز البرمجي التالي كيفية إنشاء دالة الاستدعاء المرتبطة بهذه المحاولة:

Kotlin

SafetyNet.getClient(this)
        .isVerifyAppsEnabled
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                if (task.result.isVerifyAppsEnabled) {
                    Log.d("MY_APP_TAG", "The Verify Apps feature is enabled.")
                } else {
                    Log.d("MY_APP_TAG", "The Verify Apps feature is disabled.")
                }
            } else {
                Log.e("MY_APP_TAG", "A general error occurred.")
            }
        }

Java

SafetyNet.getClient(this)
    .isVerifyAppsEnabled()
    .addOnCompleteListener(new OnCompleteListener<VerifyAppsUserResponse>() {
        @Override
        public void onComplete(Task<VerifyAppsUserResponse> task) {
            if (task.isSuccessful()) {
                VerifyAppsUserResponse result = task.getResult();
                if (result.isVerifyAppsEnabled()) {
                    Log.d("MY_APP_TAG", "The Verify Apps feature is enabled.");
                } else {
                    Log.d("MY_APP_TAG", "The Verify Apps feature is disabled.");
                }
            } else {
                Log.e("MY_APP_TAG", "A general error occurred.");
            }
        }
    });

طلب تفعيل ميزة "التحقّق من التطبيق"

تتيح لك الطريقة غير المتزامنة enableVerifyApps() أن يعرض تطبيقك مربّع حوار يطلب من المستخدم تفعيل ميزة "التحقق من التطبيقات". تعرض هذه الوسيلة عنصرًا من النوع VerifyAppsUserResponse يحتوي على معلومات بشأن جميع الإجراءات التي اتخذها المستخدم في ما يتعلّق بميزة "التحقّق من التطبيقات"، بما في ذلك ما إذا كان قد منح موافقته على تفعيلها.

يوضِّح مقتطف الرمز البرمجي التالي كيفية إنشاء دالة الاستدعاء المرتبطة بهذه المحاولة:

Kotlin

SafetyNet.getClient(this)
        .enableVerifyApps()
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                if (task.result.isVerifyAppsEnabled) {
                    Log.d("MY_APP_TAG", "The user gave consent to enable the Verify Apps feature.")
                } else {
                    Log.d(
                            "MY_APP_TAG",
                            "The user didn't give consent to enable the Verify Apps feature."
                    )
                }
            } else {
                Log.e("MY_APP_TAG", "A general error occurred.")
            }
        }

Java

SafetyNet.getClient(this)
    .enableVerifyApps()
    .addOnCompleteListener(new OnCompleteListener<VerifyAppsUserResponse>() {
        @Override
        public void onComplete(Task<VerifyAppsUserResponse> task) {
            if (task.isSuccessful()) {
                VerifyAppsUserResponse result = task.getResult();
                if (result.isVerifyAppsEnabled()) {
                    Log.d("MY_APP_TAG", "The user gave consent " +
                          "to enable the Verify Apps feature.");
                } else {
                    Log.d("MY_APP_TAG", "The user didn't give consent " +
                          "to enable the Verify Apps feature.");
                }
            } else {
                Log.e("MY_APP_TAG", "A general error occurred.");
            }
        }
    });

يمكن أن يواجه تطبيقك شرطًا أو أكثر غير معتاد عند استخدام هذه الطريقة:

  • إذا كانت ميزة "التحقّق من التطبيقات" مفعّلة، لن يظهر مربّع الحوار، وستتصرف واجهة برمجة التطبيقات كما لو أنّ المستخدم قد منح موافقته على تفعيل هذه الميزة.
  • إذا غادر المستخدم مربّع الحوار، يتم إغلاقه، ويفترض واجهة برمجة التطبيقات أنّ المستخدم لم يمنح موافقته على تفعيل هذه الميزة.
  • إذا كان تطبيقك وتطبيق آخر يستدعيان هذه الطريقة في الوقت نفسه، لن يظهر سوى مربّع حوار واحد، وستتلقّى جميع التطبيقات قيمًا متطابقة من الطريقة.

قائمة التطبيقات المثبَّتة التي قد تسبّب ضررًا

تتيح لك الطريقة غير المتزامنة listHarmfulApps() الحصول على قائمة بأي تطبيقات معروفة يُحتمل أن تكون ضارة ثبّتها المستخدم على جهازه. تتضمّن هذه القائمة فئات للتطبيقات التي تم تحديدها على أنّها ضارة محتملة كي تتمكّن تطبيقاتك من اتّخاذ الإجراء المناسب.

يوضِّح مقتطف الرمز البرمجي التالي كيفية إنشاء دالة الاستدعاء المرتبطة بهذه المحاولة:

Kotlin

SafetyNet.getClient(this)
        .listHarmfulApps()
        .addOnCompleteListener { task ->
            Log.d(TAG, "Received listHarmfulApps() result")

            if (task.isSuccessful) {
                val result = task.result
                val scanTimeMs = result.lastScanTimeMs

                val appList = result.harmfulAppsList
                if (appList?.isNotEmpty() == true) {
                    Log.e("MY_APP_TAG", "Potentially harmful apps are installed!")

                    for (harmfulApp in appList) {
                        Log.e("MY_APP_TAG", "Information about a harmful app:")
                        Log.e("MY_APP_TAG", "  APK: ${harmfulApp.apkPackageName}")
                        Log.e("MY_APP_TAG", "  SHA-256: ${harmfulApp.apkSha256}")

                        // Categories are defined in VerifyAppsConstants.
                        Log.e("MY_APP_TAG", "  Category: ${harmfulApp.apkCategory}")
                    }
                } else {
                    Log.d("MY_APP_TAG", "There are no known potentially harmful apps installed.")
                }
            } else {
                Log.d(
                        "MY_APP_TAG",
                        "An error occurred. Call isVerifyAppsEnabled() to ensure that the user "
                                + "has consented."
                )
            }
        }

Java

SafetyNet.getClient(this)
    .listHarmfulApps()
    .addOnCompleteListener(new OnCompleteListener<HarmfulAppsResponse>() {
        @Override
        public void onComplete(Task<HarmfulAppsResponse> task) {
            Log.d(TAG, "Received listHarmfulApps() result");

            if (task.isSuccessful()) {
                HarmfulAppsResponse result = task.getResult();
                long scanTimeMs = result.getLastScanTimeMs();

                List<HarmfulAppsData> appList = result.getHarmfulAppsList();
                if (appList.isEmpty()) {
                    Log.d("MY_APP_TAG", "There are no known " +
                          "potentially harmful apps installed.");
                } else {
                    Log.e("MY_APP_TAG",
                          "Potentially harmful apps are installed!");

                    for (HarmfulAppsData harmfulApp : appList) {
                        Log.e("MY_APP_TAG", "Information about a harmful app:");
                        Log.e("MY_APP_TAG",
                              "  APK: " + harmfulApp.apkPackageName);
                        Log.e("MY_APP_TAG",
                              "  SHA-256: " + harmfulApp.apkSha256);

                        // Categories are defined in VerifyAppsConstants.
                        Log.e("MY_APP_TAG",
                              "  Category: " + harmfulApp.apkCategory);
                    }
                }
            } else {
                Log.d("MY_APP_TAG", "An error occurred. " +
                      "Call isVerifyAppsEnabled() to ensure " +
                      "that the user has consented.");
            }
        }
    });