Android Studio 中 Android 应用程序的 Google Play 许可 [英] Google Play Licencing for an Android app in Android Studio

查看:40
本文介绍了Android Studio 中 Android 应用程序的 Google Play 许可的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为使用 Kotlin 编写的应用程序在 Android Studio 中为应用程序设置 Google Play 许可.我的目标是避免用户在未通过商店购买我的应用的情况下共享 APK 文件.

我尝试过的:

  • 我试过按照他们的


    1. 切换到 SDK 工具 标签


    1. 确保安装了 Google Play 许可库.如果未安装,请单击复选标记并单击应用.


    1. 在该屏幕中,您可以看到 Android SDK 位置.复制该路径:


    1. 点击文件 ->新 ->导入模块...:


    1. 粘贴您复制的路径,然后单击文本输入行右侧的小文件夹图标:


    1. 点击Android\Sdk\extras\google\market_licensing\library,然后点击确定:


    1. 点击下一步:


    1. 勾选所有内容并点击完成:


    1. 现在您的项目中应该有一个 library 文件夹:


    1. 右键点击app,然后点击打开模块设置:


    1. 点击依赖项:


    1. 点击加号按钮并选择3 Module Dependency:


    1. 检查library并点击OK:


    1. 再次点击确定并等待它同步.


    1. 如果出现错误

    <块引用>

    不应在 android 清单文件中声明 minSdk 版本.您可以将版本从清单移至 build.gradle 文件中的 defaultConfig.

    转到图书馆>清单 >AndroidManifest.xml 并删除 .


    1. 转到 Gradle 脚本 >build.gradle(模块:库):


    1. minSdkVersion 更改为 4,并根据需要更改 compileSdkVersionbuildToolsVersiontargetSdkVersion,然后单击 立即同步:


    1. 既然库已准备就绪,我们需要实际实施许可证检查.转到 MainActivity.kt.


    1. 您需要找到您的 Base 64 公钥并生成盐,如this答案中所示.我将引用该答案的必要部分,但将代码翻译成 Kotlin:

    <块引用>

    1.1 您的 Base64 唯一应用程序密钥

    获取方式:

    一个.转到您的开发者控制台.链接.

    B.如果您尚未为您的应用创建应用程序草稿,请立即创建.

    c.创建草稿后,最好上传您的.apk 作为 Alpha 或 Beta.保持未发布.

    d.点击Services &API

    e.向下滚动并找到 您的此应用程序的许可证密钥

    f.像这样将密钥复制到您的应用中:

    private const val BASE64_PUBLIC_KEY = 您的此应用程序的许可证密钥";

    确保没有空格.

    1.2 一个盐

    一个.什么是盐?

    A salt 是随机数据,是在散列一个密码.它们用于防御字典攻击彩虹表攻击.

    B.我如何获得一个?

    这个是生成随机盐的好链接.应该有正是20 个随机整数,所以把 20 放在随机字符串的数量中生成,每个字符串应该是 2 个字符长(用于这个例如,它不一定是).检查数字,并检查允许使用相同的字符串.它们也可以是负数.尝试删除任何冗余,例如<代码>00 ->0,为了一致性.

    c.我把盐放在哪里?

    在声明变量时,只需输入此代码,除了您的随机盐.

    private val SALT = byteArrayOf(YOUR RANDOM SALT COMMA SPARATED 20 INTEGERS)


    1. 应将步骤 21 中的变量添加到您的主活动类中.现在,您应该向主要活动添加一些代码.下面是它的大致样子(注意 //TODO 注释):

    import android.os.Bundle导入 android.provider.Settings导入 android.widget.Toast导入 androidx.appcompat.app.AppCompatActivity导入 com.google.android.vending.licensing.*导入 kotlin.system.exitProcess类 MainActivity : AppCompatActivity(){伴生对象{private const val BASE64_PUBLIC_KEY = "您的此应用程序的许可证密钥";//TODO 替换为您自己的密钥private val SALT = byteArrayOf(YOUR RANDOM SALT COMMA SPARATED 20 INTEGERS)//TODO 替换为您自己的盐}私有 val deviceId:由惰性字符串 {Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);}private lateinit var licenseCheckerCallback:LicenseCheckerCallback私有 lateinit var 检查器:LicenseChecker私人乐趣 doCheck(){checker.checkAccess(licenseCheckerCallback)}覆盖乐趣 onDestroy(){super.onDestroy()checker.onDestroy()}覆盖 fun onCreate(savedInstanceState: Bundle?){super.onCreate(savedInstanceState)//构造 LicenseCheckerCallback.图书馆在完成后调用它.licenseCheckerCallback = MyLicenseCheckerCallback()//使用策略构建 LicenseChecker.检查器 = 许可证检查器(这个,ServerManagedPolicy(this, AESObfuscator(SALT, packageName, deviceId)),BASE64_PUBLIC_KEY//您的公共许可密钥.)做检查()setContentView(R.layout.activity_main)//TODO 替换为你自己的布局}私人乐趣 displayResult(result: String){//TODO 你可以改变信息的显示方式Toast.makeText(this, result, Toast.LENGTH_SHORT).show()}私有内部类 MyLicenseCheckerCallback : LicenseCheckerCallback{覆盖乐趣允许(原因:Int){如果(正在完成){//如果 Activity 完成,则不要更新 UI.返回}//应该允许用户访问.}覆盖有趣的应用程序错误(错误代码:Int){//TODO 以您自己的方式处理错误.调用 `dontAllow` 很常见.dontAllow(Policy.NOT_LICENSED)}覆盖乐趣 dontAllow(原因:Int){如果(正在完成){//如果 Activity 完成,则不要更新 UI.返回}如果(原因 == Policy.RETRY){//如果从策略收到的原因是 RETRY,则可能是//由于与服务的连接丢失,所以我们应该给//用户有机会重试.所以显示一个对话框来重试.//TODO 处理 Policy.RETRY}别的{//否则,用户无权使用此应用程序.//您的响应应始终通知用户该应用程序//未获得许可,但此时您的行为可能会有所不同.你可能//向用户提供您的应用程序的有限访问版本,或者您可以//将他们带到 Google Play 购买应用程序.//TODO 实现转到市场}displayResult(未获许可")//TODO 如果您有其他方法来处理失败情况,您可能不会中止中止()}}私人乐趣中止(){完成亲和力()退出进程(0)}}


    1. 将这些权限添加到您的清单文件:

    <uses-permission android:name="com.android.vending.CHECK_LICENSE"/>


    1. 如果您收到类似以下消息的异常:

    Service Intent 必须是明确的:Intent { act=com.android.vending.licensing.ILicensingService }

    应用答案中的修复.


    1. 应该就是这样了.有关详细信息,请参阅我之前引用的答案.我希望这可以为其他人节省一些时间.

    I am trying to set up Google Play Licencing for an app in Android studio for an app written in Kotlin. My goal is to avoid users sharing APK files without purchasing my app through the store.

    What I've tried:

    • I've tried following through their documentation. It's not very useful. It skips over many details and it's not really a tutorial. I couldn't use it.

    • I've seen this question, which does have a long and detailed tutorial-like answer. But the answer seems long-outdated. It causes lots of warnings and terminates with an exception "Intent must be explicit".

    My question in summary is:

    How can I set up license checking through Google so people who haven't purchased the app through the store can't install it. This seems to be a very common thing to do even though I couldn't manage to find much of any proper answer around.

    解决方案

    Here's how I got it working in 2020:

    1. Open Android Studio.


    1. Click Tools -> SDK Manager


    1. Switch to the SDK Tools tab


    1. Make sure Google Play Licensing Library is installed. If it's not installed, click the checkmark and click Apply.


    1. Up in that screen you can see Android SDK Location. Copy that path:


    1. Click File -> New -> Import Module...:


    1. Paste the path you copied and click the small folder icon on the right of the text-input line:


    1. Click Android\Sdk\extras\google\market_licensing\library and click OK:


    1. Click Next:


    1. Leave everything checked and click Finish:


    1. Now you should have a library folder in your project:


    1. Right click on app and click Open Module Settings:


    1. Click Dependencies:


    1. Click the plus button and choose 3 Module Dependency:


    1. Check library and click OK:


    1. Click OK again and wait for it to sync.


    1. If you get an error

    The minSdk version should not be declared in the android manifest file. You can move the version from the manifest to the defaultConfig in the build.gradle file.

    Go to library > manifests > AndroidManifest.xml and remove the line <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="15" />.


    1. Go to Gradle Scripts > build.gradle (Module: library):


    1. Change minSdkVersion to 4 and also change compileSdkVersion, buildToolsVersion and targetSdkVersion as necessary, then click Sync Now:


    1. Now that the library is ready, we need the actual implementation of the license checking. Go to MainActivity.kt.


    1. You need to find your Base 64 public key and also generate a salt as shown in this answer. I am going to quote the necessary part of that answer but translate the code to Kotlin:

    1.1 Your Base64 unique application key

    How to get it:

    a. Go to your developer console. Link.

    b. If you haven't already created an application draft for your app, do it now.

    c. Once you have created the draft, it is a good idea to upload your .apk as Alpha or Beta. Leave it unpublished.

    d. Click Services & APIs

    e. Scroll down and find YOUR LICENSE KEY FOR THIS APPLICATION

    f. Copy the key into your app like this:

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

    Make sure that there are no spaces.

    1.2 A salt

    a. What is a salt?

    A salt is random data that is additional input when hashing a password. They are used to defend against dictionary attacks and rainbow table attacks.

    b. How do I get one?

    This is a good link to generate a random salt. There should be exactly 20 random integers, so put 20 in for the amount of random strings to generate, each string should be 2 characters long (used for this example, it doesn't have to be). Check numeric digits, and check Identical strings are allowed. They can be negative numbers too. Try to remove any redundancy, e.g. 00 -> 0, for the sake of consistency.

    c. Where do I put the salt?

    When declaring variables just put this code in, except with your random salt.

    private val SALT = byteArrayOf(YOUR RANDOM SALT COMMA SEPARATED 20 INTEGERS)
    


    1. Variables in step 21 should be added to your main activity class. Now, you should add some code to your main activity. Here's what it should roughly look like (Pay attention to // TODO comments):

    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) 
        }
    }
    


    1. Add these permissions to your manifest file:

    <uses-permission android:name="android.permission.INTERNET"/>  
    <uses-permission android:name="com.android.vending.CHECK_LICENSE"/>
    


    1. If you get an exception with a message similar to:

    Service Intent must be explicit: Intent { act=com.android.vending.licensing.ILicensingService }
    

    Apply the fix in this answer.


    1. That should be all. See the answer I quoted previously for more info. I hope this saves others some time.

    这篇关于Android Studio 中 Android 应用程序的 Google Play 许可的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