IT박스

Android 앱의 유료 및 무료 버전을 얻는 가장 좋은 방법

itboxs 2020. 12. 1. 07:48
반응형

Android 앱의 유료 및 무료 버전을 얻는 가장 좋은 방법


Android 마켓에 이미 무료 앱이 있지만 더 나은 기능이있는 유료 버전을 추가하고 싶습니다. 마켓에서 이미 마켓에 해당 패키지 이름을 가진 앱이 있다고 알려주기 때문에 일부 변경된 상수를 사용하여 동일한 기능을 잠금 해제 할 수 없습니다.

이 작업을 수행하는 가장 깨끗한 방법은 무엇입니까?


Android SDK는 라이브러리 프로젝트라고하는 것을 통해 공유 또는 공통 코드베이스 문제를 공식적으로 해결합니다.

http://developer.android.com/tools/projects/index.html

기본적으로 공유 코드는 라이브러리 프로젝트로 정의되고 유료 버전과 무료 버전은 이클립스 워크 벤치에있는 두 개의 다른 프로젝트이며 둘 다 앞서 언급 한 라이브러리 프로젝트를 참조합니다.

빌드시 라이브러리 프로젝트는 원하는 릴리스 중 하나와 병합됩니다.

Android SDK 예제 소스 코드에는 라이브러리 프로젝트 사용을 시작하는 데 도움이되는 TicTacToe라는 프로젝트가 포함되어 있습니다.

행운을 빕니다.

다니엘


몇 가지 접근 방식이 있지만 일반적으로 직접 시도 할 때까지 단점을 알 수 없습니다. 내 경험은 다음과 같습니다.

  1. Unlocker 앱. 이것은 구현하기 매우 쉽습니다. 라이선스 역할을하는 새 앱을 만듭니다. 원래 앱은 잠금 해제 앱의 서명이 앱의 서명과 일치하는지 확인해야합니다 (예인 경우 잠금 해제 프로그램을 기기에서 사용할 수 있고 그렇지 않으면 아니요). 잠금 해제 프로그램이 설치되지 않은 경우 무료 앱을 다운로드하라는 메시지를 표시해야합니다. 그렇지 않으면 시작하고 실행기 아이콘을 제거하십시오.

    장점 : 구현하기 쉽고 유지 관리 할 코드베이스가 하나뿐입니다.
    단점 :사용자는 때때로이 모델에 대해 혼란스러워하며, 두 개의 런처 아이콘이있는 이유 또는 방금 다운로드 한 항목을 이해하지 못합니다. 런처 아이콘을 제거하는 것은 번거롭고 장치가 재부팅 된 경우에만 변경 사항이 표시됩니다. 또한 무료 앱이 유료 잠금 해제 앱을 대신하여 라이선스 요청을 할 수 없기 때문에 Google의 라이선스 API (LVL)를 사용할 수없는 것 같습니다. 이 후자에 대한 해결 방법은 나쁜 사용자 경험으로 이어집니다.

  2. 인앱 구매. 어쨌든 코드에 IAP가 있으면 쉽게 구현할 수 있습니다. 그렇지 않으면 제대로 작동하는 데 상당한 시간이 걸립니다.

    장점 : 유지 관리 할 코드베이스가 하나 뿐이며 사용자를위한 구매 흐름이 매우 편리합니다.
    단점 : 사용자는 구매가 '지속적'인지 여부에 대해 우려한다고합니다. 즉, 나중에 앱을 다른 기기에 설치하거나 다시 설치하면 프로 기능을 계속 사용할 수 있는지 혼란스러워합니다.

  3. 공유 라이브러리 프로젝트가있는 무료 및 유료 버전. 이것은 코딩하기 어려운 일이 아니어야하며 대부분의 앱 로직을 포함하고 차이점 만 유지하는 단일 코드베이스를 갖는 논리적 결정처럼 보입니다.

    장점 : 사용자는이 모델에 덜 혼동되지만 유료 버전을 사용하기 시작하면 선호도를 잃을 지 걱정할 것입니다.
    단점 :내 경험상 Java / Eclipse는 라이브러리와 관련하여 실제로 친숙하지 않습니다. 프로젝트를 올바르게 설정하는 데 약간의 시간이 걸리지 만 전체가 어떻게 작동하는지, 어떤 매니페스트에 넣을지, 리소스에 어떤 일이 발생하는지 등 여전히 혼란 스러울 것입니다. 잘못 구성된 프로젝트와 빌드 문제에 직면하게됩니다. 리소스를 찾을 수 없습니다 (라이브러리 프로젝트는 이미 참조 된 리소스를 '보지'않으므로 참조를 하나씩 편집해야합니다). 더욱이이 모델에서는 애셋 파일이 지원되지 않습니다. 즉, "단일 코드베이스"프로젝트가 이미 엉망이 된 끔찍한 혼란을 가중시킬 수있는 심볼릭 링크, 복사 또는 기타 마법으로 몇 가지 트릭을 수행해야합니다. 그리고 프로젝트가 마침내 빌드되면 모든 것이 예상대로 작동하도록 손가락을 엇갈리게해야합니다. 누락 된 이미지와 숨겨진 오류에 대비하십시오. 물론 처음 출시 할 때 사용자에게 선호도를 유료 버전으로 마이그레이션하는 편리한 방법을 제공해야합니다.

  4. 별도의 코드베이스와 소스 컨트롤이있는 무료 및 유료 버전. 언뜻보기에 이것은 또한 괜찮은 소스 제어 시스템이 당신의 어깨에서 무게를 들어 올릴 수 있기 때문에 좋은 생각으로 보입니다.하지만 ...

    장점 : 3과 동일합니다.
    단점 : 당신은 두 개의 다른 코드베이스를 유지하고 병합 / 분기하는 지옥 만 유지하게 될 것입니다. 여기에서 예상됩니다. 앱 패키지 이름은 달라야하므로 깔끔하게 유지하려면 보유한 모든 파일을 구분해야합니다. 물론 처음 출시 할 때 사용자에게 선호도를 유료 버전으로 마이그레이션하는 편리한 방법을 제공해야합니다.

  5. 서로 파생되는 스크립트가 포함 된 무료 및 유료 버전. 달성하기에는 더러운 해킹처럼 들리지만 작동하는지 확실히 알고 있습니다.

    장점 : 3과 동일하고 단일 코드베이스 만 유지합니다.
    단점 : 스크립트를 만드는 데 약간의 시간이 걸리며 (폴더 이름을 바꾸고, 패키지, 응용 프로그램 및 프로젝트 이름을 바꾸십시오) 필요한 경우 스크립트를 수시로 업데이트하도록주의해야합니다 (이는 발생하지 않음). 무료 버전과 유료 버전 사이에 차이가 너무 많지 않은 경우). 물론 처음 출시 할 때 사용자에게 선호도를 유료 버전으로 마이그레이션하는 편리한 방법을 제공해야합니다.

