مرکز راهنماراهنما در پنلبسته اتصال

Android · Kotlin

نمای بومی، تمام‌صفحه و جایزه؛ بدون سرور.

نسخه ۱ · اتصال مستقیم

سه قدم تا اولین تبلیغ Android · Kotlin

  1. رسانه و جایگاه همان فرمت را ثبت و تأیید کنید.
  2. بسته همین پلتفرم را نصب کنید.
  3. شناسه UNT_ مثال را با شناسه جایگاه خود جایگزین کنید.
اپ شما به سرور نیاز ندارد.

نشانی HTTPS در مثال، سرور خود دیدنکس است. در حالت مستقیم، JWT، کلید خصوصی و ورود کاربر لازم نیست. Android، iOS، Unity و B4A شناسه بسته را از خود اپ می‌خوانند؛ Flutter نیز در initialize جدید، شناسه بسته را محلی می‌خواند؛ ورود دستی در روش سازگار قدیمی ممکن است. تغییر دامنه دیدنکس فقط به تغییر همین نشانی در تنظیم اپ نیاز دارد.

۱. نصب و تنظیم اولیه

برای اتصال سبک، DidnexAdView.kt، DidnexAudience.kt، DidnexPush.kt و DidnexPresentation.java را در سورس ماژول اپ با package اصلی com.didnex.ads کپی کنید. از AndroidX، Firebase یا Google Play برای تبلیغ پایه استفاده نمی‌شود. DidnexIntegrity.kt و وابستگی Play Integrity فقط برای اعتبارسنجی اختیاری اپ هستند. برای AAR از پروژه gradle-project استفاده کنید.

Android API ≥24، Kotlin پروژه میزبان، JDK 17 برای ساخت پروژه همراه. نمونه از android.app.Activity استفاده می‌کند و AndroidX اجباری نیست.

import com.didnex.ads.DidnexAdView
val ad = DidnexAdView(this)
container.addView(ad)
ad.loadDirect("https://didnex.com", "UNT_BANNER")
// On permanent removal: ad.destroy()

راه‌اندازی یک‌باره تبلیغ و پوش

نمونه کوتاه زیر فقط تنظیم اولیه است؛ callback و ظرف نمایش را در مثال کامل همین صفحه ببینید. init اجازه اعلان نمی‌گیرد و عضویت خودکار ندارد. یک کلاینت را برای عمر اپ نگه دارید و همان را برای تبلیغ و پوش استفاده کنید.

val placementId = "PASTE_YOUR_PLACEMENT_ID_HERE"
val client = com.didnex.ads.Didnex.initialize(applicationContext, origin="https://didnex.com")
val ad = com.didnex.ads.DidnexAdView(this)
container.addView(ad)
client.load(ad, placementId)
// Fullscreen: client.showInterstitial(ad, placementId)
// Reward: client.showRewarded(ad, placementId) { receipt -> /* server-applied receipt */ }
// Push: client.createPush(placementId, onMessage = { message -> false })

اندازه ثابت جایگاه

اندازه از slot جایگاه تعیین می‌شود؛ تصویر و ویدیو با contain داخل همان کادرند. ابعاد فایل یا آماده‌شدن ویدیو، اندازه بیرونی را عوض نمی‌کند. noFill و خطا کادر را جمع می‌کنند. در Unity و Godot مستطیل میزبان را مطابق پروفایل انتخاب کنید.

