التوثيق · AppsKitSDK (AKS) — دليل التكامل مع Android

5. تهيئة SDK وAdsManager

5.1 فئة Application

أنشئ فئة ترث من AppsKitSDKApplication ونفّذ أعضاءها المجرّدة الخمسة:

kotlin
class YourApplication : AppsKitSDKApplication() {

    // Encrypted default-config JSON to fall back on before Remote Config is fetched.
    // Provided to you from the AKS portal for your app.
    override fun setAKSDefaultConfigs(): String = "<encrypted-config-json-from-aks-portal>"

    override fun isTestMode(): Boolean = BuildConfig.DEBUG

    override fun isDevMode(): Boolean = BuildConfig.DEBUG

    override fun setPlatform(): Platform = Platform.GOOGLE // or Platform.AMAZON

    override fun onConfigsReadyToUse(remoteConfig: FirebaseRemoteConfig) {
        // Called once Firebase Remote Config has been fetched/activated.
        // Optional hook if you need to read custom remote-config keys yourself.
    }
}

تتولى onCreate() في الفئة الأساسية المهام الرئيسية نيابةً عنك — فهي تستدعي AppsKitSDK.initialize/setPlatform/setTestMode/setDevMode، وتجلب الإعدادات الافتراضية وتحفظها، وتبدأ تنفيذ manageRemoteConfigs()، وتستدعي AppsKitSDK.initMMP() لربط AppsFlyer/Adjust/Solar Engine. لا تحتاج إلى استدعاء أيٍّ منها بنفسك.

5.2 التهيئة دون الوراثة من AppsKitSDKApplication

الوراثة من AppsKitSDKApplication ليست إلزامية — فهي فئة تغليف لتسهيل التكامل. إذا كان تطبيقك يعتمد بالفعل على فئة أساسية خاصة به من نوع Application ولا يمكنك الاستغناء عنها، فيمكنك استدعاء دوال AppsKitSDK نفسها التي تستدعيها هذه الفئة داخليًا، مباشرةً من Application.onCreate() الخاصة بتطبيقك:

kotlin
class YourApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        FirebaseApp.initializeApp(this)

        AppsKitSDK.initialize(PlatformContext(this), this)
        AppsKitSDK.setPlatform(Platform.GOOGLE) // or Platform.AMAZON
        AppsKitSDK.setTestMode(BuildConfig.DEBUG)
        AppsKitSDK.setDevMode(BuildConfig.DEBUG)
        AppsKitSDK.setTimeToFetchRemoteConfigInSeconds(3600) // optional, defaults to 3600

        AppsKitSDK.saveDefaultConfigJson("<encrypted-config-json-from-aks-portal>")
        AppsKitSDK.manageRemoteConfigs(object : OnRemoteConfigAvailable {
            override fun onRemoteConfigReadyToFetch(remoteConfig: FirebaseRemoteConfig) {
                // optional — your own hook into the fetched remote config
            }
        })

        AppsKitSDK.initMMP() // wires up AppsFlyer / Adjust / Solar Engine from remote-config keys

        // AppsKitSDKApplication does this for you via ActivityLifecycleCallbacks. Without it,
        // AppsKitSDK has no "current activity" — native-ad preloading and any code that calls
        // AppsKitSDK.getCurrentActivity() won't have a target to work with.
        registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
            override fun onActivityResumed(activity: Activity) {
                AppsKitSDK.setCurrentActivity(PlatformActivity(activity))
                Adjust.onResume() // keeps Adjust session tracking accurate
            }
            override fun onActivityPaused(activity: Activity) {
                Adjust.onPause()
            }
            override fun onActivityCreated(activity: Activity, bundle: Bundle?) {}
            override fun onActivityStarted(activity: Activity) {}
            override fun onActivityStopped(activity: Activity) {}
            override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) {}
            override fun onActivityDestroyed(activity: Activity) {}
        })
    }
}

ما تفقده عند عدم الوراثة من الفئة الأساسية: معالجة إشعارات البث ومربع الحوار الخاصين بالاتصال بالإنترنت، ومسار عرض «إعلان فتح التطبيق على مستوى التطبيق» المدمج (requestSplashAppOpenAd/showAppOpenAd، الذي يُشغَّل تلقائيًا من onStart) — فهذه دوال مثيل تابعة لـAppsKitSDKApplication نفسها، وليست متاحة على الكائن AppsKitSDK. إذا كنت لا تزال ترغب في عرض إعلان فتح التطبيق عند بدء التشغيل البارد، فاستدعِ AdsManager.loadAppOpen/AdsManager.showAppOpen بنفسك (راجع §6) في الموضع المناسب ضمن مسار بدء التشغيل الخاص بتطبيقك.

