#java #android #реклама #in_app #встроенная_реклама
Не могу разобраться, как реализовать в приложении платное отключение рекламы с помощью in-app библиотеки AnjLab? Внизу приведу пример кода: 1) Встраивание рекламы. Здесь все работает, так что если кому нужно можете пользоваться. Подключение библиотеки build.gradle compile 'com.google.android.gms:play-services-ads:9.4.0' В файле AndroidManifest.xmlВ текстовый ресурс String.xml вставляю id рекламного баннера adMobe ca-app-pub-8911529113562577/1565264629 Вставляю баннер в файл app_bar_main.xmlФайл для отображение рекламного баннера Ads.java public class Ads { // создаем метод для создания баннера public static void showBanner(final Activity activity) { // создаем баннер, находим его по id final AdView banner = (AdView) activity.findViewById(R.id.banner); // строит и загружает баннер // импорт android.gms.ads AdRequest adRequest = new AdRequest.Builder().build(); banner.loadAd(adRequest); // слушатель загрузки баннера banner.setAdListener(new AdListener() { @Override public void onAdLoaded() { super.onAdLoaded(); setupContentViewPadding(activity, banner.getHeight()); } }); } // метод подвигает нижний край экрана, на высоте размера баннера public static void setupContentViewPadding(Activity activity, int padding) { View view = activity.findViewById(R.id.coordinator); view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), padding); } } И наконец код для показа рекламного баннера, вставляю в MainActivity.java // внедряем баннер Ads.showBanner(this); Все реклама отображается, но как теперь реализовать платное отключение? Нашел пример на этом сайте. Ссылка. 2) Отключение рекламы. Я сделал таким образом, в левом меню создал ссылку на отключение рекламы, на файл SettingsFrag.java Код: public class SettingsFrag extends Fragment implements BillingProcessor.IBillingHandler { private boolean adsStatus; // храним текущий статус отображения рекламы private boolean initialize; // храним готовность к покупкам private BillingProcessor bp; // переменная нашего процессора private PreferencesManager prefManager; // класс, который работает с SharedPreferences. Я для себя решил вынести всю логику отдельно private Resources resources; // для работы с ресурсами. Раз получаем и постоянно обращаемся private ToggleButton tbAdsState; // кнопка Context mContext; @Override public void onAttach(Context context) { super.onAttach(context); this.mContext = context; // инициализируем `BillingProcessor`. В документации на `GitHub` сказано, что для защиты от липовых покупок через приложения типа // `freedom` необходимо в конструктор `BillingProcessor`'а передать еще и свой `MERCHANT_ID`. Где его взять - внизу текущего ответа опишу шаги bp = new BillingProcessor(context, InAppBillingResources.getRsaKey(), InAppBillingResources.getMerchantId(), this); prefManager = new PreferencesManager(context); // класс, который работает с `SharedPreferences` adsStatus = prefManager.getAdsStatus(); // получаем из `SharedPreferences` сохраненное состояние рекламы (ВКЛ / ВЫКЛ) resources = context.getResources(); // получаем "доступ" к ресурсам } public static SettingsFrag newInstance() { Bundle args = new Bundle(); SettingsFrag fragment = new SettingsFrag(); fragment.setArguments(args); return fragment; } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { // создаем `View` экрана настроек View settView = inflater.inflate(R.layout.frag_sett_screen, container, false); // инициализация других полей tbAdsState = (ToggleButton) settView.findViewById(R.id.tbAdsState); // инициализация других полей // вешаем слушателя нажатий по кнопке `ToggleButton` tbAdsState.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // `adsStatus` : getAdsStatus из класса `PreferencesManager` // true - enabled (ВКЛ) | false - disabled (ВЫКЛ) if (adsStatus && initialize) { bp.purchase(getActivity(), InAppBillingResources.getSKU_Disable_Ads()); } if (!adsStatus) { tbAdsState.setChecked(false); Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.txt_ads_is_already_disabled), Toast.LENGTH_LONG).show(); } } }); return settView; } @Override public void onResume() { super.onResume(); tbAdsState.setChecked(prefManager.getAdsStatus()); } // диалог, который скажет пользователю, что после покупки необходимо перезагрузиться private void restartDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(resources.getString(R.string.msg_notification_Title)); builder.setCancelable(false); builder.setPositiveButton("Ок", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { restartApp(); dialog.cancel(); } } ); AlertDialog resetDialog = builder.create(); resetDialog.show(); } // перезагружаем приложение private void restartApp() { Intent rIntent = mContext.getPackageManager().getLaunchIntentForPackage(mContext.getPackageName()); if (rIntent != null) { rIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); mContext.startActivity(rIntent); } } // ... другие методы класса // [START billing part of class] @Override public void onProductPurchased(@NonNull String productId, TransactionDetails details) { // Called when requested PRODUCT ID was successfully purchased // Вызывается, когда запрашиваемый PRODUCT ID был успешно куплен if (bp.isPurchased(productId)) { prefManager.setAdsStatus(false); // 1. записываем в `SharedPreferences` состояние рекламы (ВЫКЛ / false) tbAdsState.setChecked(false); // 2. устанавливаем `TogglButton` в соответствующее состояние restartDialog(); // 3. перезагружаем приложение } else { tbAdsState.setChecked(true); // иначе, если не прошла покупка, оставляем состояние (ВКЛ / true) } } @Override public void onPurchaseHistoryRestored() { //Вызывается, когда история покупки была восстановлена, // и список всех принадлежащих идентификаторы продуктов был загружен из Google Play // так Вы сможете НУЖНУЮ покупку проверить for (String sku : bp.listOwnedProducts()) { //MyAppLogs.show("Owned Managed Product: " + sku); boolean wasBouhtg = sku.equals(InAppBillingResources.getSKU_Disable_Ads()); if (wasBouhtg) { // true - куплено // пишем в `SharedPreferences`, что отключили рекламу } else { // false - не куплено // пишем в `SharedPreferences`, что нужно показывать рекламу } } } @Override public void onBillingError(int errorCode, Throwable error) { // Вызывается, когда появляется ошибка. См. константы класса // для получения более подробной информации } @Override public void onBillingInitialized() { // Вызывается, когда bp был инициализирован и он готов приобрести initialize = true; } // [END billing part of class] } Файл PreferencesManager.java public class PreferencesManager { private static SharedPreferences mSPref; private SharedPreferences.Editor mSPEditor; private static final String APP_PREF = "app_pref"; // имя файла настроек Вашего приложения private static final String APP_ADS_STATUS = "adsStatus"; // статус рекламы public PreferencesManager(Context context) { mSPref = context.getSharedPreferences(APP_PREF, Context.MODE_PRIVATE); } public void setAdsStatus(boolean adsStatus) { // true - enabled | false - disabled mSPEditor = mSPref.edit(); mSPEditor.putBoolean(APP_ADS_STATUS, adsStatus); mSPEditor.apply(); } public boolean getAdsStatus() { return mSPref.getBoolean(APP_ADS_STATUS, true); } } Файл InAppBillingResources.java public class InAppBillingResources { // Ваш `RSA` ключ из `Google Play Developer Console` private static final String RSA_KEY = "MAFD........."; private static final String MERCHANT_ID = "18........."; // Ваш `MERCHANT_ID` из `Google Play Developer Console` private static final String SKU_DISABLE_ADS = "android.test.purchased"; // Ваш `product_id`, создается в `Google Play Developer Console` public static String getRsaKey() { return RSA_KEY; } public static String getMerchantId() { return MERCHANT_ID; } public static String getSKU_Disable_Ads() { return SKU_DISABLE_ADS; } } Файл frag_sett_screen.xml с переключателем. ... 3) Как теперь этот код совместить с отображением рекламы Ads.showBanner(this);? Что бы если нажать на переключатель или если приложение было уже куплено то скрыть Ads.showBanner(this); и наоборот если не оплатили, то показывать баннер. Я понимаю может кому-то этот вопрос покажется глупым, но у меня абсолютно уже мозги не работают, не могу никак сообразить.
Ответы
Ответ 1
На сколько я понял, Ваше приложение работает по схеме в одной Activity показываем Fragmentы. Хорошо. Так как у Вас есть метод, который подымает пользовательский контент и показывает под ним рекламу, то мы его и будем пытаться обуздать :-) Что делаем ? В классе MainActivity (или как там у Вас называется главная Activity) @Override protected void onCreate(Bundle savedInstanceState) { // получаем наши `SharedPreferences` PreferencesManager prefManager = new PreferencesManager(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_min); // проверяем нашу запись в файле настроек. Если реклама не отключена, то у нас будет true записано, то есть состояние ВКЛЮЧЕНО // а также проверяем подключение к сети Internet простеньким способом // true - enabled | false - disabled boolean adsState = prefManager.getAdsStatus(); if (adsState && CheckURLConnection.isNetworkAvailable(this)) { Ads.showBanner(this, adsState); } else { Ads.showBanner(this, adsState); } // далее Вы просто инициализируете все свои `View` в `MainActivity` // добавляете что нужно } класс CheckURLConnection public class CheckURLConnection { public static boolean isNetworkAvailable(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null; } } класс Ads public class Ads { public static void showBanner(final Activity activity, boolean adsState) { // вместо LinearLayout у Вас будет ВАШ View, который располагается над AdView. В вопросе фигурирует CoordinatorLayout, вот его и нужно будет здесь инициализировать по аналогии с LinearLayout final LinearLayout adsContainer = (LinearLayout) activity.findViewById(R.id.container); final AdView mAdView = (AdView) activity.findViewById(R.id.banner); if (adsState) { AdRequest adRequest; // DEBUG or RELEASE if (BuildConfig.DEBUG) { adRequest = new AdRequest.Builder() .addTestDevice() .build(); } else { adRequest = new AdRequest.Builder() .build(); } mAdView.loadAd(adRequest); mAdView.setAdListener(new AdListener() { @Override public void onAdLoaded() { super.onAdLoaded(); setupContentViewPadding(activity, mAdView.getHeight()); } }); } else { adsContainer.removeView(mAdView); } } public static void setupContentViewPadding(Activity activity, int padding) { View view = activity.findViewById(R.id.container); // рекомендую добавить 8dp отступа над баннером, чтобы была ЧЕТКАЯ граница, которая отделяет его и пользовательские данные (Google просто рекомендует делать границу, иначе могут быть ложные клики и бан AdMob аккаунта) view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), padding + 8); } } <здесь Hash Вашего смартфона или эмулятора> [тип String] - нужно делать для того, чтобы в режиме отладки приложения (DEBUG) Вы сами себе не испортили всё! То есть не стали показывать сами себе настоящую рекламу, проверять клики по ней. Проверка - это нормально! Но не нормально проверять на реальный баннерах, за что Google/AdMob банит аккаунт AdSense. Когда соберете приложение (выпустите его в Google Play Маркет), то будет выполняться блок else условия if (BuildConfig.DEBUG) В итоге мы получаем: - в MainActivity происходит проверка состояния adsState из наших локальных настроек PreferencesManager, а также проверка доступа в сеть Internet. Если куплено отключение рекламы, то метод getAdsStatus() вернет нам false. И реклама не будет показана. - как производить покупку отключения рекламы я описал здесь (https://ru.stackoverflow.com/a/770241/22239). Там и про ToggleButton есть, и про ее обновление, и диалоги с пользователем. Пишите в комментарии, если будут вопросы. Успехов! ;-) // Увы, но весь код приложения за Вас я написать не могу. Ваш вопрос не глупый! По природе вопросов глупых нет, есть люди, которые полностью в чем-то не разобрались/изучили. // Кстати, Вы мне мой же код в вопросе прислали. Изучите его хорошо. Я постарался все покрыть комментариями, чтобы было понятно каждому, что происходит на той или иной строчке класса
Комментариев нет:
Отправить комментарий