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