Лицензирование Google Play для приложения Android в Android Studio - PullRequest
0 голосов
/ 11 июля 2020

Я пытаюсь настроить лицензирование Google Play для приложения в Android studio для приложения, написанного на Kotlin. Моя цель - не допустить, чтобы пользователи обменивались файлами APK, не покупая мое приложение в магазине.

Что я пробовал:

  • Я пробовал следовать через их документация . Это не очень полезно. Он пропускает многие детали, и на самом деле это не учебник. Я не мог его использовать.

  • Я видел этот вопрос, на который есть длинный и подробный ответ, похожий на учебник. Но ответ кажется давно устаревшим. Это вызывает множество предупреждений и завершается исключением: «Намерение должно быть явным».

Вкратце мой вопрос:

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

1 Ответ

1 голос
/ 12 июля 2020

Вот как я заработал в 2020 году:

  1. Открыть Android Studio.
Нажмите Инструменты -> Менеджер SDK

enter image description here


  1. Перейдите на вкладку Инструменты SDK

enter image description here


  1. Убедитесь, что Библиотека лицензирования Google Play установлена. Если он не установлен, щелкните галочку и нажмите Применить .

enter image description here


  1. На этом экране вы можете увидеть Android SDK Расположение . Скопируйте этот путь:

enter image description here


  1. Щелкните Файл -> Создать -> Модуль импорта ... :

enter image description here


  1. Вставьте скопированный путь и щелкните маленький значок папки справа от строки ввода текста:

enter image description here


  1. Щелкните Android \ Sdk \ extras \ google \ market_licensing \ library и нажмите OK :

enter image description here


  1. Нажмите Далее :

enter image description here


  1. Оставьте все отмеченными и нажмите Fini sh:

enter image description here


  1. Теперь у вас должна быть папка library в вашем проекте:

enter image description here


  1. Щелкните правой кнопкой мыши app и щелкните Открыть настройки модуля :

enter image description here


  1. Нажмите Зависимости :

enter image description here


  1. Нажмите нажмите кнопку плюс и выберите 3 Зависимость модуля :

enter image description here


  1. Отметьте library и щелкните OK :

enter image description here


  1. Щелкните OK еще раз и дождитесь его синхронизации c.
Если вы получаете сообщение об ошибке

Версия minSdk не должна указываться в файле манифеста android. Вы можете переместить версию из манифеста в defaultConfig в файле build.gradle.

Go в библиотеку> манифесты> AndroidManifest. xml и удалить строку <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="15" />.

Go до Скрипты Gradle> build.gradle (Модуль: библиотека) :

enter image description here


  1. Измените minSdkVersion на 4 и также измените compileSdkVersion, buildToolsVersion и targetSdkVersion по мере необходимости, затем щелкните Sync Now:

enter image description here


  1. Теперь, когда библиотека готова, нам нужен фактическое осуществление проверки лицензии. Go - MainActivity.kt.
Вам нужно найти свой c ключ Base 64 publi, а также создать соль, как показано в этом ответе. Я процитирую необходимую часть этого ответа, но переведу код на Kotlin:

1.1 Ваш уникальный ключ приложения Base64

Как его получить:

а. Go в консоль разработчика. Ссылка .

б. Если вы еще не создали черновик для своего приложения, сделайте это сейчас.

c. После того, как вы создали черновик, рекомендуется загрузить свой .apk как альфа- или бета-версию. Оставьте его неопубликованным.

d. Щелкните Services & APIs

e. Прокрутите вниз и найдите YOUR LICENSE KEY FOR THIS APPLICATION

f. Скопируйте ключ в свое приложение следующим образом:

private const val BASE64_PUBLIC_KEY = "YOUR LICENSE KEY FOR THIS APPLICATION";

Убедитесь, что нет пробелов.

1.2 Соль

a. Что такое соль?

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

b. Как мне его получить?

