Альтернатива платному отключению рекламы в бесплатном приложении Android

Доброго времени суток, Хабрахабр!

Меня зовут Александр, я разработчик под ОС Android. Сегодня хочу с вами поделиться опытом реализации альтернативного платному способу отключения рекламы в приложении — отключение рекламы за просмотр рекламы (AdMob Rewarded Video Ads). Интересно? Тогда добро пожаловать под кат.


Как все было ?


В далеком 2013 году я решил заняться разработкой приложений под Android, начал читать тематические книги, статьи, смотрел видео уроки и т.д. Написал первое недоприложение и приуныл, т.к. хотелось сделать что-то полезное, нужное обществу, а идей не было. В 2014 меня знакомый попросил разработать для него мобильный справочник по синтаксису платформы Arduino (там С язык). С огромным желанием я взялся за этот проект и реализовал первую версию для Android 3.0+. Через время решено было усовершенствовать ее, и так появилась вторая версия (для Android 4.0+). Обе они бесплатные с баннером от AdMob внизу и платным его отключением. Все было хорошо, пока мне не стали писать, что ~150-170 рублей РФ дороговато для отключения рекламы навсегда в их любимом справочнике. На что я ответил «бартерным» решением вопроса — пользователь может отключить баннер внизу на время за просмотр видео рекламы от AdMob.
[вернуться к содержанию]

Реализация, часть 1: Принцип работы (словами)


При запуске приложения пользователю будет показан Dialog, с предложением отключить рекламу, если, конечно, он ранее ее не отключил или отсутствует подключение к сети Интернет. В случае положительного ответа, приложение показывает фрагмент с кнопками, с помощью которых и можно выполнить отключение рекламы в приложении удобным способом.
[вернуться к содержанию]

Реализация, часть 2: Внешний вид


Диалог с предложением отключить рекламу
Диалог с предложением отключить рекламу

Экран отключения рекламы
Экран отключения рекламы

1 видео реклама просмотрена
1 видео реклама просмотрена

5 видео реклам просмотрено
5 видео реклам просмотрено

Реклама отключена на 1 час
Реклама отключена на 1 час

Реклама отключена на 1 день
Реклама отключена на 1 день

[вернуться к содержанию]

Реализация, часть 3: Принцип работы (java код)


Код главной Activity

public class ActivityMain extends AppCompatActivity  {
    private boolean internet;
    private boolean isAdsDisabled;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // get SharedPreferences
        prefManager = new PreferencesManager(this);
        isAdsDisabled = prefManager.isAdsDisabled(); // true - disable | false - enabled
        // ... здесь код создания Вашего UI

        internet = CheckURLConnection.isNetworkAvailable();
        // true - disable | false - enabled
        if (internet && !isAdsDisabled && isTimeUp()) {
            DialogFragment disableAds = new DisableAdsDialog();
            if (!disableAds.isResumed()) {
                disableAds.show(getSupportFragmentManager(), ConstantHolder.DIALOG_DISABLE_ADS);
            }
        }

    private boolean isTimeUp() {
        return System.currentTimeMillis() > prefManager.getEstimatedAdsTime();
    }
}


Код класса CheckURLConnection
public class CheckURLConnection {

    public static boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager)
                MyAppClass.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager != null) {
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            return activeNetworkInfo != null && activeNetworkInfo.isConnected();
        } else {
            return false;
        }
    }
}


Код класса PreferencesManager

public class PreferencesManager {

    private Context mContext;

    private static SharedPreferences mSPref;
    private SharedPreferences.Editor mSPEditor;

    public PreferencesManager(Context context) {
        this.mContext = context;
        mSPref = mContext.getSharedPreferences(ConstantHolder.APP_PREF, Context.MODE_PRIVATE);
    }

    // получаем значение состояния рекламы из SharedPreferences
    public boolean isAdsDisabled() {
        return mSPref.getBoolean(ConstantHolder.APP_PREF_DISABLE_ADS, false);
    }

    // получаем дату в миллисекундах, когда нужно включить рекламу
    public long getEstimatedAdsTime() {
        return mSPref.getLong(ConstantHolder.APP_DISABLE_ADS_PERIOD, 0);
    }
}

Класс ConstantHolder — класс, в котором я храню константы, чтобы не импортировать их отовсюду, а только из одного места брать (аналог класса R)

public class ConstantHolder {

    //Preferences Constants
    public static final String APP_PREF = "app_pref";
    public static final String APP_PREF_DISABLE_ADS = "disableAds";         // Реклама
    public static final String APP_DISABLE_ADS_PERIOD = "disableAdsPeriod"; // Период отключения рекламы
}

И самое интересное — класс-фрагмент отключения рекламы