پروفایل دیدنکساندازه مرجعنوار ثابت زیر رسانه
بنر استاندارد ۳۲۰ × ۵۰320 × 50ندارد
بنر بزرگ ۳۲۰ × ۱۰۰320 × 100ندارد
بنر مستطیل ۳۰۰ × ۲۵۰300 × 250ندارد
بنر عریض ۷۲۸ × ۹۰728 × 90ندارد
بنر تطبیقی با نسبت ۳۲۰ × ۵۰320 × 50ندارد
همسان افقی ۱۶:۹ + نوار ثابت640 × 36084 پیکسل منطقی
همسان مربع + نوار ثابت600 × 60084 پیکسل منطقی
ویدیوی همسان ۱۶:۹ + نوار ثابت640 × 36084 پیکسل منطقی
ویدیوی درون محتوا ۱۶:۹640 × 360ندارد
کاروسل ۱۶:۹ با نوار ثابت640 × 36084 پیکسل منطقی
نظرسنجی در کادر ثابت320 × 30084 پیکسل منطقی
کارت صوتی ثابت320 × 96ندارد
تمام‌صفحه با حاشیه امن360 × 64084 پیکسل منطقی
تمام‌صفحه با حاشیه امن360 × 64084 پیکسل منطقی
تمام‌صفحه با حاشیه امن360 × 64084 پیکسل منطقی
تمام‌صفحه با حاشیه امن360 × 64084 پیکسل منطقی
تمام‌صفحه با حاشیه امن360 × 64084 پیکسل منطقی

این‌ها پروفایل محصول دیدنکس‌اند؛ گواهی استاندارد یا یک اندازه پیکسلی جهانی برای همه فرمت‌ها نیستند. حداقل وضوح در فرم کمپین کنترل می‌شود. برای فعال‌شدن renderer جدید در اپ نصب‌شده، یک بار SDK را به‌روزرسانی کنید.

فونت و ظاهر مشترک

ظاهر کارت در هر دو روش مستقیم و پراکسی از پاسخ همان تبلیغ خوانده می‌شود. مدیر در تنظیمات ← ظاهر تبلیغ و SDK، رنگ، زمینه، فونت، گردی کارت، جای نشان و پخش خودکار ویدیوی معمولی را تعیین می‌کند. ابتدا یک‌بار SDK و اپ را به‌روزرسانی کنید؛ سپس تغییرات پشتیبانی‌شده در درخواست بعدی تبلیغ اعمال می‌شوند. فونت Noto Sans Arabic فارسی و لوگو از سرور خود دیدنکس کش می‌شوند؛ خطای این دارایی‌های اختیاری باعث noFill یا خطای تبلیغ نمی‌شود. Unity برای UGUI یک فونت کوچک فارسی همراه و شکل‌دهی حروف در مرز نمایش دارد. سرور کد اجرایی جدید به اپ نمی‌فرستد.

ویدیوی معمولی هنگام دیده‌شدن خودکار و بی‌صداست؛ صوت و جایزه با انتخاب کاربر شروع می‌شوند. دامنه دیدنکس را در font-src سیاست CSP وب مجاز کنید.

۲. Manifest و مجوزهای لازم

قطعه زیر را با فایل موجود ادغام کنید. INTERNET باید در Manifest اصلی نسخه Release هم باشد. تبلیغ پایه به مجوز مکان، اعلان، حافظه یا شناسه تبلیغاتی نیاز ندارد.

<!-- Merge into your existing manifest. No cleartext exception is required. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <application>
  <activity android:name="com.example.didnex.DidnexActivity" android:exported="false" />
 </application>
</manifest>

در iOS فایل PrivacyInfo.xcprivacy بسته را به منابع Target اضافه کنید؛ HTTPS به غیرفعال‌کردن ATS نیاز ندارد. UIBackgroundModes فقط برای پوش پس‌زمینه اختیاری است. در Unity دسترسی اینترنت Player Settings را روی Require قرار دهید.

بازکردن جایگاه و راهنمای قدم‌به‌قدم اتصال — در پنل، نمونه با شناسه و بستهٔ رسانهٔ شما ساخته می‌شود؛ تست تا دریافت گزارش همان جلسه ادامه دارد.

۳. مثال کامل هر فرمت