5.3 الأنشطة

أنشئ فئة ترث من AppsKitSDKBaseActivity (للشاشات المبنية على AppCompatActivity) أو من AppsKitSDKBaseComponentActivity (للشاشات المبنية على ComponentActivity مباشرةً أو التي تستخدم Compose فقط):

kotlin
class HomeActivity : AppsKitSDKBaseActivity() {

    override fun setScreenNameAndId(): Pair<Int, String> = Pair(1, "Home")

    override fun enableAppAutoUpdate(): Boolean = true

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState) // required — this drives ad-network init, preloading,
                                            // session/day tracking, and the auto SCREEN event
        setContent { /* your Compose UI */ }
    }
}

توفّر لك الوراثة من هذه الفئات الأساسية تلقائيًا: تهيئة شبكات الإعلانات والتحميل المسبق في الشاشة الأولى، وتمرير استدعاءات دورة الحياة إلى IronSource في onResume/onPause، وتتبّع الجلسات وعدد الأيام، ومربع حوار للاتصال بالإنترنت، ومطالبات اختيارية بالتحديث داخل التطبيق، والدالة sendAKSEvent(...) لإرسال أحداث مرتبطة بهذه الشاشة (راجع §7). (أما تمرير استدعاءات onResume/onPause الخاصة بـAdjust فيتم على مستوى Application — راجع §5.2 — وليس هنا.)

مربع حوار الاتصال بالإنترنت

تراقب فئتا النشاط الأساسيتان الاتصال في onResume()، وتعرضان افتراضيًا مربع حوار «لا يوجد اتصال بالإنترنت» يمنع التفاعل مع الشاشة عند انقطاع الاتصال، ثم تغلقانه تلقائيًا عند عودة الاتصال. هذه الميزة مفعّلة لكل شاشة ما لم تعطّلها:

kotlin
class HomeActivity : AppsKitSDKBaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        showInternetConnectivity(false) // opt this screen out of the automatic dialog
    }

    // Called on every connectivity change, dialog or not — hook your own UI here
    override fun onInternetConnectivityChange(isInternetAvailable: Boolean?) {
        // e.g. show/hide your own offline banner
    }

    // Optional — return an anchor view to get a "back online" Snackbar when the
    // dialog dismisses on reconnect. Returns null (no Snackbar) by default.
    override fun getSnackBarView(): View? = findViewById(R.id.rootLayout)
}

عند استدعاء showInternetConnectivity(false)، يظل AKS يستدعي onInternetConnectivityChange، لكنه يمرّر دائمًا true بغض النظر عن حالة الاتصال الفعلية — إذ لا يتتبّع الاتصال الفعلي بعد تعطيل إدارته. إذا كنت تحتاج إلى حالة دقيقة هنا، فاعتمد على فحص الاتصال الخاص بك للتحكم في واجهة انقطاع الاتصال التي توفّرها.

تقييد الشاشة بالاتجاه العمودي

لقفل شاشة على الاتجاه العمودي، استدعِ restrictPortraitOnly() (وهي دالة محمية ومتاحة في فئتَي النشاط الأساسيتين):

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    restrictPortraitOnly()
}

يؤدي ذلك إلى استدعاء setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT) نيابةً عنك — باستثناء Android 8.0 (API 26)، حيث يُتخطّى هذا الاستدعاء عمدًا، لأن setRequestedOrientation معروف بتسبّبه في تعطل الأنشطة ذات السمات شبه الشفافة أو العائمة في هذا الإصدار تحديدًا من نظام التشغيل.

5.4 الموافقة وتهيئة الإعلانات

بعد الحصول على الموافقة (مثلًا عبر مسار UMP/CMP من Google)، أبلغ AKS بأن عرض الإعلانات أصبح مسموحًا:

kotlin
AdsManager.initializeAds(userHasGivenConsent = true, isCCPAConsent = true)

5.5 إزالة الإعلانات / التحكم بناءً على عمليات الشراء داخل التطبيق (IAP)

إذا كان تطبيقك يوفّر عملية شراء «إزالة الإعلانات»، فاربطها عبر AKS بدلًا من التحكم بنفسك في السماح باستدعاءات الإعلانات — إذ يتحقّق كل استدعاء تحميل أو عرض بالفعل من هذه العلامة داخليًا:

kotlin
AppsKitSDK.setRemoveAdsStatus(true)   // call after a successful purchase/restore
AppsKitSDK.getRemoveAdsStatus()       // check current status