java код целого класса
public class SettingsAdsFrag extends Fragment
        implements View.OnClickListener {


    private static final String VIEWED_ZERO_VIDEO_ADS = "0";
    private static final int VIEWED_ADS_NUMBER_PER_HOUR = 1;
    private static final int VIEWED_ADS_NUMBER_PER_DAY = 5; //5
    private static final long DISABLE_ADS_PERIOD_1_HOUR     =      60 * 60 * 1000;
    private static final long DISABLE_ADS_PERIOD_24_HOURS   = 24 * 60 * 60 * 1000;


    private Context mContext;
    private PreferencesManager prefManager;
    private RewardedVideoAd mRewardedVideoAd;
    private AdRequest mAdRequest;


    private boolean internet;
    private boolean readyToPurchase;
    private boolean bDisableAds;
    private String ready;
    private String notReady;
    private static int adsViewedCounter = 0;


    private Button btnReadyToViewing;
    private Button btnDisableAdsPerHour;
    private Button btnDisableAdsPerDay;
    private TextView tvViewedAds;
    private TextView tvEstimatedDate;
    private ToggleButton tbDisableAds;

    private BillingProcessor bp;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.mContext = context;
		// инициализируем свой класс менеджер хранения настроек
        prefManager = new PreferencesManager(context);
		// получаем текущее состояние интернет соединения
        internet = CheckURLConnection.isNetworkAvailable();
		// присваиваем "не готово" биллингу
        readyToPurchase = false;
		// сохраняем в глобальные переменные значения "НЕ ГОТОВО" и "СМОТРЕТЬ" из ресурсов. Сделал так, чтобы по несколько раз к ресурсам не обращаться
        ready = context.getString(R.string.txt_cat_ads_ready_for_viewing);
        notReady = context.getString(R.string.txt_cat_ads_not_ready_for_viewing);
    }



    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		// отключаю меню у Toolbar
        setHasOptionsMenu(false);
		// инициализирую биллинг с помощью библиотеки от Anjlab - In-App-Billing-v3
        bp = new BillingProcessor(getActivity(),
                InAppBillingResources.getRsaKey(),     // мой RSA ключ
                InAppBillingResources.getMerchantId(), // мой ID продавца из Google Play Developer Console
                bpHandler // и сам хэндлер
				);
		// получаю состояние рекламы из файла настроек
        bDisableAds = prefManager.isAdsDisabled(); // true - disable | false - enabled
    }



    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        // здесь код вывода заголовков в Toolbar, опустил его, т.к. не по теме статьи


        // [START AdMob Rewarded Video Ads - инициализация]
        mRewardedVideoAd = MobileAds.getRewardedVideoAdInstance(getActivity());
        mRewardedVideoAd.setRewardedVideoAdListener(rewardedVideoAdListener);

	// такую хитрость я применяю везде, чтобы повторно Google меня не забанил на AdMob (еще 1 год писать апелляции я не хочу!)
        if (BuildConfig.DEBUG) {            
			mAdRequest = new AdRequest.Builder()
					.addTestDevice(DeviceHash.getHtcDeviceHash())
					.build();
        } else {
            mAdRequest = new AdRequest.Builder()
                    .build();
        }

	// загружаю видео рекламу
        loadRewardedVideoAd();
        // [END AdMob Rewarded Video Ads]


	// создаем View экрана Настройки - Отключение рекламы
        View settAdsView = inflater.inflate(R.layout.frag_sett_ads_screen, container, false);

        // [START ToggleButton Disable Ads]
        tbDisableAds = (ToggleButton) settAdsView.findViewById(R.id.tb_disable_ads);
        // если биллинг инициалирован  и отключение рекламы  куплено, то сохраняем это в SharedPrefereces и устанавливаем "Отключено" на кнопке-переключателе
	// да-да-да, я еще раз делаю запрос в Google на предмет покупки. А вдруг юзер руками подправил файл настроек ?
        if (readyToPurchase) {
            if (bp.isPurchased(InAppBillingResources.getSKU_DisableAds())) {
                setAdsDisable();
                tbDisableAds.setChecked(false);
            }
        } else {
            // в противном случае читаю то, что записано было
            // true - disable | false - enabled
            tbDisableAds.setChecked(!bDisableAds);
        }
	// устанавливаю слушатель нажатия по кнопке
        tbDisableAds.setOnClickListener(this);
        // [END ToggleButton Disable Ads]


	// далее идет элементарная инициализация полей и установка значений для каждой из них. Ничего сложного
        // [START TextView Rewarded Video Ads Disabling Guide]
        TextView tvRewardedGuide = (TextView) settAdsView.findViewById(R.id.tv_rewarded_video_disabling_guide);

        tvRewardedGuide.setText(String.format(getActivity().getString(R.string.txt_cat_ads_disable_tmp_text),
                VIEWED_ADS_NUMBER_PER_HOUR,
                VIEWED_ADS_NUMBER_PER_DAY));
        // [END TextView Rewarded Video Ads Disabling Guide]

        // [START TextView Viewed Ads]
        tvViewedAds = (TextView) settAdsView.findViewById(R.id.tv_viewed_ads);
        // [END TextView Viewed Ads]


        // [START Button Ready for Viewing]
        btnReadyToViewing = (Button) settAdsView.findViewById(R.id.btn_ready_to_viewing);
        btnReadyToViewing.setText(notReady);
        btnReadyToViewing.setEnabled(false);
        btnReadyToViewing.setOnClickListener(this);
        // [END Button Ready for Viewing]


        // [START Button Disable Ads Per Hour]
        btnDisableAdsPerHour = (Button) settAdsView.findViewById(R.id.btn_disable_ads_per_hour);
        btnDisableAdsPerHour.setEnabled(false);
        btnDisableAdsPerHour.setOnClickListener(this);
        // [END Button Disable Ads Per Hour]


        // [START Button Disable Ads Per Day]
        btnDisableAdsPerDay = (Button) settAdsView.findViewById(R.id.btn_disable_ads_per_day);
        btnDisableAdsPerDay.setEnabled(false);
        btnDisableAdsPerDay.setOnClickListener(this);
        // [END Button Disable Ads Per Day]


        // [START TextView Last Viewing Time]
        tvEstimatedDate = (TextView) settAdsView.findViewById(R.id.tv_estimated_date);
        // [END TextView Last Viewing Time]


	// обновляю значения текстовых полей и текста кнопок
        updateTextView();
        updateButtons();

        return settAdsView;
    }



    @Override
    public void onResume() {
        // Rewarded Video Ad - необходимо для поддержания жизненного цикла видео рекламы
        if (mRewardedVideoAd != null) {
            mRewardedVideoAd.resume(getActivity());
        }
        super.onResume();
        // updateUI - обновляю экран
        updateTextView();
        updateButtons();
    }



    @Override
    public void onPause() {
        // Rewarded Video Ad - необходимо для поддержания жизненного цикла видео рекламы
        if (mRewardedVideoAd != null) {
            mRewardedVideoAd.pause(getActivity());
        }
        super.onPause();
    }


    
    @Override
    public void onDestroy() {
        // Rewarded Video Ad - необходимо для поддержания жизненного цикла видео рекламы
        if (mRewardedVideoAd != null) {
            mRewardedVideoAd.destroy(getActivity());
        }
        super.onDestroy();
    }



    // обработчик нажатий по кнопкам
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tb_disable_ads:
                // disable ads ? setText(..OFF) : setText(..ON)
                // if state ON (disableAds - false)
                // true - ads disabled; false - ads enabled
                if (!bDisableAds && readyToPurchase) {
                    // если реклама не отключена и биллинг готов, выполняем покупку "Отключить рекламу навсегда платно"
                    bp.purchase(getActivity(), InAppBillingResources.getSKU_DisableAds());
                }
                break;
            case R.id.btn_ready_to_viewing:
                // если видео реклама загружена, то запускаем ее просмотр
                if (mRewardedVideoAd.isLoaded()) {
                    mRewardedVideoAd.show();
                }
                break;
            case R.id.btn_disable_ads_per_hour:
                // отключаем рекламу 1 час
                disableAdsPerPeriod(DISABLE_ADS_PERIOD_1_HOUR);

                adsViewedCounter--;

                updateTextView();
                updateButtons();

                break;
            case R.id.btn_disable_ads_per_day:
                // отключаем рекламу 1 день
                disableAdsPerPeriod(DISABLE_ADS_PERIOD_24_HOURS);

                clearAdsCounter();
                updateTextView();
                updateButtons();

                break;
            default:
                break;
        }
        // true - ads disabled;
        // false - ads enabled
        if (bDisableAds) {
            tbDisableAds.setChecked(false);
            showSnackbar();
        }
    }



    // ==========================================================
    // [START        R E W A R D E D        V I D E O        A D]
    private RewardedVideoAdListener rewardedVideoAdListener = new RewardedVideoAdListener() {
        @Override
        public void onRewardedVideoAdLoaded() {		
            // когда видео реклама будет полностью загружена, влючаем кнопку просмотра
            btnReadyToViewing.setText(ready);
            btnReadyToViewing.setEnabled(true);
        }

        @Override
        public void onRewardedVideoAdOpened() {
        }

        @Override
        public void onRewardedVideoStarted() {		
            // устанавливаем НЕ ГОТОВО на кнопку и выключаем ее
            btnReadyToViewing.setText(notReady);
            btnReadyToViewing.setEnabled(false);
        }

        @Override
        public void onRewardedVideoAdClosed() {
	    // загружаем новую видео рекламу
            loadRewardedVideoAd();
        }

        @Override
        public void onRewarded(RewardItem rewardItem) {
	    // если счетчик рекламы меньше количества просмотров для отключения на день, то инкрементируем его
            if (adsViewedCounter < VIEWED_ADS_NUMBER_PER_DAY) {
                adsViewedCounter++;
            }

	    // обновляем поля экрана
            updateTextView();
            updateButtons();
        }

        @Override
        public void onRewardedVideoAdLeftApplication() {
        }

        @Override
        public void onRewardedVideoAdFailedToLoad(int i) {
	    // загружаем новую рекламу
            loadRewardedVideoAd();
        }
    };

    private void loadRewardedVideoAd() {
	 // если есть доступ в сеть Интернет, грузим видео рекламу
        if (internet) {
            mRewardedVideoAd.loadAd(mContext.getString(R.string.admob_rewarded_video_id), mAdRequest);
        }
    }

    // [END        R E W A R D E D        V I D E O        A D]
    // ==========================================================



	// обновляем текстовые поля согласно условий и значения счетчика просмотров
	// показываем дату возобновления рекламы в приложении, если ее отключили временно
    private void updateTextView() {

        // true - disable | false - enabled
        if (bDisableAds) {
            tvViewedAds.setText(String.valueOf(adsViewedCounter));
            tvEstimatedDate.setText("");
        } else {
            // [START        U P D A T E        T E X T V I E W :    tvViewedAds]
            if (adsViewedCounter > 0 && adsViewedCounter <= VIEWED_ADS_NUMBER_PER_DAY) {
                String strViewedAdsCount = adsViewedCounter + " / " + VIEWED_ADS_NUMBER_PER_DAY;
                tvViewedAds.setText(strViewedAdsCount);
            } else {
                tvViewedAds.setText(VIEWED_ZERO_VIDEO_ADS);
            }
            // [END        U P D A T E        T E X T V I E W :    tvViewedAds]


            // [START        U P D A T E        T E X T V I E W :    tvEstimatedDate]
            long estimatedDate = prefManager.getEstimatedAdsTime();
            long currentDate = System.currentTimeMillis();
            if (estimatedDate != 0 && estimatedDate > currentDate) {
                String strEstimatedDate = convertTime(estimatedDate);
                String strEstimatedDateFinal = "<b>" + mContext.getString(R.string.txt_tv_header_estimated_time).toUpperCase() + "</b>"
                        + "<br>"
                        + strEstimatedDate;
                tvEstimatedDate.setText(Html.fromHtml(strEstimatedDateFinal));
            }
            // [END        U P D A T E        T E X T V I E W :    tvEstimatedDate]           
        }
    }



	// обновляем кнопки
    private void updateButtons() {
        // 0
        if (adsViewedCounter == 0) {
            btnDisableAdsPerHour.setEnabled(false);
            btnDisableAdsPerDay.setEnabled(false);
        }
        // 1 - 4
        if (adsViewedCounter > 0 && adsViewedCounter < VIEWED_ADS_NUMBER_PER_DAY) {
            btnDisableAdsPerHour.setEnabled(true);
        }
        // 5
        if (adsViewedCounter == VIEWED_ADS_NUMBER_PER_DAY) {
            btnDisableAdsPerHour.setEnabled(true);
            btnDisableAdsPerDay.setEnabled(true);
        }
    }



	// метод отключения рекламы на период
    private void disableAdsPerPeriod(long disablePeriod) {
	 // текущая дата в миллисекундах
        long currentDate = System.currentTimeMillis();
	 // дата возобновления рекламы в приложении
        long estimatedDate = currentDate + disablePeriod;
	 // сохраняем дату в файл настроек
        prefManager.setEstimatedDate(estimatedDate);

		// отключаем баннер внизу экрана
        AdMobAds.disableBanner(getActivity(), true);
    }



	// обнуляем счетчик
    private void clearAdsCounter() {
        adsViewedCounter = 0;
    }



	// конвертер миллисекунд в дату и время согласно формату
    public String convertTime(long time) {
        Date date = new Date(time);
        Format format = new SimpleDateFormat("dd MMM yyyy @ HH:mm:ss");
        return format.format(date);
    }



    // ==========================================================
    // [START        IN        APP         BILLING]
    BillingProcessor.IBillingHandler bpHandler = new BillingProcessor.IBillingHandler() {
        @Override
        public void onProductPurchased(@NonNull String productId, @Nullable TransactionDetails details) {
            // Called when requested PRODUCT ID was successfully purchased
            // Вызывается, когда запрашиваемый PRODUCT ID был успешно куплен

            if (bp.isPurchased(productId)) {
		 // сохраняем новое состояние рекламы "отключена" и устанавливаем "Выключено" для кнопки-переключателя
                setAdsDisable();
                tbDisableAds.setChecked(false);
                // перезапускаем приложение
                restartDialog();
            } else {
				// иначе устанавливаем "Включено"
                tbDisableAds.setChecked(true);
            }
        }

        @Override
        public void onPurchaseHistoryRestored() {
            //Вызывается, когда история покупки была восстановлена,
            // и список всех принадлежащих идентификаторы продуктов был загружен из Google Play
        }

        @Override
        public void onBillingError(int errorCode, @Nullable Throwable error) {
            // Вызывается, когда появляется ошибка. См. константы класса
            // для получения более подробной информации
        }

        @Override
        public void onBillingInitialized() {
            // Вызывается, когда bp был инициализирован и он готов приобрести
            readyToPurchase = true;
        }
    };
    // [START        IN        APP         BILLING]
    // ==========================================================



	// метод сохранения отключенного состояния рекламы
    private void setAdsDisable() {
        prefManager.setAdsDisabled();
    }



    // диалог перезапуска приложения
    // [START restartDialog]
    private void restartDialog() {
        AlertDialog.Builder builder;

        View alertLayout = View.inflate(mContext, R.layout.dialog_restart, null);
        if (prefManager.getAppTheme() == 0) {
            builder = new AlertDialog.Builder(getActivity(), R.style.AppThemeDialogStyleLight);
        } else {
            builder = new AlertDialog.Builder(getActivity(), R.style.AppThemeDialogStyleDark);
        }

        builder.setTitle(getActivity().getString(R.string.msg_notification_Title));
        builder.setView(alertLayout);

        builder.setPositiveButton(getActivity().getString(R.string.ans_restart),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        restartApp();
                    }
                });
        builder.show();
    }
    // [END restartDialog]



    // метод перезапуска приложения
    // [START restartApp]
    private void restartApp() {
        Intent i = getActivity().getPackageManager().getLaunchIntentForPackage(getActivity().getPackageName());
        if (i != null) {
            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            getActivity().startActivity(i);
        }
    }
    // [END restartApp]



    // Snackbar с уведомлением, что рекламу уже отключена. Если пользователь снова кликнет по кнопке отключения рекламы
    private void showSnackbar() {
        Snackbar.make(getActivity().getWindow().getDecorView().getRootView(),
                getActivity().getResources().getString(R.string.advertising_is_already_disabled),
                Snackbar.LENGTH_SHORT).show();
    }
}


