Страницы

Поиск по вопросам

Показаны сообщения с ярлыком реклама. Показать все сообщения
Показаны сообщения с ярлыком реклама. Показать все сообщения

вторник, 31 декабря 2019 г.

Реклама и продвижение проекта [закрыт]

#реклама #продвижение


        
             
                
                    
                        
                            Закрыт. Этот вопрос не по теме. Ответы на него в данный
момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Update the question so it's
on-topic for Stack Overflow на русском.
                        
                        Закрыт 4 года назад.
                                                                                
           
                
        
Допустим Вы собрались сделать хороший проект, который будет пользоваться спросом
и станет (возможно) популярным (например как Хэшкод). 
Допустим Вы взяли и сделали его и он получился у Вас "хорошим" (т.е. без багов (почти),
приятный интерфейс и высокая производительность). 
Допустим Вы нашли ресурсы оплатить хороший хостинг (если это сайт) или сделали пару
качественных копий дисков с Вашим приложением (например игрой)
Если все эти невероятные условия выполняются, то как продвигать свой проект? С помощью
каких средств? (допустим проект ориентирован на IT-специалистов, например как Хэшкод)
Как представить Ваш проект на хорошем уровне? Чтобы посмотрев на презентацию, людям
хотелось попробовать Ваш продукт? Заметил, что существует тенденция делать видеоролики,
демонстрирующие функционал проекта, например redactorjs или временная линия facebook,
видео к которой можно посмотреть на главной странице, если вы не авторизировались на
сайте. И тогда ещё вопрос: может ли это быть наилучшим вариантом? Стоит ли вообще делать
такие видео?
Вот сколько вопросов, но задача одна: как показать своё творение миру, чтобы он от
этой презентации захотел попробовать Ваш продукт?    


Ответы

Ответ 1



Проведу параллель с муз. группой. Вот, мы собрались, хорошие музыканты, сделали программу из N-цати песен, репали в течении неск. месяцев на реп. базе. Вложились и купили хорошие инструменты и кейсы для путешествий с оными. Записали демо, сделали сайт. Раскруткой никто из нас заниматься не умеет, мы не по этой части, мы - «до/соль/до/соль», люди сцены и искусства, типа. Взяли специально обученного энергичного человечка со связями, красными волосами и женского пола. И все завертелось: клубы в Москве, фестиваль в Адлере. Вывод: для раскрутки нужен человек, dedicated, в этом разбирающийся, и не начинающий. Как в том же фильме "Социальная сеть". Договориться можно по-разному: и за % с прибыли, и за фикс. ставку, и за интерес и веру в это супер-начинание.

Ответ 2



У меня в голове вертится только одно слово - "Хабр". Пару хороших статеек, мол, после того, как поюзаете наш проект вы не сможете понять, как жили без него раньше. И стоить это все может 0 руб, а юзеров постоянных получишь.

Ответ 3