완벽한 솔루션은 없지만 가능성 중 하나를 구현하려는 경우 위의 내용이 올바른 방향을 제시 할 수 있습니다.


Gradle 빌드 시스템을 사용하면 이제 각각 고유 한 패키지 이름을 가진 다양한 제품 버전을 가질 수 있습니다. 다음은 동일한 앱의 무료 및 프로 버전이있는 gradle 스크립트의 예입니다.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 19
    buildToolsVersion "19.1"

    defaultConfig {
        applicationId "com.example.my.app"
    }

    productFlavors {
        free {
            applicationId "com.example.my.app"
            minSdkVersion 15
            targetSdkVersion 23
            versionCode 12
            versionName '12'
        }
        pro {
            applicationId "com.example.my.app.pro"
            minSdkVersion 15
            targetSdkVersion 23
            versionCode 4
            versionName '4'
        }
    }

R클래스는에 지정된 패키지 이름으로 생성 AndroidManifest.xml되므로 플레이버를 전환 할 때 한 줄의 코드를 변경할 필요가 없습니다.

Build VariantsAndroid Studio의 왼쪽 하단에서 액세스 할 수있는 창 에서 플레이버를 전환 할 수 있습니다 . 또한 서명 된 APK를 생성하려는 경우 Android 스튜디오에서 APK를 빌드하려는 버전을 묻습니다.

또한 각 플레이버마다 다른 리소스를 가질 수 있습니다. 예를 들어, 디렉토리 pro디렉토리 만들 수 있습니다 src. 디렉토리 구조는 디렉토리와 유사해야합니다 main. (예 : 프로 버전에 대해 다른 런처 아이콘을 원하면에 배치 할 수 있습니다 src\pro\res\drawable. 플레이버 src\main\res\drawable로 전환하면 에있는 무료 아이콘이 대체 됩니다 pro.)

위에서 설명한 strings.xmlin pro리소스 디렉토리 를 생성 하면 메인 strings.xml과 프로 strings.xml가 병합 strings.xml되어 pro플레이버 빌드시 최종 결과를 얻습니다 . 특정 문자열 키가 free 및 pro xml 모두에 존재하는 경우 문자열 값은 pro xml에서 가져옵니다.