Этот - хорошая ссылка для генерации случайной соли. Должно быть ровно 20 случайных целых чисел, поэтому введите 20 для количества случайных строк для генерации, каждая строка должна быть 2 символов (используется в этом примере, это не обязательно быть). Проверьте число c цифр и проверьте, что одинаковые строки разрешены. Они тоже могут быть отрицательными числами. Попробуйте удалить любую избыточность, например, 00 -> 0, для единообразия.

c. Куда мне добавить соль?

При объявлении переменных просто введите этот код, кроме вашего случайная соль.

private val SALT = byteArrayOf(YOUR RANDOM SALT, COMMA SEPARATED, 20 INTEGERS)
Переменные на шаге 21 должны быть добавлены к вашему основному классу деятельности. Теперь вы должны добавить код к своей основной деятельности. Вот как это должно примерно выглядеть (обратите внимание на // TODO комментарии):
import android.os.Bundle
import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.vending.licensing.*
import kotlin.system.exitProcess

class MainActivity : AppCompatActivity()
{
    companion object
    {
        private const val BASE64_PUBLIC_KEY = "YOUR LICENSE KEY FOR THIS APPLICATION" // TODO replace with your own key

        private val SALT = byteArrayOf(YOUR RANDOM SALT, COMMA SEPARATED, 20 INTEGERS) // TODO replace with your own salt
        
    }
    
    private val deviceId: String by lazy {
        Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
    }
    private lateinit var licenseCheckerCallback: LicenseCheckerCallback
    private lateinit var checker: LicenseChecker
    
    private fun doCheck()
    {
        checker.checkAccess(licenseCheckerCallback)
    }

    override fun onDestroy()
    {
        super.onDestroy()
        checker.onDestroy()
    }



    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)

        // Construct the LicenseCheckerCallback. The library calls this when done.
        licenseCheckerCallback = MyLicenseCheckerCallback()

        // Construct the LicenseChecker with a Policy.
        checker = LicenseChecker(
            this,
            ServerManagedPolicy(this, AESObfuscator(SALT, packageName, deviceId)),
            BASE64_PUBLIC_KEY // Your public licensing key.
        )

        doCheck()

        setContentView(R.layout.activity_main) // TODO Replace with your own layout
    }

    private fun displayResult(result: String)
    {
         // TODO you can change this how the info is displayed
        Toast.makeText(this, result, Toast.LENGTH_SHORT).show()
    }

    private inner class MyLicenseCheckerCallback : LicenseCheckerCallback
    {
        override fun allow(reason: Int)
        {
            if (isFinishing)
            {
                // Don't update UI if Activity is finishing.
                return
            }
            // Should allow user access.
        }

        override fun applicationError(errorCode: Int)
        {
             // TODO handle the error your own way. Calling `dontAllow` is common.
            dontAllow(Policy.NOT_LICENSED)
        }

        override fun dontAllow(reason: Int)
        {
            if (isFinishing)
            {
                // Don't update UI if Activity is finishing.
                return
            }
            

            if (reason == Policy.RETRY)
            {
                // If the reason received from the policy is RETRY, it was probably
                // due to a loss of connection with the service, so we should give the
                // user a chance to retry. So show a dialog to retry.

                // TODO handle Policy.RETRY
            }
            else
            {
                // Otherwise, the user isn't licensed to use this app.
                // Your response should always inform the user that the application
                // isn't licensed, but your behavior at that point can vary. You might
                // provide the user a limited access version of your app or you can
                // take them to Google Play to purchase the app.

                // TODO implement goto market
            }
            displayResult("Not Licensed")
            
            // TODO you may not abort if you have some other way to handle the fail case
            abort()
        }
    }

    private fun abort()
    {
        finishAffinity()
        exitProcess(0) 
    }
}
Добавьте эти разрешения в свой файл манифеста:
<uses-permission android:name="android.permission.INTERNET"/>  
<uses-permission android:name="com.android.vending.CHECK_LICENSE"/>
Если вы получаете исключение с сообщением, похожим на:
Service Intent must be explicit: Intent { act=com.android.vending.licensing.ILicensingService }

Примените исправление в это ответ.

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