Не знаю, силен ли я в этой теме, но все же попробую ответить =) Во-первых, если вы задумали проект для узкого круга лиц: ориентирован на IT-специалистов То уже можно не рассчитывать на супер популярность, так как "узкий круг" говорит сам за себя. Вы можете рассчитывать на аудиторию 10000 - 20000 человек, пока, думаю, не более. В целом, все зависит от вас, конечно же. Но на популярность FaceBook`а можете не рассчитывать =) Во-вторых. Вот вы создали "супер мега крутой ресурс" и начинаете задумываться о серьёзной раскрутке. Тут перед вами стоит выбор: идти легальным путем или же наоборот - "жульничать"( и тратить на раскрутку в разы меньше! ). Второй способ редко бывает малоэффективнее первого, так как даже если взять, к примеру, раскрутку ресурса с помощью ботнета, рассылки спама и т.д. Первый способ очень "дорого стоит". Реклама ныне не стоит того, чего за неё просят...но в обоих способах вы вряд ли выйдете проигравшими - тут все только от вас, опять же, зависит! В-третьих Раскрутка видеоролика на YouTube тоже требует неких затрат, иначе можете рассчитывать не более, чем на 3-4k просмотров. P.S А на мой взгляд, чтобы люди ходили на ваш ресурс и с радостью сообщали о его существовании своим знакомым, нужно просто-напросто создать на ресурсе что-то новое, ввести некое новшество в тематику ресурса! Вы можете создать простой форум, но прикрутить к нему, например, мемы( ну просто пример! ) и люди, заинтересованные вашим творением, будут засиживаться там часами =). Конечно же, если вы сейчас сядете и будете писать "социальную сеть для собак", то лучше даже и не начинать... А вообще вопрос удачный! Удачи!

понедельник, 16 декабря 2019 г.

Как реализовать платное отключение рекламы с помощью in-app

#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 есть, и про ее обновление, и диалоги с пользователем. Пишите в комментарии, если будут вопросы. Успехов! ;-) // Увы, но весь код приложения за Вас я написать не могу. Ваш вопрос не глупый! По природе вопросов глупых нет, есть люди, которые полностью в чем-то не разобрались/изучили. // Кстати, Вы мне мой же код в вопросе прислали. Изучите его хорошо. Я постарался все покрыть комментариями, чтобы было понятно каждому, что происходит на той или иной строчке класса

среда, 27 ноября 2019 г.

Защита своего приложения

#java #android #google_play #защита #реклама


Здравствуйте.Имеется приложение с встроенными покупками, рекламой.С помощью Lucky
Patcher его можно подправить.Например удалить или отключить рекламные активити и пользоваться
приложением.Отключил активити через Lucky Patcher, в своем приложении проверяю на доступность
этой активити

PackageInfo pis = getPackageManager().getPackageInfo (getPackageName(), PackageManager.GET_ACTIVITIES);
pis.activities[3].isEnabled();


Получается активити всегда включена.Может кто знает как это дело проверить, и как
можно защитить свое приложение от подобных программ?
    


Ответы

Ответ 1



Самый лучший способ: перестать страдать фигней и делать качественное приложение. Чтобы при попытке пропатчить его, пользователя останавливала не защита, а его совесть, его уважение к вам, его желание вас отблагодарить. И если он все равно решил вылечить приложение от жадности, то никакой защитой его не вернуть, автор приложения просто сделает хуже себе же. Мой ответ на подобный вопрос: https://stackoverflow.com/questions/47283143/. И если пользователь захочет вылечить приложение от жадности, он это всегда сделает. Если не Фридомом или Лаки Патчером, то АПКТулом и ручной правкой. Самое лучшее, что вы можете сделать - это поставить себя на место человека с ЛакиПатчером и подумать, что можно сделать с приложением дальше, с позиции именно пользователя, который является самым главным человеком в деле разработки приложений.

Ответ 2



не знаю,может бредовая идея.. Но что если проверять при каждом запуске вашего приложения установлен ли Lucky Patcher или нет? если установлен то приложение будет показывать что-то типа "удалите Lucky Patcher и переустановите приложение". Переустановить ибо юзер может скачать отключить рекламу и удалить, либо копай в сторону сертификатов.

Ответ 3



Я защищал свое приложение и от Freedom, и от Lucky Patcher. Сначала проверял установленные пакеты на устройстве пользователя. В итоге перешел на использование Proguard совместо с Android Billing Library, после этого мое приложение не поддавалось на взлом с помощью Lucky Patcher. Тут можешь изучить, как встроить в приложение эту библиотеку. Вот можешь скачать мое приложение и попробовать на нем LuckyPatcher.

вторник, 25 июня 2019 г.

Как отключить рекламу?

Как отключить рекламу в android приложении после клика пользователя, например, на сутки? Стандартный баннер, который вызывается в Activity
AdView adView = (AdView) this.findViewById(R.id.adView); AdRequest adRequest = new AdRequest.Builder().build(); adView.loadAd(adRequest)
Что с ним сделать, чтобы отключить после нажатия?


Ответ

Сохрани в shared preferences или в бд переменную,которая хранит время последнего нажатия ,при включении приложения загружай переменную и сравнивай с текущей датой ,в последующем вызывай adview

суббота, 27 октября 2018 г.

Как реализовать платное отключение рекламы с помощью 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 с переключателем.

tools:layout_editor_absoluteX="87dp" tools:layout_editor_absoluteY="66dp"/>

3) Как теперь этот код совместить с отображением рекламы Ads.showBanner(this);? Что бы если нажать на переключатель или если приложение было уже куплено то скрыть Ads.showBanner(this); и наоборот если не оплатили, то показывать баннер.
Я понимаю может кому-то этот вопрос покажется глупым, но у меня абсолютно уже мозги не работают, не могу никак сообразить.


Ответ

На сколько я понял, Ваше приложение работает по схеме в одной 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 есть, и про ее обновление, и диалоги с пользователем.
Пишите в комментарии, если будут вопросы. Успехов! ;-)
// Увы, но весь код приложения за Вас я написать не могу. Ваш вопрос не глупый! По природе вопросов глупых нет, есть люди, которые полностью в чем-то не разобрались/изучили.
// Кстати, Вы мне мой же код в вопросе прислали. Изучите его хорошо. Я постарался все покрыть комментариями, чтобы было понятно каждому, что происходит на той или иной строчке класса