현재 버전이 코드에서 프로인지 무료인지 확인해야 할 경우 다음과 같은 방법을 사용할 수 있습니다.

public boolean isPro() {
    return context.getPackageName().equals("com.example.my.app.pro");
}

자세한 내용은 참조하십시오


하나의 소스 코드 두 개의 앱 (Eclipse)

시장에서 두 가지 형태의 프레젠테이션으로 앱을 관리하는 데 반복되는 문제가 있습니다. 아마도 둘 사이에 1 비트 차이 만있을 수 있습니다 (paidFor = true;) 아이콘도 다를 수 있습니다.

이 접근 방식은 http://blog.javia.org/android-package-name/ 에서 Mihai가 설명하는 패키지 이름에 대한 설명을 사용합니다.이 설명은 소스 코드를 관리하는 데 사용되는 패키지 이름과 게시하는 데 사용되는 패키지 이름 간의 차이를 강조합니다. Android 마켓의 apk. 이 예에서 게시 된 두 패키지 이름은 com.acme.superprogram 및 com.acme.superprogrampaid이고 Java 소스 코드 패키지 이름은 com.acme.superprogram입니다.

매니페스트에서 활동은 .ActivityName으로 나열되고 이름이 지정됩니다. Mike Wallace는 최근 프레젠테이션에서 앞의 점이 중요하며 정규화 된 패키지로 대체 할 수 있다고 지적했습니다. 예를 들어 "com.acme.superprogram.DialogManager"는 manifest.xml 텍스트에서 ".DialogManager"를 대체 할 수 있습니다.

1 단계는 java 소스 코드 관리 패키지 이름 (com.acme.superprogram)을 사용하여 모든 활동 android : name 항목을 이러한 완전한 패키지 이름으로 바꾸는 것입니다.

그런 다음 매니페스트 패키지 이름을 변경할 수 있습니다.

Eclipse에서는 강제로 재 컴파일되고 gen 폴더에 새 R.java가 생성됩니다. 여기에 약간 까다로운 부분이 있습니다. com.acme.superprogram 및 com.acme.superprogrampaid 폴더에는 두 개의 폴더가 있으며 하나에 만 R.java가 있습니다. 프로그램이 R.layout.xyz 항목을 확인할 수 있도록 R.java를 다른 폴더에 복사하기 만하면됩니다.

패키지를 변경할 때

몇 가지 앱에서 시도해 보았습니다. 에뮬레이터와 2.1 전화에서 함께 실행 중이며 둘 다 Android 마켓에 있습니다.


나는 같은 문제를 안고 두 개의 안드로이드 앱을 만드는데 하나는 my_epic_app_free이고 다른 하나는 my_epic_app_paid입니다. 내가 할 일은 유료 버전 만 변경 한 다음 별도의 Java 콘솔 프로그램이 있습니다. 디스크에서 직접 모든 .java 파일에 액세스하고 메모리에 복사하고 패키지 이름과 매니페스트 행을 조작하는 것뿐입니다. 그런 다음 무료 앱에 직접 붙여 넣습니다. 데스크톱의 버튼 누름에이 기능이 있으므로 유료 버전에서 개발이 끝나면 버튼을 누른 다음 무료 버전을 컴파일합니다. 유료 앱과 무료 앱이 서로 통신하고 사용자는 둘 다 설치할 수도 있으며 무료 버전은 유료 버전을보고 유료 버전으로 잠금 해제됩니다.

또 다른 아이디어는 유료 앱을 키 파일이 포함 된 베어 본 프로그램으로 만드는 것입니다. 유료 앱이 실행되면 자동으로 무료 버전이 실행되고 무료 버전은 유료 버전으로 작동합니다.

무료 앱은 유료 앱의 키 파일이 있는지 확인하고, 존재하는 경우 무료 앱의 잠금을 해제합니다. 이것은 코드 중복을 방지합니다. 패키지 이름은 여전히 ​​달라야하지만 이상적으로는 유료 앱을 자주 변경할 필요가 없습니다.

이점 : 유료 버전으로 "업그레이드"할 때 사용자 데이터 / 설정이 손실되지 않습니다.

단점 : 사용자가 먼저 유료 버전을 설치하면 번거로운 무료 버전을 설치하도록 지시해야합니다. 왜 유료 버전에 대해 두 개의 앱을 설치해야합니까?


마모 모듈도있는 경우 추가 작업을 수행해야합니다.