Класс работы с баннером AdMob. Ничего сложного, публикую для ознакомления. Хотя его же и на StackOverFlow ни раз выкладывал

public class AdMobAds {

    public static void disableBanner(final Activity activity, boolean disableAds) {

        final View adsContainer = activity.findViewById(R.id.container);
        final AdView adView = (AdView) activity.findViewById(R.id.adView);

        if (disableAds) {
            adView.setVisibility(View.GONE);
            adsContainer.setPadding(0, 0, 0, 0);
        } else {
            AdRequest adRequest;
            if (BuildConfig.DEBUG) {                
                    adRequest = new AdRequest.Builder()
                            .addTestDevice(DeviceHash.getHtcDeviceHash())
                            .build();
            } else {
                adRequest = new AdRequest.Builder()
                        .build();
            }
            adView.loadAd(adRequest);

            adView.setAdListener(new AdListener() {
                @Override
                public void onAdFailedToLoad(int errorCode) {
                    MyAppLogs.show("[bottom-banner] >> onAdFailedToLoad: реклама не загружена\terrorCode = " + errorCode + ".");
                    super.onAdFailedToLoad(errorCode);
                }

                @Override
                public void onAdLoaded() {
                    super.onAdLoaded();
                    MyAppLogs.show("[bottom-banner] >> onAdLoaded");
                    if (adView.getVisibility() == View.GONE) {
                        adView.setVisibility(View.VISIBLE);
                    }
                    View adsContainer = activity.findViewById(R.id.container);
                    adsContainer.setPadding(adsContainer.getPaddingLeft(),
                            adsContainer.getPaddingTop(),
                            adsContainer.getPaddingRight(),
                            adView.getHeight() + 8);
                }
            });
        }
    }
}

