5. تهيئة SDK وAdsManager
5.1 فئة Application
أنشئ فئة ترث من AppsKitSDKApplication ونفّذ أعضاءها المجرّدة الخمسة:
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() في تطبيقك:
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 فقط):
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()، وتعرضان افتراضيًا مربع حوار «لا يوجد اتصال بالإنترنت» يمنع التفاعل مع الشاشة كلما انقطع الاتصال، ثم تغلقانه تلقائيًا عند عودة الاتصال. هذا السلوك مفعّل لكل شاشة ما لم تعطّله:
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() (أسلوب محمي، متاح في فئتي النشاط الأساسيتين):
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 ليعرف أن عرض الإعلانات مسموح:
AdsManager.initializeAds(userHasGivenConsent = true, isCCPAConsent = true)5.5 إزالة الإعلانات / التحكم عبر عمليات الشراء داخل التطبيق (IAP)
إذا كان تطبيقك يبيع خيار «إزالة الإعلانات»، فاربطه عبر AKS بدلًا من تقييد استدعاءات الإعلانات بنفسك — إذ يتحقّق كل استدعاء تحميل أو عرض من هذا العَلَم داخليًا بالفعل:
AppsKitSDK.setRemoveAdsStatus(true) // call after a successful purchase/restore
AppsKitSDK.getRemoveAdsStatus() // check current status