هر شناسه جایگاه فقط یک فرمت دارد؛ فرمت باید با نوع رسانه و سیاست‌های پنل سازگار باشد. مثال کامل همان فرمت را انتخاب کنید. تمام‌صفحه فقط در نقطه طبیعی تجربه کاربر نمایش داده شود. ویدیوی معمولی خودکار و بی‌صداست؛ صوت و جایزه با اقدام کاربر شروع می‌شوند.

بنر · درون صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("banner" to "UNT_BANNER")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("banner" to "UNT_BANNER")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
بنر تطبیقی · درون صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("adaptive_banner" to "UNT_ADAPTIVE_BANNER")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("adaptive_banner" to "UNT_ADAPTIVE_BANNER")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
همسان · درون صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("native" to "UNT_NATIVE")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("native" to "UNT_NATIVE")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
ویدیوی همسان · درون صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("native_video" to "UNT_NATIVE_VIDEO")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("native_video" to "UNT_NATIVE_VIDEO")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
ویدیوی درون محتوا · درون صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("video" to "UNT_VIDEO")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("video" to "UNT_VIDEO")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
بینابینی · تمام‌صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("interstitial" to "UNT_INTERSTITIAL")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("interstitial" to "UNT_INTERSTITIAL")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
ویدیوی جایزه‌دار · جایزه‌دار
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("rewarded" to "UNT_REWARDED")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("rewarded" to "UNT_REWARDED")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
بینابینی جایزه‌دار · جایزه‌دار
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("rewarded_interstitial" to "UNT_REWARDED_INTERSTITIAL")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("rewarded_interstitial" to "UNT_REWARDED_INTERSTITIAL")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
آغاز اپ · تمام‌صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("app_open" to "UNT_APP_OPEN")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("app_open" to "UNT_APP_OPEN")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
بازی تعاملی · تمام‌صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("playable" to "UNT_PLAYABLE")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("playable" to "UNT_PLAYABLE")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
صوتی · درون صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("audio" to "UNT_AUDIO")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("audio" to "UNT_AUDIO")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
کاروسلی · درون صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("carousel" to "UNT_CAROUSEL")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("carousel" to "UNT_CAROUSEL")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
نظرسنجی · درون صفحه
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("poll" to "UNT_POLL")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}
روش سروری اختیاری همین فرمت

فقط برای اپ دارای سرور: نشانی پراکسی و تابع نشست فعلی اپ را تکمیل کنید. تابع خالی نمونه، نشست واقعی ایجاد نمی‌کند. کلید خصوصی روی سرور می‌ماند.