다음은 플레이버 및 빌드 유형으로 마모 모듈을 패키징하기위한 Gradle 파일의 몇 가지 예 입니다.

모듈 모바일 build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.example.app"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 85
        versionName "2.5.2"
    }
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
            embedMicroApp = true
            minifyEnabled false
        }
        release {
            embedMicroApp = true
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            zipAlignEnabled true
        }
    }
    productFlavors {
        free{
            applicationId "com.example.app"
        }
        pro{
            applicationId "com.example.app.pro"
        }
    }
}

configurations {
    freeDebugWearApp
    proDebugWearApp
    freeReleaseWearApp
    proReleaseWearApp
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'

    freeDebugWearApp project(path: ':wear', configuration: 'freeDebug')
    proDebugWearApp project(path: ':wear', configuration: 'proDebug')

    freeReleaseWearApp project(path: ':wear', configuration: 'freeRelease')
    proReleaseWearApp project(path: ':wear', configuration: 'proRelease')
}

모듈 마모 build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
    publishNonDefault true

    defaultConfig {
        applicationId "com.example.app"
        minSdkVersion 20
        targetSdkVersion 23
        versionCode 85
        versionName "2.5.2"
    }
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
            minifyEnabled false
        }
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            zipAlignEnabled true
        }
    }
    productFlavors {
        free {
            applicationId "com.example.app"
        }
        pro {
            applicationId "com.example.app.pro"
        }
    }
}

dependencies {

    ...

}

도서관 프로젝트를 사용하고 싶지 않고 두 사람이 의견에 언급 한 위험에 만족한다면 @ user426990이 이론적으로 훌륭한 대답을 제공했습니다. 그러나 eclipse는 내보내기를 위해 새로운 빌드를 할 때 gen 디렉토리의 전체 내용을 지우는 것처럼 보입니다 (일반 원칙으로 주장하기가 어렵습니다).

com.acme.superprogram을 작성했고 com.acme.superprogrampaid를 작성하려는 경우 동일한 원칙에 기반한 대체 솔루션은 다음과 같습니다.

  1. Ensure that your manifest points to the activities, services and so on by full name. As per @user426990's answer ".CoolActivity" must be listed as com.acme.superprogram.CoolActivity

  2. Create a new class MyR in your code (com.activity.superprogram, with the rest of the code) as follows:

    package com.acme.superprogram;
    import com.acme.superprogram.R;
    
    public final class MyR {
        public final static R.attr     attr     = new R.attr();
        public final static R.color    color    = new R.color();
        public final static R.dimen    dimen    = new R.dimen();
        public final static R.layout   layout   = new R.layout();
        public final static R.id       id       = new R.id();
        public final static R.string   string   = new R.string();
        public final static R.drawable drawable = new R.drawable();
        public final static R.raw      raw      = new R.raw();
        public final static R.style    style    = new R.style();
        public final static R.xml      xml      = new R.xml();
    }
    

    You will need to vary the exact content to reflect the resources you use! For example, you may not need the xml line and may need another one. Look at the real R.java file in gen/com/acme/superprogram and you will need one line per class. You may need to subclass.

  3. Now (a) remove all "import com.acme.superprogram.R" lines from your code and (b) replace all "R." references to "MyR.". This way all your references to R are indirected via one place. the downside is that they all get warnings about not being static enough. You have three options with these warnings: you can suppress them, you can ignore them, or you can make a more complete version of MyR, with a line for each entry in R which you use:

    package com.acme.superprogram;
    import com.acme.superprogram.R;
    
    public final class MyR {
        final static class attr {
            final static int XXXX = R.attr.XXXX
    // And so on ...
    
  4. As per @user426990, you can now change the package in the manifest from "com.acme.superprogram" to "com.acme.superprogrampaid"; you probably also want to change the name, launch icon and the key variables at this point.

  5. Change the import line in MyR to import com.acme.superprogrampaid.R

And away you go.

ps. Remember to change the file name in the final export dialog box ...


Changing the package name will help.
Just change the package name of your paid app using eclipse and put it in market.

That will solve your problem.


Why not make two different Eclipse projects? It is not so difficult to fix the few things referring to the package name by hand. Take care to change the import statements and the manifest file. You need to code twice anyway. Of course, it is a nuisance to fix code in both places.

The proper solution would be in the market. It should allow two applications with the same package names, and ask to replace the one when the other is to be installed. Upon upload, it should check if the package name is really from the same software vendor.

Rene

참고URL : https://stackoverflow.com/questions/3711967/best-way-to-have-paid-and-free-version-of-an-android-app

반응형