التوثيق · التكامل مع 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