package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val diagnosticToken = "".ifBlank { null }
 private val proxy = "https://YOUR-BACKEND.example/ads"
 // Return the current app session, never a server key. Empty means unconfigured.
 private fun appSessionToken(): String = ""
 private val origin = "https://didnex.com"
 private val units = linkedMapOf("poll" to "UNT_POLL")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewarded(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitial(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.load(proxy,appSessionToken(),unit,diagnosticToken=diagnosticToken)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}

۴. مثال کامل با مدیریت خطا

این مثال عیناً از فایل sdk/android/examples/DidnexActivity.kt داخل بسته ساخته می‌شود. نام package نمونه، شناسه‌های UNT_ و ظرف نمایش را با اپ خود هماهنگ کنید. برای بنر و تمام‌صفحه از نمونه جدا استفاده کنید.

نمایش مثال کامل Android · Kotlin
package com.example.didnex
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.*
import com.didnex.ads.DidnexAdView

/** Replace each UNT_ value with an approved unit of that exact format. */
class DidnexActivity : Activity() {
 private val origin = "https://didnex.com"
 private val units = linkedMapOf(
  "banner" to "UNT_BANNER", "adaptive_banner" to "UNT_ADAPTIVE_BANNER",
  "native" to "UNT_NATIVE", "native_video" to "UNT_NATIVE_VIDEO", "video" to "UNT_VIDEO",
  "interstitial" to "UNT_INTERSTITIAL", "rewarded" to "UNT_REWARDED",
  "rewarded_interstitial" to "UNT_REWARDED_INTERSTITIAL", "app_open" to "UNT_APP_OPEN",
  "playable" to "UNT_PLAYABLE", "audio" to "UNT_AUDIO", "carousel" to "UNT_CAROUSEL", "poll" to "UNT_POLL")
 private lateinit var slot: LinearLayout
 private lateinit var status: TextView
 private var busy=false
 private var inline: DidnexAdView? = null
 private var fullscreen: DidnexAdView? = null
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  val root=LinearLayout(this).apply { orientation=LinearLayout.VERTICAL }
  setContentView(root)
  status=TextView(this);root.addView(status)
  val select=Spinner(this)
  select.adapter=ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item,units.keys.toList())
  root.addView(select)
  root.addView(Button(this).apply { text="نمایش تبلیغ";setOnClickListener { showFormat(select.selectedItem.toString()) } })
  slot=LinearLayout(this);root.addView(slot,LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT))
 }
 private fun showFormat(format:String) {
  if(busy)return
  val unit=units[format]?:return
  busy=true
  val full=format in setOf("interstitial","app_open","playable","rewarded","rewarded_interstitial")
  val ad=DidnexAdView(this)
  ad.listener=object:DidnexAdView.Listener {
   override fun onLoaded(requestId:String) { if(!full)busy=false;status.text="تبلیغ آماده شد" }
   override fun onDismiss() {busy=false}
   override fun onNoFill(reason:String) { busy=false; status.text="فعلاً تبلیغی موجود نیست" }
   override fun onError(message:String) { busy=false; status.text="تبلیغ در دسترس نیست؛ استفاده از اپ ادامه دارد" }
  }
  if(full){fullscreen?.destroy();fullscreen=ad
   if(format.startsWith("rewarded")) ad.showRewardedDirect(origin,unit) { _ ->
    status.text="جایزه در کیف نصب دیدنکس ثبت شد" // Never credit locally again.
   } else ad.showInterstitialDirect(origin,unit)
  }else{inline?.destroy();slot.removeAllViews();inline=ad;slot.addView(ad);ad.loadDirect(origin,unit)}
 }
 override fun onResume(){super.onResume();inline?.setActive(true);fullscreen?.setActive(true)}
 override fun onPause(){inline?.setActive(false);fullscreen?.setActive(false);super.onPause()}
 override fun onDestroy(){inline?.destroy();fullscreen?.destroy();super.onDestroy()}
}

۵. نبود تبلیغ، قطعی شبکه و چرخه عمر

آغاز اپ را منتظر تبلیغ نگه ندارید. noFill وضعیت عادی است؛ فضای تبلیغ را مخفی کنید و اپ ادامه یابد. درخواست پشت سر هم و retry بی‌وقفه انجام ندهید. هنگام حذف صفحه، handle یا view را مطابق مثال ببندید. در تب پنهان یا پوشش سفارشی، active را false کنید. نمایش خودکار روی هر resume مناسب نیست.

۶. جایزه، کیف و پوش

جایزه فقط پس از انتخاب کاربر، تماشای کامل و رسید verified و applied سرور معتبر است. callback یعنی جایزه پیش‌تر در کیف نصب دیدنکس ثبت شده؛ دوباره به موجودی اضافه نکنید. برای مصرف، externalId را پیش از ارسال ذخیره و در retry ثابت نگه دارید. کیف نصب، حساب قابل بازیابی چنددستگاهی نیست.

Inbox بدون Firebase و در اپ فعال کار می‌کند. پوش پس‌زمینه به رضایت کاربر، مجوز سیستم‌عامل و اتصال FCM/APNs/Web Push نیاز دارد؛ فعال‌کردن تبلیغ به این تنظیم‌ها وابسته نیست. همه ۱۳ فرمت اتصال مستقیم دارند؛ React Native و Godot فعلاً مستقیم هستند و شش SDK اصلی پراکسی اختیاری هم دارند.

