{"id":18687906,"url":"https://github.com/tenmax/ad-placement-library-sdk-android","last_synced_at":"2025-09-05T13:39:18.494Z","repository":{"id":254213198,"uuid":"844995083","full_name":"tenmax/ad-placement-library-sdk-android","owner":"tenmax","description":null,"archived":false,"fork":false,"pushed_at":"2024-12-19T07:49:46.000Z","size":832,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-11T09:40:18.430Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tenmax.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-20T11:28:40.000Z","updated_at":"2024-11-18T17:18:42.000Z","dependencies_parsed_at":"2024-08-29T04:24:53.733Z","dependency_job_id":"87523a28-a872-4bbd-91f4-5d57e1690a54","html_url":"https://github.com/tenmax/ad-placement-library-sdk-android","commit_stats":null,"previous_names":["tenmax/ad-placement-library-sdk-android"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenmax%2Fad-placement-library-sdk-android","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenmax%2Fad-placement-library-sdk-android/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenmax%2Fad-placement-library-sdk-android/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenmax%2Fad-placement-library-sdk-android/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tenmax","download_url":"https://codeload.github.com/tenmax/ad-placement-library-sdk-android/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239546361,"owners_count":19656962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T10:34:45.746Z","updated_at":"2025-09-05T13:39:18.439Z","avatar_url":"https://github.com/tenmax.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TenMax Mobile SDK for Android\n\nThis repository provides the guidelines and examples to demonstrate how to use TenMax Mobile SDK to show AD on your Android app.\n\n## Prerequisites\n\nBefore using the SDK, please contact TenMax (app_support@tenmax.io) to\n\n- register your app bundle ID\n- obtain your app publisher ID\n\nThese two values would be used to initiate the SDK.\n\n## Get Started\n\nFollow the steps to use the TenMax Mobile SDK:\n\n### Install SDK\n\nYou can download the AAR file from the release and put the AAR file into `\u003cproject-root\u003e/\u003cyour-app\u003e/libs` and let Android Studio import it.\n\nHowever, the SDK needs other libraries (Gson, Retrofit, and Google Play AD identifier) to work, thus, please also add required libraries:\n\n- Gson (`com.google.code.gson:gson:2.11.0`)\n- Retrofit (`com.squareup.retrofit2:retrofit:2.11.0`)\n- Gson Converter (`com.squareup.retrofit2:converter-gson:2.11.0`)\n- Google Play AD Identifier (`com.google.android.gms:play-services-ads-identifier:18.1.0`)\n\nAfter importing those libraries, you should see something like this in your `build.gradle.kts`:\n\n```gradle\ndependencies {\n    implementation(files(\"$projectDir/libs/adkit.aar\"))\n    implementation(libs.gson)\n    implementation(libs.retrofit)\n    implementation(libs.converter.gson)\n    implementation(libs.play.services.ads.identifier)\n}\n```\n\nIn this way, you need to download the new AAR file if the SDK is updated.\n\n### SDK Configuration\n\nOpen your app's manifest file (`AndroidManifest.xml`) and add `tenmax-publisher-id` as the application's metadata. The publisher ID is provided by TenMax. Note that the SDK would get the bundle ID for you, but you must ensure that is the same as the value you registered in the [Prerequisites](#prerequisites) section.\n\n```xml\n\u003cmanifest\u003e\n    \u003capplication\u003e\n        \u003cmeta-data android:name=\"tenmax-publisher-id\" android:value=\"{tenmax-publisher-id}\" /\u003e\n    \u003c/application\u003e\n\u003c/manifest\u003e\n```\n\n### SDK initiation\n\nTenMax Mobile SDK must be initiated before use, thus, in your application class (if you do not have an application class, please create a simple one), then, add the following code to initiate the SDK in `onCreate()` method. Don't worry, the SDK would run the initiation in an independent thread pool so won't increase your application launch time.\n\n```java\npublic class DemoApplication extends Application {\n\n    @Override\n    public void onCreate() {\n        TenMaxMobileSDK.initiate(this, (spaces, error) -\u003e {\n            if (error != null) {\n                Log.d(getClass().toString(), \"something wrong\");\n            }\n        });\n        super.onCreate();\n    }\n}\n```\n\nIf you do not initiate the SDK, every call to show ADs, the SDK will give you an error. The SDK initiation would load the AD information from TenMax's server and try to obtain the Android advertising ID (AAID) for you. Now, you are ready to show AD.\n\n## Show ADs\n\n### Interstitial AD\n\nFirst, let's show an interstitial AD (fullscreen AD) when your first activity started. Assume your application's `MainActivity` has three tabs: `HomeFragment`, `DashboardFragment`, and `NotificationFragment` (a sample project created by Android Studio). In the `HomeFragment`, add the following lines to show an interstitial AD when Home fragment resumed:\n\n```java\npublic class HomeFragment extends Fragment {\n\n    private TenMaxAd fullscreenAd;\n\n    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n        // other view setup code\n        this.fullscreenAd = interstitialAd(\"{interstitial-space-id}\", this.getActivity());\n        return root;\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        this.fullscreenAd.show();\n    }\n\n    @Override\n    public void onDestroyView() {\n        super.onDestroyView();\n        binding = null;\n        cleanAd(this.fullscreenAd);\n    }\n}\n\n```\n\nThe AD presentation is asynchronous, thus, please keep the `TenMaxAd` object returned from the `interstitialAd` method. You can dispose (cancel) the presentation when the user switches to other tabs by calling `cleanAd` method (or calling `ad.dipose()`). The SDK would cancel the presentation (if not presented yet) or remove the presentation and then clean up resources to reduce memory usage.\n\n### Banner AD\n\nYou can show a banner AD on top of the screen or bottom of the screen. Even more, you can show both the top and bottom banners on the same screen. However, the relationship between the banner and your app's UI is up to you. For example, you can let the top banner hover on your app's UI. Thus, you need to add a container in your layout file to determine the relationship, like this.\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003candroidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".ui.notifications.NotificationsFragment\"\u003e\n\n    \u003c!-- other UI elements--\u003e\n\n    \u003cFrameLayout\n        android:id=\"@+id/topBanner1\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\u003e\n    \u003c/FrameLayout\u003e\n\n    \u003c!-- other UI elements--\u003e\n\u003c/androidx.constraintlayout.widget.ConstraintLayout\u003e\n```\n\nBack to your code, call the `bannerAd` method to let SDK create the banner AD in the specified container.\n\n```java\npublic class NotificationsFragment extends Fragment {\n\n    private TenMaxAd topBannerAd;\n    private FragmentNotificationsBinding binding;\n\n    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n        // other view setup code\n        this.topBannerAd = bannerAd(\"{banner-space-id}\", this.getActivity(), this.binding.topBanner1, top);\n        return root;\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        this.topBannerAd.show();\n    }\n\n    @Override\n    public void onDestroyView() {\n        super.onDestroyView();\n        binding = null;\n        cleanAd(this.topBannerAd);\n    }\n}\n```\n\nYes, you decide the container's position in the layout file, but you still need to provide the position information (`TenMaxBannerPosition.top`) when calling `bannerAd`. The SDK would use this information to avoid duplication (see [Duplication Detection](#duplication-detection)).\n\n### Inline AD\n\nTo embed an inline AD into your app, you need to add a container to your layout file. For example, in the `fragment_dashboard.xml`, add a `FrameLayout` as the container and setup its layout. As shown, it uses `wrap_content` as `layout_width` and `layout_height` to show a zero-size container, uses `center_horizontal` as `layout_gravity` to centerize the container, and then sets `paddingBottom` to `10dp` to give some space to other UI elements.\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003candroidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@color/gray_600\"\n    tools:context=\".ui.dashboard.DashboardFragment\"\u003e\n\n    \u003c!-- other UI elements--\u003e\n    \u003cFrameLayout\n        android:id=\"@+id/inlineAd\"\n        android:paddingBottom=\"10dp\"\n        android:layout_width=\"wrap_content\"\n        android:layout_gravity=\"center_horizontal\"\n        android:layout_height=\"wrap_content\" /\u003e\n    \u003c!-- other UI elements--\u003e\n\u003c/androidx.constraintlayout.widget.ConstraintLayout\u003e\n```\n\nIn your code, use the `inlineAd` method to embed the AD into the container. Then, the SDK would resize your container when the AD is loaded and ready to show.\n\n```java\npublic class DashboardFragment extends Fragment {\n\n    private TenMaxAd inlineAd;\n    private FragmentDashboardBinding binding;\n\n    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n        // other view setup code\n        this.inlineAd = inlineAd(\"{inline-space-id}\", this.getActivity(), this.binding.inlineAd);\n        return root;\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        this.inlineAd.show();\n    }\n\n    @Override\n    public void onDestroyView() {\n        super.onDestroyView();\n        binding = null;\n        cleanAd(this.inlineAd);\n    }\n}\n```\n\n[This is an experimental feature, cloud be changed in the later version.]\nYou can let the inline AD to (aspect) full fill a container with fixed size.\nFor example, the `inlineAdContainer` is a 300 x 200 fixed size container. \n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003candroidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@color/gray_600\"\n    tools:context=\".ui.dashboard.DashboardFragment\"\u003e\n\n    \u003c!-- other UI elements--\u003e\n    \u003cFrameLayout\n        android:id=\"@+id/inlineAdContainer\"\n        android:layout_width=\"300dp\"\n        android:layout_height=\"200dp\"\n        android:layout_gravity=\"center_horizontal\"\u003e\n        \u003cFrameLayout\n            android:id=\"@+id/inlineAd\"\n            android:paddingBottom=\"10dp\"\n            android:layout_width=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:layout_height=\"wrap_content\" /\u003e\n    \u003c/FrameLayout\u003e\n    \u003c!-- other UI elements--\u003e\n\u003c/androidx.constraintlayout.widget.ConstraintLayout\u003e\n```\n\nThen, when initiate the inline AD, you can configure it with a lambda to specify which container to fill.\n\n```java\npublic View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n    // other view setup code\n    this.inlineAd = inlineAd(\"{inline-space-id}\", this.getActivity(), this.binding.inlineAd, (options) -\u003e {\n        options.aspectFill(this.binding.inlineAdContainer);\n    });\n    return root;\n}\n```\n\nNote, to use the aspect fill, you need to ensure the container's aspect ratio is the same as the AD.\nIf the aspect ratio does not match, if after scale, the calculated width or height exceeds the container's\nwidth or height, the AD could be cropped. You can know the case happened by listen the event (see the [callbacks and listener](#callback-and-listener) section).\n\n### Floating AD\n\nYou can let an AD keep floating on your app **until the app user close it**.\nTo show the floating app, call `floatingAd` with the fragment.\nThis is recommended for developers who use Android Fragment system.\nhowever, for developers who only use Activity, there is another overloading method to call with the activity to show floating AD.\n\n```java\npublic class DashboardFragment extends Fragment {\n\n    private TenMaxAd floatingAd;\n\n    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n        // other view setup code\n        this.floatingAd = floatingAd(\"{floating-space-id}\", this);\n        return root;\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        this.floatingAd.show();\n    }\n\n    @Override\n    public void onDestroyView() {\n        super.onDestroyView();\n        binding = null;\n        cleanAd(this.floatingAd);\n    }\n}\n\n```\n\nNote, because the AD would be always floating on the page (fragment/activity) until the user close it, calling `dispose` or `cleanAd` would not close the AD.\nDo worry the resource leak, when the AD is closed, SDK would clean the resources for you.\n\n## Advanced topics\n\n### Timing and Naming Convention\n\nAD on different pages would have different prices. To collect needed information, TenMax Mobile SDK would monitor your application and fragment lifecycle. Thus, to avoid disturbing information collection, please follow these conventions:\n\n- Always show ADs when the activity or fragment resumed (`onResume`) to ensure the size layout is already finished\n- Give a unique name to the fragment that plays the role of a page, e.g., `HomeFragment`, `DashboardFragment`, or `NotificationsFragment` in the previous samples.\n\nIf you do not follow the convention and SDK can not collect the correct information, the SDK will refuse to show AD in the unexpected case.\n\n### Callback and Listener\nEach method that shows AD can configure optional listener and callback. For example,\n\n```java\npublic View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n    // other view setup code\n    this.inlineAd = inlineAd(\"{inline-space-id}\", this.getActivity(), this.binding.inlineAd, (options) -\u003e {\n        options.listenSession(listener)\n            .monitorInitiation(callback);\n    });\n    return root;\n}\n```\n\nThe callback would be called immediately when the specified space ID is found or something wrong happened. You can provide a callback to know what happened during the setup.\n\nYou can provide the listener to listen all the events of the entire presentation lifecycle. Here is a simple listener to listen to some events:\n- `adViewableEventSent` - the user saw the AD for 1 second, and SDK would send viewable event to the TenMax server.\n- `adLoadingTimeout` - the AD loading timeout (maybe network is too slow) so the presentation is cancelled.\n- `adNotFound` - can not find an AD for the specified space so the presentation is cancelled.\n- `adViewAspectFillOversizing` - the AD try to scale and full fill the container, but the aspect ratio does not match, so width or height oversized \n\n\n```java\npublic class SimpleAdSessionListener implements TenMaxAdSessionListener {\n\n    private final Context context;\n\n    public SimpleAdSessionListener(Context context) {\n        this.context = context;\n    }\n\n    @Override\n    public void adViewableEventSent(TenMaxAdSession session) {\n        Toast.makeText(this.context, \"viewable event sent\", 1).show();\n    }\n\n    @Override\n    public void adLoadingTimeout(TenMaxAdSession session) {\n        Toast.makeText(this.context, \"AD loading timeout\", 1).show();\n    }\n\n    @Override\n    public void adNotFound(TenMaxAdSession session) {\n        Toast.makeText(this.context, \"received adNoFill event\", 1).show();\n    }\n}\n```\n\n### Duplication Detection\n\nFor most ADs, the presentation must be unique on the page. Thus, TenMax Mobile SDK would track the presentation requests. If SDK found the duplication, it would show a warning message for the app developer to fix the case. Also, TenMax would review your app to ensure you follow TenMax's rules.\n\n#### Duplication Rules by Ad Type\n\nEach ad type has specific duplication rules based on its presentation characteristics:\n\n##### Banner Ads\n- **Rule**: Only one banner ad can be displayed per position (top/bottom) per page\n- **Logic**:\n  - Maintains separate tracking for top and bottom banner positions\n  - Maps page names to space IDs for each position\n  - Prevents multiple banners at the same position on the same page\n  - Allows the same space on different pages or different positions\n\n##### Inline Ads\n- **Rule**: Prevents the same space from appearing multiple times across the app\n- **Logic**:\n  - Tracks space occurrences globally across all pages\n  - Prevents the same space from being shown on different pages\n  - Prevents the same space from being shown multiple times on the same page\n  - Once a space is displayed, it cannot be displayed again until removed\n\n##### Floating Ads\n- **Rule**: Only one floating ad can be active at a time\n- **Logic**:\n  - Prevents multiple floating ads from being displayed simultaneously\n\n##### Fullscreen/Interstitial Ads\n- **Rule**: No duplication restrictions\n- **Logic**:\n  - Fullscreen ads are exempt from duplication detection by design\n  - Can be displayed multiple times without restriction\n\n## Google Privacy Survey for TenMax SDK\n\nAndroid publisher should provide the information that data their apps collect, including the data collected by third-party SDKs. For your convenience, TenMax SDK provides the information on its data collection in the [Data Collection Survey for TenMax SDK](Privacy.md).\n\n## app-ads.txt Support\n\nThe app-ads.txt file is a standardized document listing authorized digital sellers, introduced by the IAB to enhance transparency and combat fraud in the advertising ecosystem. It ensures seller legitimacy, safeguarding against fraudulent activities and domain misrepresentation.\n\nDevelopers are required to host this file at the root of their website. Brand advertisers and demand-side platforms (DSPs) access and analyze this file to validate seller authenticity when purchasing ad inventory programmatically through exchanges, supply-side platforms (SSPs), or ad networks.\n\nCopy the app-ads.txt file into the root of the developer website so that it's findable in the location.\n\n### app-ads.txt\n```text\ngoogle.com, pub-4338256439626145, DIRECT, f08c47fec0942fa0 \ngoogle.com, pub-9467144491537745, DIRECT, f08c47fec0942fa0\ntenmax.io, fadcc2c833, DIRECT\nfout.jp, 1537, DIRECT\nfout.jp, 113, DIRECT\n```\n\n## Issues and Contact\n\nIf you have any issue when using TenMax Mobile SDK, please contact app_support@tenmax.io. We will help you as soon as possible.\n\n\n## User Data Deletion Notice\n\nFor requests to delete the privacy data linked to users, please submit the request via [User Data Deletion Notice Form](https://forms.office.com/r/SnU40q6VmQ).\n\n## License\n\nTenMax\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftenmax%2Fad-placement-library-sdk-android","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftenmax%2Fad-placement-library-sdk-android","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftenmax%2Fad-placement-library-sdk-android/lists"}