[вернуться к содержанию]

Заключение


Вот и все. Суть статьи — поделиться с обществом своей идеей и ее реализацией. А также получить приглашение на Хабрахабр, если кому-то понравится то, чем я поделился. Буду рад и благодарен за ваше мнение в вопросах доработки кода и/или идеи. Если понадобится дополнительное пояснение — пишите, я в кратчайшие сроки внесу правки в статью или дам ответ в комментариях.

Ссылку на приложение по понятным причинам не публикую в открытом доступе. Этика есть этика! Кому нужно — дам в лс.

Статистика AdMob пока еще сырая, с момента внедрения данной альтернативы прошло всего ~2 недели. Не все пользователи обновились. Но точно есть те, кто пользуется таким способом отключения баннера внизу.

UPDATE: Ссылка на статью с результатами ИТОГ 3-х месяцев: Альтернатива платному отключению рекламы в бесплатном приложении Android

Благодарю всех, кто дочитал статью до конца!
Поделиться публикацией
Похожие публикации
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 97
  • 0
    Правильно ли я понимаю, что это сделано чтоб можно смотреть рекламу с «наземного» инета, что б потом не тратить трафик с мобильного?

    PS:
    Хорошая идея. Было б вообще хорошо, если развить далее: «посмотреть» на пару дней или неделю вперед. Но думаю, тут уже можно столкнуться с ограничением со стороны рекламодателя.
    • 0
      Правильно ли я понимаю, что это сделано чтоб можно смотреть рекламу с «наземного» инета, что б потом не тратить трафик с мобильного?
      Я просто пошел людям навстречу. Есть те, кто не хочет платить за отключение рекламы, но она им мешает. Выход всегда есть! Поэтому я дал возможность избавиться на время от баннера внизу путем просмотра видео рекламы. Один раз посмотрел — нет баннера 1 час. Посмотрел больше — иной временной диапазон без рекламы внизу. И людям приятно, и мне лишняя копеечка за просмотры.

      В играх разработчики дают своим пользователям золото, монеты или дополнительные жизни, если те посмотрят 1-2 ролика. Я же даю то, что нужно моим пользователям. «И волки сыты, и овцы целы!»

      PS:
      Хорошая идея. Было б вообще хорошо, если развить далее: «посмотреть» на пару дней или неделю вперед. Но думаю, тут уже можно столкнуться с ограничением со стороны рекламодателя.
      Я хотел так сделать, но столкнулся с проблемой — рекламы для текущего региона, где пользователь находится, сейчас может не быть в нужном количестве. Поэтому решено было не развивать механизм хранения уже выполненных просмотров, а запустить в тестовом режиме то, что я описал в статье.

      Благодарю Вас за конструктивный комментарий!
    • 0
      Спасибо за статью, интересна экономика этого решения. Стоит ли оно того?
      • 0
        Большую роль в данном решении играет возможность отключать рекламу бесплатно. Как я говорил в статье, что пользователи не хотят платить и жалуются в отзывах к приложению. Сопровождают свои комментарии заниженными оценками. То есть само приложение их устраивает на 1`000`000%, но реклама (маленький баннер внизу) + еще и разработчик жлоб, хочет нажиться, просит денег за отключение. Поэтому 3 или 2 звезды вообще. Сначала я писал аргументы и доводы в ответ, старался как-то дать понять, что реклама внизу и платное ее отключение — нормально! Но потом понял, что это бессмысленно. Так я и пришел к тому, что дал пользователю возможность самому принимать решение: платно или бесплатно он будет избавляться от баннера внизу.

        Если говорить о цифрах, то имеем следующее (период 01.02 — 24.02.2018, сегодня):
        bottom banner:
        * 49`047 показов
        * 217 кликов
        * 0.44% CTR
        * 0.05$ за клик
        * сумма: 10.68$

        rewarded video ads:
        * 3`807 показов
        * 7 кликов
        * 0.18 CTR
        * 0.27$ за клики
        * сумма: 1.92$

        Видно, что сам баннер внизу ГОРАЗДО прибыльный, оно то и понятно. Он расположен всегда внизу экрана, а до видео рекламы нужно еще и добраться по пунктам меню или через положительный ответ на вопрос в DialogFragment, который я показываю пользователю при старте приложения. Код, кстати, приложил к статье.

        Еще немного цифр для Вас:
        активных установок: 18`428 из общего числа установок — 62`004
        средняя оценка: 4.66 по результатам 1`452 оцениваний

        Спасибо за статью, ...
        Пожалуйста. Рад тому, что Вам она понравилась.
        • 0
          Не про Ваше приложение, а про рекламу.
          То есть само приложение их устраивает на 1`000`000%, но реклама (маленький баннер внизу) ...

          Есть еще один неприятный момент. Этот маленький баннер внизу экрана содает жуткие тормоза. Что виновато? Может криво блок рекламы вставлен, может слабый телефон. Но во многих приложениях, при подключении к интернету (без интернета не показывает :)), наблюдаются фризы при смене баннера.
          • 0
            Никогда не замечал фризов рекламы.
            • 0
              Может, синхронный запрос какой-нибудь, или проверка в цикле. У нас же 5g уже везде, новые баннеры грузятся мгновенно, можно не париться с оптимизацией. А могли и ядра в фоновых процессах завязнуть. Появился интернет, все проснулись — и в сеть.
              • 0
                Появился интернет, все проснулись — и в сеть.
                Да, бывает и так. Весь смартфон подвисает в момент тотальной синхронизации данных на смартфоне и различных сервисов.
                • 0
                  Нет, микрофриз именно во время смены баннера на новый. Интернет 3g, да и то достаточно поганенький. (По ощущениям — ждет загрузки в потоке приложения.)
              • 0
                О чем вы? У нас и LTE до сих пор не везде, а в иных местах и ешечка тормозит
                • 0
                  LTE ??? В Украине только стал нормального работать 3G. И то не везде еще есть покрытие, есть соты с EDGE.
                  • 0
                    О сарказме. 5g на компах у разработчиков и тестеров, видимо, поэтому и не парятся, а в моём комментарии опущен тег <сарказм></сарказм>. Надо было поставить…
                    • 0
                      Упс. Не заметил этот тег. xD
                      К сожалению, разработчик никак не может повлиять на скорость загрузки баннеров adMob. Он может только обрабатывать методы обратного вызова жизненного цикла баннера/рекламы, большего Google не позволяет делать.
                      • 0
                        Вот если Google мог сделать неблокирующую загрузку баннера, но не сделал, значит, их разработчики живут в розовых мечтах, полностью покрытых скоростной 5g сетью )
                        Не являюсь гуру Android-разработки, так что моё предположение о синхронном коде полностью спекулятивно.
                        • 0
                          Нет, KodyWiremane. Я проверял загрузку баннера на EDGE и 3G — все ок. Все ок при условии, что в этот момент смартфон не синхронизируется с облаком Google/Mail.ru/Yandex/и др. Когда происходит процесс синхронизации, смартфон начинает лагать. А там летит все.

                          И еще хочу добавить, что компаниям гигантам все равно на наши возможности, т.к. есть усредненное движение технологий вперед. К примеру, минимальная версия Android, которую должны поддерживать Android разработчики — 19/20 (Android 4.4 (KitKat) / Android 5.0 (Lollipop))

                          То есть все, что ДО Android KitKet Google рекомендует не поддерживать, и новинки в Google Play нужно выпускать с minSdkVersion=19.
                          Кто поддерживает устройства с Android 4.0, как я например, делают это уже на свое усмотрение, лишаются части новых плюшек, которые Google каждый год добавляет. Сложность поддержки старых устройств с каждым годом только усложняется.
                          Приложения для старых версий Android можно оснастить библиотеками совместимости (support-library-v4/7/13), но в них не всегда есть то, что нужно. И, если и есть, то не всегда работает так же хорошо, как и в на оригинальном Android 6.0, к примеру. Отсюда вылазят костыли и велосипеды, баги и лаги.

                          Надеюсь, я Вас не сильно загрузил своим расширенным ответом на простой вопрос. :-)
                          • 0
                            Ну, это понятно, что жернова прогресса неумолимы,) Тот же JS: гораздо приятнее пользовать стандартный API, нежели подключать в код вязанки костылей для исторических браузеров. В то же время, косяки разработчиков остаются с нами. Пусть у гигантов всё в порядке, но с блокировкой промахиваются другие. Вот в одной знакомой игре, пока грузится очередное супер-заманчивое предложение дня (при переходе на экран локации с другой локации или из другого режима), не работает UI. Т. е. картинка рендерится, анимируется, но нажатия игнорирует.
              • +1
                Когда реклама сразу на экране, сверху или снизу, она мешает не только эстетически, но и вполне себе фукционально — например случайные тапы могут увести по ссылке рекламной. Если это во время игры приводит к потере контроля. А дальше зависит от типа игры, в интерактивных играх это всегда поражение, и вполне ожидаемо после 2-3 раз на эмоциях пользователь проставляет 2-3 звезды.

                Собсно, это я к тому, что когда реклама на экране, больше переходов может быть не от желания её просмотреть, а от мисскликовмисстапов.
                • 0
                  Поэтому Google/AdMob установили привила, что нельзя ставить контролы около баннеров. И нужно явно отделять баннер от UI. Я, к примеру, добавил отступ в 8dp (в коде есть).
                  • 0
                    А если это «всевдошутер» где тапаешь в любом месте экрана, и если ты ещё не наловчился, запросто можно тыкнуть в рекламу? тоже самое верно для экранов 4-4.5, как у меня, потому что лопата на 5.5-6 уже не очень комфортна в виде мобилки.
                    Для тех целей где нужен экран больше у меня 7" планшетка имеется :)
                    Мисстапы случаются у многих, особенно поначалу (сужу исключительно по своему опыту и пробному приложению).
                    • 0
                      Я с Вами согласен на 1оо% на счет мисстапов! Главное, чтобы они случались не по вине неправильной расстановки контролов на экране.

                      Хочу еще добавить к Вашему комментарию, что нормальный разработчик не будет вставлять баннер в шутере или иной динамичной игре. Для них существуют межстраничные (Interstitial Ads) и видео (Rewarded Video Ads) рекламы, которые показываются пользователю после проигрыша или в режиме паузы. Показывать баннер в динамичной игре — хардкор какой-то. Мистапов будет ооочень много и «мигания» объявлений будут отвлекать внимание игрока.

                      А мое решение в таких играх просто избавит от межстраничных или видео реклам после проигрыша. Хотя не каждый захочет его применять, т.к. выгодней в играх за просмотр видео рекламы давать монеты/жизни/золото/ключи/и другие плюшки.

                      // я так это вижу, другие разработчики могут считать по-другому))
              • 0
                Стоит ли оно того?
                Мое решение хорошо подойдет для приложений с бОльшей аудиторией. В моем же случае, если говорить только о доп. доходе с рекламы, не стоит оно того. Пока не стоит. Посмотрим, что будет через 1-2 месяца, когда пользователи обновятся и привыкнут. Когда разрабатывал такой вид отключения, моя цель была — убавить негатив в комментариях и сохранить рейтинг приложения в Google Play.
              • 0

                Спасибо за статью и за идею!)

                • +1
                  Пожалуйста. Пользуйтесь. Если реализуете/придумаете какие-то форки, то обязательно дайте сообществу знать! :-) Интересно.
                • 0
                  Интересный метод. Отпишись пожалуйста после месяцев трех-четырех о результатах
                  • 0
                    Да, конечно. Мне самому хочется узнать и расшарить эти данные.
                • 0
                  Статическая переменная для проверки наличия интернета… Что-то здесь не так.
                  • 0
                    Что именно не так?
                    • 0

                      Статическая переменная internet будет инициализирована только один раз при создании класса активити. Какой в ней смысл?

                      • 0
                        Во время создания ActivityMain получаем информацию о наличии доступа в сеть Интернет. Если есть, то делаем по коду, иначе пропускаем все.
                        В классе ActivityMain есть еще несколько мест, где нужно считать значение из internet. Поэтому переменная является глобальной.

                        anegin, или Вы хотили сказать, что модификатор static лишний?
                        • 0
                          К тому моменту, когда нужно будет прочитать значение из переменной internet, ее значение может быть уже не актуальным, т.е. сети уже может не быть.
                          В нужных местах достаточно вызывать CheckURLConnection.isNetworkAvailable(), чтобы узнавать о наличии сети по факту в нужный момент.
                          А так получается, что наличие сети проверяется один раз при создании класса активити и зачем-то сохраняется в переменной, к тому же еще private static.

                          Static-поля и методы нужны для доступа к ним без создания экземпляра класса. Например, в static-методах этого класса или inner-static-классах — это если поле private. Или, например, как константы для доступа из других классов — это если поле не private.
                          • 0
                            Я так сделал, чтобы по 10 раз не вызывать метод проверку доступа к сети Интернет.

                            Ок. Понял Вас. Постараюсь в ближайшее время подправить код.
                            • 0
                              Вызов этого метода «быстрый», т.к. проверяется только факт наличия любого сетевого соединения, а не реальная возможность куда-то подключиться (выход в Интернет). Поэтому его можно и нужно вызывать каждый раз непосредственно перед коннектом куда-либо. К слову, кроме activeNetworkInfo != null нужно еще проверять activeNetworkInfo.isConnected()
                              • 0
                                Благодарю за совет.
                                Обновил код в статье и приложении.
                  • 0
                    На словах выглядит интересно, однако у меня есть одно подозрение.
                    Если пользователь посмотрит рекламу 5 раз подряд, и он не кликнет по ссылке, то его ценность сильно уменьшится и этому пользователю будут показываться дешевая реклама. Т.е. Вы получите меньше денег за рекламу, чем если бы вы растянули эти 5 показов на больший временной отрезок.
                    • 0
                      Дельное замечание! Можете дать ссылку на подтверждение Ваших слов?

                      В моем решении есть два зайца, и обоих хочется поймать! Первый, самый ценный/важный, — заяц-хранитель рейтинга приложения. Он выполняет функции успокаивания пользователей в вопросах отключения рекламы. Платить не хочешь — смотри рекламу.

                      Второй заяц — не менее важная персона, а именно: доход с рекламы и ее платном отключении. И у этого зайца появляются какие-то прихрамывания — Ваше замечание касательно удешевления рекламы.
                      Но стоит помнить, что платят то за клики по баннеру, а не просмотры.
                      Поэтому я Вас прошу предоставить подтверждение/факты к Вашему дельному замечанию.
                      Если Ваше утверждение верно на 1оо%, то придется переписывать код.
                      • 0
                        Но стоит помнить, что платят то за клики по баннеру, а не просмотры.

                        Я говорю про видео рекламу, и тап по нему после просмотра, а не про баннер, который висит все время в меню.

                        Можете дать ссылку на подтверждение Ваших слов?

                        К сожалению официального подтверждения у меня нет. Я обычный программист, и это утверждение слышал внутри нашей компании. Игнорировать думаю не стоит.

                        Даже если я прав, возможно не стоит переписывать код. Здесь говорится, что дешевая реклама в некоторых случаях выгоднее. Стоит изучить аналитику в admob.
                        • 0
                          Хорошая мини статья! Благодарю Вас за то, что поделились!
                    • 0

                      Когда уже запилят адблок для мобилы...

                      • 0
                        Вы же понимаете, что для кого-то реклама — источник дохода?! И блокируя ее показ, Вы лишаете человека/компанию заработка. Это равносильно пиратству. Кто-то потратил часть своей жизни на создание, к примеру, цифрового продукта, и хочет, чтобы за его труд потребители заплатили. А пираты берут и крадут у него эту возможность.

                        Чтобы проникнуться этой мыслью, нужно сначала самому что-то создать для общества.

                        Каюсь! Я тоже раньше не уважал чужой труд! Сейчас же все наоборот!
                        Кстати, чтобы урегулировать «баталии» между правообладателями и пирами, придумали Open Source проекты. Они бесплатны в распространении, понятны в принципах работы. Но для их существования нужны денежные вливания, то есть донат/пожертвования. Как Вы относитесь к Open Source и донату?
                        • 0
                          Игроки которые не покупают дополнительный контент в free to play, видимо тоже «равносильны пиратам»?
                          А может не нужно везде пихать это избитое слово?
                          Украсть «возможность» — не возможно.

                          Есть и третья возможность, которой часто пользуются, те кто вышел из пиратсва (а это между делом, большая часть СНГ) — бесплатно для частного пользования, платно для коммерческого.

                          Чем больше будет такого софта, тем спокойнее и легче будет жить в цифровую эпоху.

                          • 0
                            Игроки которые не покупают дополнительный контент в free to play, видимо тоже «равносильны пиратам»?
                            Нет, они не пираты.

                            А может не нужно везде пихать это избитое слово?
                            Украсть «возможность» — не возможно.
                            Никогда ранее не слышал такого.

                            Есть и третья возможность, которой часто пользуются, те кто вышел из пиратсва (а это между делом, большая часть СНГ) — бесплатно для частного пользования, платно для коммерческого.
                            И как узнать о типе использования? Ведь можно на дому заниматься коммерцией.
                            • 0
                              И как узнать о типе использования?
                              Никак. Если соблюдать рамки дозволенного.
                              Допустим мы делаем 2 типа лицензии, коммерческая и обычная. Программа учёта доходов/расходов. Как узнать, для себя купил или на работе работу работает? Только если слать себе суммы и кол-во (при этом всё равно остается шанс ошибиться, например если приложение скачает благотворительный фонд/ОО/НКО), но я не считаю этот вариант приемлемым. Потому — никак.

                              И как узнать о типе использования?
                              Хороший вопрос. Именно от него я пришел к написанному ранее.
                              Теперь посмотрим иначе, у нас есть два типа пользователей, которые купят и не купят. С первыми всё понятно, а вот вторые всё равно обойдут защиту или уйдут.
                              И вот тут теряется самое важное(на мой взгляд, как разработчика) — статистика и фидбек. И не знаешь, сколько установили, сколько из них пользуются, что они думают и что хотят добавить или убрать.
                              • 0
                                По поводу обратной связи.
                                Чаще же есть сайты, электронный адрес разработчика, форумы и т.д., куда можно написать свое обращение. Бывали же случаи, когда люди просили полную лицензированную версию для работы со ссылкой на то, что денег вообще нет, а пользоваться продуктом сильно хотят. Разработчики в ответ давали ключи.
                                Но это редкие случаи.
                                • 0
                                  Не будет пользователь писать вам на сайте, форуме или имеил, по моему опыту. Тот фидбек который Вы описываете — это в самом лучшем случае 10% от всех пользователей.

                                  Когда кто-то разрабатывает интерфейс стараются учитывать, что пользователи не любят сложности и делают всё доступным в 1-2 клика/тапа. Но при этом в серьёз уверены, что пользователь будет делать больше телодвижений, что б написать что-то в ответ, o rly?
                                  • 0
                                    Так в Google Play и так все делается в 1-2 клика. В подвале страницы приложения есть связь с разработчиком, а в приложении есть кнопка ведущая на страницу в Google Play.

                                    Да, согласен. UI должен быть простым до безумия!
                              • 0
                                оракле никак не узнает о том, что его нелицензионно используют (на сколько виртуалок его ставят, а?), но ничего, одни из самых жирных богатеев в мире
                                • 0
                                  Так вроде в 2015/2016/или 2017 году Google и Oracle порешали свои дела в суде на счет JVM в Android?
                            • 0

                              Все программы должны писаться ради получения морального удовлетворения. Все, что пишется для 'монетизации', обычно одноразовый трэш. Когда программы писали для удовольствия, программы были хороши. Когда туда пришли кодеры ради монетизации, маркет превратился в помойку. Фонарик? С баннером.


                              ПС хотите зарабатывать на программировании? Работайте на работодателя.

                              • 0
                                Спасибо за ценные указания, о том, как следует зарабатывать. Надеюсь, что человек с похожим образом мыслей не придет ко власти в моей стране.
                                Насчет маркета. Проблема не в куче мусорных приложений, а в том, что эту кучу толком не проверяют. Нет стандартов, нет ограничений особых, свобода — она такая. Хэйтить разработчиков бессмысленно и бесполезно.
                                • 0
                                  Полностью с Вами согласен!
                                  • 0
                                    о кстати, еще мысль возникла
                                    Немного капитанства
                                    Проблема не в наличии рекламы в приложениях. А в самой рекламе. В основном рекламируют неинтересные тебе вещи, либо сама реклама лишена привлекательности. То есть, первыми виноваты маркетологи, делающие неэффективную рекламу. Что, в свою очередь, привело к распространению агрессивного способа ее показа. А уже это побуждает ставить плагины и патчить приложения.
                                    • 0
                                      Да. И снова разработчик ничего не может с этим сделать. Увы.

                                      Меня самого сильно напрягает реклама новой видео соц. сети (гори в аду создатель этого ужаса для малолетних!)
                                      • 0
                                        Это вы про kwai?
                                        Не пользовался, у меня только вк из соцсетей, да и тот за музыкой. Был. Если вы понимаете о чем я)
                                        Реклама и впрямь не очень, что не мешает этому покемону набирать популярность.
                              • 0
                                Никакой работодатель не будет платить разработчику за самостоятельный софт, с которого работодатель не будет иметь профита. Иначе с каких денег ему вообще платить? Не беру в расчет тот случай, когда пишется приложение (клиент) для существующей системы, с которой работодатель уже имеет профит.
                              • 0
                                Ну я создавал для общества. И что?
                                Например, посадил дерево. Теперь со всех деньги требовать, кто на него смотрит, кто о нем думает или кто дышит кислородом?
                              • +1

                                Есть AdAway, практически полное уничтожение рекламы в андроиде. Причём никакой нагрузки на систему: домены, с которых качается реклама, блокируются на уровне DNS ( прописываются в /etc/hosts )
                                Списки доменов обновляются по сети, аналогично адблоку.
                                Недостаток: нужен рут

                                • 0
                                  И как тогда монетизировать свой труд, если отовсюду народ старается что-то украсть, заблокировать и т.д.?

                                  Как бы Вы, leshakk, монетизировали свое приложение, зная, что можно заблокировать рекламу, взломать покупку полной версии и т.д.?
                                  • +1
                                    Уж точно не рекламой.
                                    Как пользователь скажу, что если мне ОЧЕНЬ понравилась прога,
                                    я лучше заплачу за неё.

                                    Вот пара примеров:

                                    1.Утилита для диагностики вариаторов Nissan по OBDII.
                                    Написана энтузиастом с автомобильного форума, писалась по сути «для себя».
                                    Первые версии были бесплатны. Потом автор сдела программу платной,
                                    но предыдущие версии оставил в свободном доступе на сайте.
                                    По большому счёту, функционал бесплатной версии вполне достаточен,
                                    дальнейшие отличаются только большим удобством, но я купил,
                                    чтобы поблагодарить автора, учитывая, что стоимость программы в 5-10 раз ниже суммы,
                                    которую просят за «компьютерную диагностику» в сервисе.

                                    2. Программа учёта расхода топлива. Тоже написана энтузиастом.
                                    Есть как платная, так и бесплатная версии.
                                    В платной добавлена возможность синхронизации данных с облаком.
                                    Стоимость символическая. Купил.

                                    И что характерно, даже в бесплатных версиях этих программ не было никакой рекламы.
                                    Чтож, их авторы уважают своих пользователей, потому и сами достойны уважения.
                                    • 0
                                      Уж точно не рекламой.

                                      Кому как, ведь все люди разные. Кто-то предпочтет посмотреть рекламу и потратить свое время, чем потратит свои деньги.
                                      • 0
                                        Я, кстати, в приложении 2 месяца назад реализовал донат для тех, кто выражает желание задонатить разработчику, но не знает куда.
                                        За 2 месяца работы — 1 или 2 доната

                                        В RU-нете люди не привыкли платить. Да, есть и те, кто готов отблагодарить за труд, как Вы с ПО для Nissan'a. Есть те, кто с пониманием относится к баннеру внизу. Есть даже те, кто покупает отключение рекламы и за баги в приложении не ставит «1 звезду», а просто обновляет/пишет в комментарий или на контактный электронный адрес, что поломалось у него что-то.
                                        Низкий поклон от меня таким ЛЮДЯМ!
                                        • 0
                                          кстати о донате — а что, разве гугла не запрещает такие вещи? на сколько я помню там политика только такая — ни копейки мимо кассы, т.е. гугла. Так, что за донат можно и огрести
                                          • 0
                                            Все у меня ок! Донат в приложении реализован через In-App-Billing Google.

                                            кстати о донате — а что, разве гугла не запрещает такие вещи? на сколько я помню там политика только такая — ни копейки мимо кассы, т.е. гугла. Так, что за донат можно и огрести

                                            Да, я тоже такое когда-то читал. И тоже удивляюсь приложениям по бронированию услуг в парикмахерских, к примеру, через иные платежки.
                                            Может уже можно свои платежки добавлять? Не читали обновленные правила Google Play?
                                            • +1
                                              ну я стараюсь следить за изменениями, но бабло мимо кассы — одна из самых страшных крамол в гуглах/епплах
                                              • 0
                                                Если изменений не было, я их все равно понимаю, т.к. Google/Apple имеет возможность вернуть деньги пользователю, а левые платежки под вопросом.

                                                А репутация в первую очередь пострадает у магазина Google/Apple.
                                                • 0
                                                  ну это спорный вопрос…
                                                  • 0
                                                    да, согласен. Наперед мы не сможем просчитать))
                                      • 0
                                        Мы с Вами говорим о разного рода приложениях. Ваше для автомобиля распространяется через форум, и в такое приложение глупо интегрировать рекламу!
                                        Такое же заключение можно сделать и для ПО фирм (о нем идет обсуждение чуть выше в данной ветке комментариев).

                                        Другое дело — ПО для смартфонов, которое чаще распространяется через специализированные магазины типа Google Play. В таких магазинах полно людей из неплатежеспособной категории: школьники, студенты, люди с низким доходом. Эти люди 70-90% никак благодарят, и пишут в комментариях/отзывах еще и претензии касательно неполноты бесплатной версии приложения. Оценку, естественно, занижают.
                                        Чего не скажешь о владельцах авто, оборудованных бортовыми компьютерами. Аудитория платежеспособная.
                                        • 0
                                          Примеры, которые я привёл, это именно приложения под андроид и распространяются через Google Play. Но они написаны энтузиастами для энтузиастов, а не просто желающими срубить по-быстрому «100500 денег».

                                          У меня вообще создалось впечатление, что история появления большинства
                                          «программ» в маркете примерно такова:

                                          1. Автор узнал, что на «программах для телефона» можно «поднять» кучу денег.
                                          2. Чтение книжки из серии «программирование под android для чайников»
                                          3. Написание очередного «фонарика» с напихиванием в него рекламы по самое небалуйся.
                                          4. Ожидание $$$

                                          • 0
                                            Есть еще более частая категория — портфолио.
                                            Пишешь приложение ради демонстрации своих умений, прицепом добавляешь монетизацию. Чтоб была просто.
                                            • 0
                                              Есть еще более частая категория — портфолио.
                                              Пишешь приложение ради демонстрации своих умений, прицепом добавляешь монетизацию. Чтоб была просто.
                                              Вижу лукавство.
                                              Чисто для портфолио, рекламы бы не было, чтоб оценка была выше.
                                              Плюс написанное ранее, если собрать воедино, говорит о желании получать с приложения.
                                              • 0
                                                Собственно, к чему спор? В первом же предложении статьи всё открытым текстом написано.
                                                • 0
                                                  Спора и нет)))

                                                  Кратко опишу всю ситуацию.

                                                  1. Мое приложение было создано еще в 2014 для знакомого.
                                                  2. Первый раз я опубликовал его в Google Play без баннера
                                                  3. Когда приложение стало иметь спрос, и народ начал просить расширить его, я добавил баннер внизу
                                                  4. После попросили дать возможность его отключать платно, т.к. отвлекает
                                                  5. Сделал платное отключение, расширил информацию в приложении (на это понадобилось дополнительное время, а не те считанные часы, что были ранее)
                                                  6. Платное отключение не всех устраивает -> так появилось решение, которое я описал в статье.

                                                  И да, решением делюсь со всем на правах «Робин Гуда». Считаю, что это позволит уменьшить гнев пользователей в Google Play на рекламу в приложениях.
                                                  Да, я хочу заработать на своем приложении. И считаю, что это нормально. Контент открыт полностью, никто ничем не ограничен.
                                                  Вопрос с рекламой прост: не нравится — отключай платным или бесплатным способом.

                                                  Надеюсь, я смог ответить на поставленные вопросы :-) И уменьшить батхерт в комментариях к приложению на счет рекламы.
                                                  • +1
                                                    Я только одного не могу понять: нафига справочник по адурине на телефоне, если всё равно разработка за компом?
                                                    • 0
                                                      Хороший вопрос! Очень хороший! Я наконец уже могу ставить "+1", поэтому Вы его получаете!

                                                      Из отзывов к приложениям я понял, что люди выполняют дебаг своих схем в разных местах: подвалы без Wi-Fi и 3G, крыши зданий, где ситуация бывает аналогичной, работы в полях. Так же мой справочник приносит пользу тем, кто пишет код в IDE на компьютере, и не хочет переключаться на броузер, чтобы подсмотреть описание нужной функции или библиотеки.

                                                      Если Вы работаете с платформой Arduino, то найдите мои справочники в Google Play, установите их (его, если говорить о 2-й версии). Посмотрите на их/его функционал и материал. После Вы сможете сделать вывод о необходимости иметь его всегда под рукой.
                                                      • 0
                                                        Буду весьма признателен, если в личку пришлёте ссылку на неё.
                                                        Что касается подвалов и прочих полей, то в комплекте Arduino IDE (бррр) есть вполне себе годная копия справки.
                                                        • 0
                                                          Честно скажу, что сильно рад спросу на мое приложение!
                                                          Я вообще всегда получаю массу от того, что мои разработки хотя бы работают, а тут еще и люди оценили, дали положительную обратную связь. Супер вообще!

                                                          Да, сейчас Вам сброшу ссылку.
                                                          • 0
                                                            Интерес академический, а не практический, не обольщайтесь особо.
                                                        • 0
                                                          Внезапно возник вопрос: если люди работают с дебагом в подвалах и прочих помещениях без Wi-Fi и 3/4G, то как они смогут на месте посмотреть рекламу-то?
                                                          • 0
                                                            А им и не нужно ничего смотреть.
                                                            Нет сети — нет рекламы.
                                                            • 0
                                                              Или запрещаем указанной программе доступ в интернет и забываем про неудобства.
                                                              • 0
                                                                Жестко, но можно.

                                                                Интересно стало, а настанет ли время, когда люди будут с пониманием относиться к такому способу монетизации (рекламе в приложениях)?

                                                                • 0
                                                                  Мне тоже интересен этот вопрос.
                                                                  Но пока я вижу обилие навязчивой (<= ключевое слово) рекламы везде.
                                                                  Пожалуй, одна из самых мерзких вещей, которое изобрело человечество.
                                                                  • 0
                                                                    1. Без рекламы мы бы с Вами не смогли узнать о новинках.
                                                                    2. навязчивой? Это как? Она к Вам в дверь стучит? (шутка)
                                                                    Если внизу приложения мигает баннер, по-моему, это не навязчивость, а наоборот — уважение к пользователю приложения!
                                                                    Навязчивая реклама = СПАМ в абонентские ящики в наших с Вами подъездах. Это высший пилотаж навязчивости. Или реклама на ТВ каждые 5-10 мин.

                                                                    А баннер внизу — норм. Я так считаю.
                                                                    • 0
                                                                      В дверь не то чтобы стучит, но весьма назойливо канючит: «посмотри меня… ну посмотри меня… ой, а хочешь, я тебя час трогать не буду, но ПОСМОТРИ МЕНЯ ПЯТЬ РАЗ!!! ну пожалуйста!!!»
                                      • 0

                                        Но рут это возможность своими руками сломать систему или серьезно снизить ее безопасность

                                        • 0
                                          В кривых и незнающих руках? Of course!
                                          А еще — это возможность сделать стоковую систему чище, производительнее, функциональнее. Вас наверное обрадует тот факт, что производители смартфонов нынче стараются максимально оградить пользователей от возможности получить суперюзера на свое устройство.
                                          • 0

                                            Вот вы своим пенсионерам поставите рут?

                                            • 0
                                              О чем вы вообще? Поточнее, пожалуйста, я не разумею в ваш сленг.
                                              • 0

                                                Есть у вас родители или родственники, которым опасно давать рутованный телефон?

                                                • 0
                                                  Ах, вот оно что, а я надеялся, что это все-таки что-то иное означает.
                                                  При чем здесь это? Объясните, в чем связь возможности получения рута и теми, кому этот рут вапще не нужен?
                                                  Просто берешь — и не даешь его в руки. Пусть пользуются другими, неразлоченными, раз такой вопрос. О возможности использования своего девайса другими людьми нужно думать заранее. И это вовсе не означает, того, что рут — плохо. Или я вообще не понимаю ваших претензий, что вы хотите донести? Скажите конкретно.
                                                  • 0
                                                    Полагаю, автор комментария предупреждает, что не стоит давать ружьё человеку, не умеющему обращаться с оружием, чтобы тот по неосторожности не отстрелил себе ногу.
                                      • 0
                                        Уже.
                                        Но либо работает только по WiFi + надо уставливать НЕ из Play Store (откуда их выкинули). Либо нужен рут.
                                        Либо нужно решение с псевдо-VPN (AdGuard вроде бы так работает, Opensource аналоги вроде есть).
                                        Либо нужен аппарат от Samsung и не любой (а рута/VPN — не нужно) — AdHell (как устроено — читаем habrahabr.ru/post/314116 ).
                                        Работает не со всеми приложениями (с Youtube единственный известный мне способ 100% заблокировать рекламу — root + Xposed + специально для Youtube написанный модуль Xposed (по сути динамический патч программы)).
                                        • 0
                                          Как насчет патченных версий? На 4pda их есть
                                          • 0
                                            Не универсальное решение (под конкретное приложение надо) + с обновлениями заморочки.

                                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                      Самое читаемое