۷. آزمون و رفع خطا

diagnosticToken پنل، با فایل واقعی متناسب با فرمت (تصویر، ویدیو، صوت یا بازی) تست بدون هزینه و جایزه می‌دهد؛ تأیید تحویل مالی نیست. برای تبلیغ واقعی، کمپین سازگار با بودجه و رسانه فعال لازم است. در خطای package، پسوند flavor خروجی را با رسانه تطبیق دهید؛ در وب Origin دقیق و HTTPS را بررسی کنید. خطای سرویس را با موفقیت مالی یا جایزه محلی جایگزین نکنید.

آزمون‌های قرارداد سرور، وب و بسته‌بندی در مخزن اجرا می‌شوند. وضعیت کامپایل منطبق با هش منبع در SDK Lab و releases.json ثبت می‌شود؛ اجرای دستگاه فقط با رسید مستقل device_playback قابل تأیید است.

پیش از انتشار اپ، ساخت Release، قطع شبکه، DNS نامعتبر، پاسخ خراب، خروج صفحه وسط درخواست، پس‌زمینه و تکرار claim را روی دستگاه هدف بررسی کنید. مسیر ساخت تکرارپذیر و تست‌های هر SDK همراه سورس هستند.

قابلیت‌های SDK جدید و عیب‌یاب داخل اپ

نسخه نمایشی این انتشار ۱ است؛ شماره فنی و هش هر بسته در مرکز SDK درج شده است. هر ۱۱ فرمت در اتصال مستقیم و سرور اختیاری پشتیبانی می‌شوند؛ playable با helper بینابینی نمایش داده می‌شود و نیازمند SDK جدید است. در «لابراتوار تبلیغ»، بازی را بسازید و کمپین/جایگاه با فرمت playable انتخاب کنید. قالب‌های همان بازی در Flutter/Unity بومی رسم می‌شوند؛ وب و Kotlin/Swift/B4A از محیط HTML5 محدود استفاده می‌کنند.

برای عیب‌یاب، از پنل ناشر توکن تست جایگاه بگیرید و همان درخواست تست را اجرا کنید. در Flutter حالت debug، Android اپ debuggable، Swift ساخت DEBUG و Unity ساخت Development نیز مجازند. گزارش فقط محلی و محدود به ۸۰ رخداد، زمان، خطا، نوع رسانه و کیفیت است؛ کلید، JWT، URL امضاشده و شناسه مخاطب ثبت نمی‌شود. خروجی کپی را خودتان برای پشتیبانی می‌فرستید.

adView.showInspector(this); // Activity

خروجی‌های ویدیوی تطبیقی به‌طور خودکار از mediaSources انتخاب می‌شوند. حالت کم‌مصرف/شبکه موبایل کیفیت پایین، Wi-Fi یا شبکه سریع کیفیت بالاتر و شبکه نامشخص کیفیت میانی می‌گیرد. اجازه ACCESS_NETWORK_STATE در Android برای تشخیص شبکه لازم است؛ در نبود دسترسی، انتخاب محافظه‌کارانه انجام می‌شود. رویداد بارگذاری، نمایش قابل مشاهده، پیشرفت ویدیو و تأیید جایزه همچنان از مسیر امضاشده می‌گذرند؛ عیب‌یاب درآمد ایجاد نمی‌کند.

ابزارهای ساخت موبایل و دستگاه واقعی در محیط انتشار این سورس در دسترس نبودند. آزمون قرارداد سرور، رمزنگاری، تولید رسانه و پنل انجام شده؛ پیش از انتشار اپ، ساخت SDK در Flutter/Xcode/Android Studio/Unity/B4A و آزمون دستگاه را انجام دهید. بسته‌ها روی pub.dev یا فروشگاه‌ها منتشر نشده‌اند.