├── android
├── settings.gradle
├── gradle.properties
├── .gitignore
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── kotlin
│ │ └── cu
│ │ └── fluttercuba
│ │ └── apklis_payment_checker
│ │ ├── ApklisPaymentCheckerPlugin.kt
│ │ └── Verify.kt
└── build.gradle
├── example
├── README.md
├── android
│ ├── gradle.properties
│ ├── app
│ │ ├── src
│ │ │ ├── main
│ │ │ │ ├── res
│ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── drawable
│ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ └── values
│ │ │ │ │ │ └── styles.xml
│ │ │ │ ├── kotlin
│ │ │ │ │ └── cu
│ │ │ │ │ │ └── fluttercuba
│ │ │ │ │ │ └── apklis_payment_checker_example
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── debug
│ │ │ │ └── AndroidManifest.xml
│ │ │ └── profile
│ │ │ │ └── AndroidManifest.xml
│ │ └── build.gradle
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ ├── .gitignore
│ ├── build.gradle
│ └── settings.gradle
├── .metadata
├── analysis_options.yaml
├── pubspec.yaml
├── .gitignore
└── lib
│ └── main.dart
├── .metadata
├── .gitignore
├── test
├── apklis_payment_status_test.dart
├── apklis_info_test.dart
└── apklis_payment_checker_test.dart
├── pubspec.yaml
├── analysis_options.yaml
├── .github
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
└── workflows
│ ├── publish.yml
│ └── tests.yml
├── lib
├── apklis_payment_status.dart
├── apklis_info.dart
└── apklis_payment_checker.dart
├── CHANGELOG.md
├── LICENSE
├── README.md
└── CODE_OF_CONDUCT.md
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'apklis_payment_checker'
2 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # Apklis Payment Checker Example for Flutter
2 |
3 | Demonstrates how to use the `apklis_payment_checker` plugin.
4 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 | android.enableR8=true
5 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fluttercuba/apklis-payment-checker-flutter/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fluttercuba/apklis-payment-checker-flutter/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fluttercuba/apklis-payment-checker-flutter/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fluttercuba/apklis-payment-checker-flutter/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fluttercuba/apklis-payment-checker-flutter/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
6 |
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/cu/fluttercuba/apklis_payment_checker_example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package cu.fluttercuba.apklis_payment_checker_example
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 1aafb3a8b9b0c36241c5f5b34ee914770f015818
8 | channel: stable
9 |
10 | project_type: plugin
11 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 1aafb3a8b9b0c36241c5f5b34ee914770f015818
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | allprojects {
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 | }
8 |
9 | rootProject.buildDir = '../build'
10 | subprojects {
11 | project.buildDir = "${rootProject.buildDir}/${project.name}"
12 | project.evaluationDependsOn(':app')
13 | }
14 |
15 | tasks.register("clean", Delete) {
16 | delete rootProject.buildDir
17 | }
18 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 |
9 | # Added manually
10 |
11 | # https://dart.dev/guides/libraries/private-files#the-rules
12 | doc/api/
13 |
14 | # https://dart.dev/guides/libraries/private-files#pubspeclock
15 | # Except for application packages
16 | pubspec.lock
17 |
18 | # IntelliJ
19 | *.iml
20 | *.ipr
21 | *.iws
22 | .idea/
23 |
24 | # VSCode
25 | .code
26 | coverage/
27 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:lint/analysis_options.yaml
2 |
3 | analyzer:
4 | exclude:
5 | #- '**.freezed.dart'
6 |
7 | linter:
8 | rules:
9 | # Util classes are awesome!
10 | # avoid_classes_with_only_static_members: false
11 |
12 | # Make constructors the first thing in every class
13 | # sort_constructors_first: true
14 |
15 | # Choose wisely, but you don't have to
16 | # prefer_double_quotes: true
17 | # prefer_single_quotes: true
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: apklis_payment_checker_example
2 | description: Demonstrates how to use the apklis_payment_checker plugin.
3 |
4 | publish_to: "none"
5 |
6 | environment:
7 | sdk: ">=3.2.0 <4.0.0"
8 |
9 | dependencies:
10 | apklis_payment_checker:
11 | path: ../
12 | cupertino_icons: ^1.0.0
13 | flutter:
14 | sdk: flutter
15 |
16 | dev_dependencies:
17 | flutter_test:
18 | sdk: flutter
19 | lint: ^1.10.0
20 |
21 | flutter:
22 | uses-material-design: true
23 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/test/apklis_payment_status_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:apklis_payment_checker/apklis_payment_status.dart';
2 | import 'package:flutter_test/flutter_test.dart';
3 |
4 | void main() {
5 | group('ApklisPaymentStatus', () {
6 | test('support equality', () {
7 | final paymentStatus1 =
8 | ApklisPaymentStatus(paid: true, username: 'username');
9 | final paymentStatus2 =
10 | ApklisPaymentStatus(paid: true, username: 'username');
11 |
12 | expect(paymentStatus1, equals(paymentStatus2));
13 | expect(paymentStatus1.hashCode, equals(paymentStatus2.hashCode));
14 | });
15 | });
16 | }
17 |
--------------------------------------------------------------------------------
/test/apklis_info_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:apklis_payment_checker/apklis_info.dart';
2 | import 'package:flutter_test/flutter_test.dart';
3 |
4 | void main() {
5 | group('ApklisInfo', () {
6 | test('support equality', () {
7 | final apklisInfo1 = ApklisInfo(
8 | isInstalled: true,
9 | versionCode: 1,
10 | versionName: '1.0.0',
11 | );
12 | final apklisInfo2 = ApklisInfo(
13 | isInstalled: true,
14 | versionCode: 1,
15 | versionName: '1.0.0',
16 | );
17 |
18 | expect(apklisInfo1, equals(apklisInfo2));
19 | expect(apklisInfo1.hashCode, equals(apklisInfo2.hashCode));
20 | });
21 | });
22 | }
23 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: apklis_payment_checker
2 | description: Plugin de Flutter para el chequeo de pagos de Apklis. Basado en el repositorio para Kotlin y Java https://github.com/Z17-CU/apklischeckpayment
3 | version: 1.1.0
4 | homepage: https://github.com/fluttercuba/apklis-payment-checker-flutter
5 |
6 | environment:
7 | sdk: ">=3.2.0 <4.0.0"
8 | flutter: ">=3.16.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 |
14 | dev_dependencies:
15 | flutter_test:
16 | sdk: flutter
17 | lint: ^2.8.0
18 |
19 | flutter:
20 | plugin:
21 | platforms:
22 | android:
23 | package: cu.fluttercuba.apklis_payment_checker
24 | pluginClass: ApklisPaymentCheckerPlugin
25 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:lint/analysis_options.yaml
2 |
3 | # You might want to exclude auto-generated files from dart analysis
4 | analyzer:
5 | exclude:
6 | #- '**.freezed.dart'
7 |
8 | # You can customize the lint rules set to your own liking. A list of all rules
9 | # can be found at https://dart-lang.github.io/linter/lints/options/options.html
10 | linter:
11 | rules:
12 | # Util classes are awesome!
13 | # avoid_classes_with_only_static_members: false
14 |
15 | # Make constructors the first thing in every class
16 | # sort_constructors_first: true
17 |
18 | # Choose wisely, but you don't have to
19 | # prefer_double_quotes: true
20 | # prefer_single_quotes: true
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Solicitud de característica
3 | about: Sugerir una idea para este proyecto
4 | title: '[FEATURE] '
5 | labels: 'feature'
6 | assignees: ''
7 |
8 | ---
9 |
10 | **¿Su solicitud de característica está relacionada con un problema? Por favor describa.**
11 | Una descripción clara y concisa de cuál es el problema. Ex. Siempre me frustra cuando [...]
12 |
13 | **Describe la solución que te gustaría**
14 | Una descripción clara y concisa de lo que quieres que suceda.
15 |
16 | **Describe las alternativas que has considerado**
17 | Una descripción clara y concisa de cualquier solución o característica alternativa que haya considerado.
18 |
19 | **Contexto adicional**
20 | Agregue cualquier otro contexto o capturas de pantalla sobre la solicitud de función aquí.
21 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }()
9 |
10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
11 |
12 | repositories {
13 | google()
14 | mavenCentral()
15 | gradlePluginPortal()
16 | }
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21 | id 'com.android.library' version '8.8.2' apply false
22 | id 'org.jetbrains.kotlin.android' version '2.1.10' apply false
23 | }
24 |
25 | include ":app"
--------------------------------------------------------------------------------
/lib/apklis_payment_status.dart:
--------------------------------------------------------------------------------
1 | /// La clase ApklisPaymentStatus registra el estado de un pago.
2 | ///
3 | /// Registra si esta pagado o no.
4 | /// Registra el nombre de usuario que realiza la acción de chequeo.
5 | class ApklisPaymentStatus {
6 | /// El [paid] almacena el estado del Payment en true | false
7 | final bool paid;
8 |
9 | /// El [username] almacena el nombre de usuario.
10 | final String? username;
11 |
12 | /// Para crear un instancia de la clase [ApklisPaymentStatus]
13 | ApklisPaymentStatus({
14 | required this.paid,
15 | required this.username,
16 | });
17 |
18 | @override
19 | bool operator ==(Object other) {
20 | if (identical(this, other)) return true;
21 |
22 | return other is ApklisPaymentStatus &&
23 | other.paid == paid &&
24 | other.username == username;
25 | }
26 |
27 | @override
28 | int get hashCode => paid.hashCode ^ username.hashCode;
29 | }
30 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | # .github/workflows/publish.yml
2 | name: Publish to pub.dev
3 |
4 | on:
5 | push:
6 | tags:
7 | # must align with the tag-pattern configured on pub.dev, often just replace
8 | # {{version}} with [0-9]+.[0-9]+.[0-9]+
9 | # - 'v[0-9]+.[0-9]+.[0-9]+' # tag-pattern on pub.dev: 'v{{version}}'
10 | - 'v*.*.*'
11 | # If you prefer tags like '1.2.3', without the 'v' prefix, then use:
12 | # - '[0-9]+.[0-9]+.[0-9]+' # tag-pattern on pub.dev: '{{version}}'
13 | # If your repository contains multiple packages consider a pattern like:
14 | # - 'my_package_name-v[0-9]+.[0-9]+.[0-9]+'
15 |
16 | # Publish using the reusable workflow from dart-lang.
17 | jobs:
18 | publish:
19 | permissions:
20 | id-token: write # Required for authentication using OIDC
21 | uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1
22 | # with:
23 | # working-directory: path/to/package/within/repository
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Historial de Cambios
2 |
3 | ## 1.1.0
4 |
5 | * Actualizada versión mínima de Flutter a ">=3.16.0" y Dart a ">=3.2.0 <4.0.0"
6 | * Actualizado el Apklis payment provider en Android
7 | * Actualizadas las versiones de AGP y Gradle
8 |
9 | ## 1.1.0-dev.4
10 |
11 | * Actulizada versión mínima de Flutter a ">=3.16.0" y Dart a ">=3.2.0 <4.0.0"
12 |
13 | ## 1.1.0-dev
14 |
15 | * Actulizado el Apklis payment provider en Android
16 | * Actulizadas las versiones de AGP y Gradle
17 |
18 | ## 1.0.0
19 |
20 | * Soporte para null-safety
21 |
22 | ## 0.3.1
23 |
24 | * Añadir comentarios para la generación automática de la documentación
25 |
26 | ## 0.3.0
27 |
28 | * Implementar método para saber si Apklis está instalada en el dispositivo (En caso positivo, saber también el número y nombre de la versión)
29 |
30 | ## 0.2.0
31 |
32 | * Utilizar por defecto el nombre del paquete de la aplicación
33 |
34 | ## 0.1.1
35 |
36 | * Poner de homepage el enlace al repositorio
37 | * Añadir un badge de la última versión disponible en pub.dev
38 |
39 | ## 0.1.0
40 |
41 | * Implementar la primera versión beta
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Flutter Cuba
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Informe de error
3 | about: Crea un informe de error para ayudarnos a mejorar
4 | title: '[BUG] '
5 | labels: 'bug'
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe el error**
11 | Una descripción clara y concisa de cuál es el error.
12 |
13 | **Reproducir**
14 | Pasos para reproducir el comportamiento:
15 | 1. Vaya a '...'
16 | 2. Haga clic en '....'
17 | 3. Desplácese hacia abajo hasta '....'
18 | 4. Ver error
19 |
20 | **Comportamiento esperado**
21 | Una descripción clara y concisa de lo que esperaba que sucediera.
22 |
23 | **Capturas de pantalla**
24 | Si corresponde, agregue capturas de pantalla para ayudar a explicar su problema.
25 |
26 | **Escritorio (complete la siguiente información):**
27 | - SO: [p. Ej. iOS]
28 | - Navegador [p. Ej. cromo, safari]
29 | - Versión [p. Ej. 22]
30 |
31 | **Smartphone (complete la siguiente información):**
32 | - Dispositivo: [p. Ej. iphone 6]
33 | - SO: [p. Ej. iOS8.1]
34 | - Navegador [p. Ej. navegador de valores, safari]
35 | - Versión [p. Ej. 22]
36 |
37 | **Contexto adicional**
38 | Agregue aquí cualquier otro contexto sobre el problema.
39 |
--------------------------------------------------------------------------------
/lib/apklis_info.dart:
--------------------------------------------------------------------------------
1 | /// La clase ApklisInfo registra la información de la aplicación Apklis.
2 | ///
3 | /// Registra si se encuentra instalada o no.
4 | /// Registra el código de la versión.
5 | /// Registra el nombre de la versión.
6 | class ApklisInfo {
7 | /// El [isInstalled] almacena el valor en `true` si esta instalada
8 | /// y `false` en caso contrario.
9 | final bool isInstalled;
10 |
11 | /// El [versionCode] almacena el valor del código de la versión
12 | final int? versionCode;
13 |
14 | /// El [versionName] almacena el valor del nombre de la versión
15 | final String? versionName;
16 |
17 | /// Para crear una instancia de la clase [ApklisInfo]
18 | ApklisInfo({
19 | required this.isInstalled,
20 | required this.versionCode,
21 | required this.versionName,
22 | });
23 |
24 | @override
25 | bool operator ==(Object other) {
26 | if (identical(this, other)) return true;
27 |
28 | return other is ApklisInfo &&
29 | other.isInstalled == isInstalled &&
30 | other.versionCode == versionCode &&
31 | other.versionName == versionName;
32 | }
33 |
34 | @override
35 | int get hashCode =>
36 | isInstalled.hashCode ^ versionCode.hashCode ^ versionName.hashCode;
37 | }
38 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'cu.fluttercuba.apklis_payment_checker'
2 | version '1.0-SNAPSHOT'
3 |
4 | buildscript {
5 | ext.kotlin_version = '1.7.10'
6 | repositories {
7 | google()
8 | mavenCentral()
9 | }
10 |
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:4.1.3'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | }
15 | }
16 |
17 | rootProject.allprojects {
18 | repositories {
19 | google()
20 | mavenCentral()
21 | }
22 | }
23 |
24 | apply plugin: 'com.android.library'
25 | apply plugin: 'kotlin-android'
26 |
27 | android {
28 | namespace="cu.fluttercuba.apklis_payment_checker"
29 | compileSdkVersion 34
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_17
33 | targetCompatibility JavaVersion.VERSION_17
34 | }
35 |
36 | sourceSets {
37 | main.java.srcDirs += 'src/main/kotlin'
38 | }
39 | defaultConfig {
40 | minSdkVersion 16
41 | }
42 | lintOptions {
43 | disable 'InvalidPackage'
44 | }
45 | }
46 |
47 | dependencies {
48 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
49 | implementation 'androidx.annotation:annotation:1.4.0'
50 | }
51 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
17 |
20 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
33 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | id "dev.flutter.flutter-gradle-plugin"
5 | }
6 |
7 | def localProperties = new Properties()
8 | def localPropertiesFile = rootProject.file('local.properties')
9 | if (localPropertiesFile.exists()) {
10 | localPropertiesFile.withReader('UTF-8') { reader ->
11 | localProperties.load(reader)
12 | }
13 | }
14 |
15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
16 | if (flutterVersionCode == null) {
17 | flutterVersionCode = '1'
18 | }
19 |
20 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
21 | if (flutterVersionName == null) {
22 | flutterVersionName = '1.0'
23 | }
24 |
25 | android {
26 | namespace="cu.fluttercuba.apklis_payment_checker_example"
27 | compileSdkVersion 34
28 |
29 | compileOptions {
30 | sourceCompatibility JavaVersion.VERSION_17
31 | targetCompatibility JavaVersion.VERSION_17
32 | }
33 |
34 | sourceSets {
35 | main.java.srcDirs += 'src/main/kotlin'
36 | }
37 |
38 | lintOptions {
39 | disable 'InvalidPackage'
40 | }
41 |
42 | defaultConfig {
43 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
44 | applicationId "cu.fluttercuba.apklis_payment_checker_example"
45 | minSdkVersion flutter.minSdkVersion
46 | targetSdkVersion 31
47 | versionCode flutterVersionCode.toInteger()
48 | versionName flutterVersionName
49 | }
50 |
51 | buildTypes {
52 | release {
53 | // TODO: Add your own signing config for the release build.
54 | // Signing with the debug keys for now, so `flutter run --release` works.
55 | signingConfig signingConfigs.debug
56 | }
57 | }
58 | }
59 |
60 | flutter {
61 | source '../..'
62 | }
63 |
--------------------------------------------------------------------------------
/lib/apklis_payment_checker.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:apklis_payment_checker/apklis_info.dart';
4 | import 'package:apklis_payment_checker/apklis_payment_status.dart';
5 | import 'package:flutter/services.dart';
6 |
7 | // ignore: avoid_classes_with_only_static_members
8 | /// {@template apklis_payment_checker}
9 | /// La clase ApklisPaymentChecker registra las funcionalidades de Apklis.
10 | ///
11 | /// Registra la función para obtener el nombre del paquete.
12 | /// Registra la función para comprobar si esta pagado o no.
13 | /// Registra la función para obtener la información de Apklis.
14 | /// {@endtemplate}
15 | class ApklisPaymentChecker {
16 | /// Establece la comunicacion entre codigo de Kotlin/Android y Flutter/Dart.
17 | static const _channel = MethodChannel('apklis_payment_checker');
18 |
19 | /// Devuelve `String` con el nombre del paquete.
20 | static Future getPackageName() async {
21 | final Map? map = await _channel.invokeMapMethod('getPackageName');
22 |
23 | final String packageName = map!['packageName'] as String;
24 |
25 | return packageName;
26 | }
27 |
28 | /// Devuelve `Future` con la información del estado de pago.
29 | static Future isPurchased([String? packageId]) async {
30 | packageId ??= await getPackageName();
31 | final Map? map = await _channel.invokeMapMethod('isPurchased', packageId);
32 | if (map == null) {
33 | return ApklisPaymentStatus(paid: false, username: null);
34 | }
35 |
36 | final paid = map['paid'] as bool;
37 | final username = map['username'] as String?;
38 |
39 | return ApklisPaymentStatus(paid: paid, username: username);
40 | }
41 |
42 | /// Devuelve `Future` con la información de Apklis.
43 | static Future getApklisInfo() async {
44 | final Map? map = await _channel.invokeMapMethod('getApklisInfo');
45 |
46 | final isIntalled = map!['isIntalled'] as bool;
47 |
48 | if (isIntalled) {
49 | final versionCode = map['versionCode'] as int?;
50 | final versionName = map['versionName'] as String?;
51 |
52 | return ApklisInfo(
53 | isInstalled: isIntalled,
54 | versionCode: versionCode,
55 | versionName: versionName,
56 | );
57 | }
58 |
59 | return ApklisInfo(
60 | isInstalled: false,
61 | versionCode: null,
62 | versionName: null,
63 | );
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/cu/fluttercuba/apklis_payment_checker/ApklisPaymentCheckerPlugin.kt:
--------------------------------------------------------------------------------
1 | package cu.fluttercuba.apklis_payment_checker
2 |
3 | import android.content.Context
4 | import androidx.annotation.NonNull
5 | import io.flutter.embedding.engine.plugins.FlutterPlugin
6 | import io.flutter.plugin.common.MethodCall
7 | import io.flutter.plugin.common.MethodChannel
8 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler
9 | import io.flutter.plugin.common.MethodChannel.Result
10 |
11 | /** ApklisPaymentCheckerPlugin */
12 | class ApklisPaymentCheckerPlugin : FlutterPlugin, MethodCallHandler {
13 | /// The MethodChannel that will the communication between Flutter and native Android
14 | ///
15 | /// This local reference serves to register the plugin with the Flutter Engine and unregister it
16 | /// when the Flutter Engine is detached from the Activity
17 | private lateinit var channel: MethodChannel
18 | private lateinit var context: Context
19 |
20 | override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
21 | channel = MethodChannel(flutterPluginBinding.binaryMessenger, "apklis_payment_checker")
22 | channel.setMethodCallHandler(this)
23 | context = flutterPluginBinding.applicationContext
24 | }
25 |
26 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
27 | when (call.method) {
28 | "getPackageName" -> {
29 | val hashMap = HashMap()
30 | hashMap["packageName"] = context.packageName
31 | return result.success(hashMap)
32 | }
33 | "isPurchased" -> {
34 | val packageId = call.arguments()
35 | val response = packageId?.let { Verify.isPurchased(context, it) }
36 | val hashMap = HashMap()
37 | hashMap["paid"] = response?.first ?: false
38 | hashMap["username"] = response?.second
39 | return result.success(hashMap)
40 | }
41 | "getApklisInfo" -> {
42 | val response = Verify.getApklisInfo(context)
43 | val hashMap = HashMap()
44 | hashMap["isIntalled" ] = response.first
45 | hashMap["versionCode"] = response.second
46 | hashMap["versionName"] = response.third
47 | return result.success(hashMap)
48 | }
49 | else -> {
50 | result.notImplemented()
51 | }
52 | }
53 | }
54 |
55 | override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
56 | channel.setMethodCallHandler(null)
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: tests
2 | on: [push, pull_request, workflow_dispatch]
3 | jobs:
4 | tests:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - name: Setup Action
8 | uses: actions/checkout@v2
9 | - name: Setup Java
10 | uses: actions/setup-java@v1
11 | with:
12 | java-version: '12.x'
13 | - name: Setup Flutter
14 | uses: subosito/flutter-action@v1
15 | with:
16 | channel: 'stable'
17 | - name: Run Tests
18 | run: |
19 | flutter pub get
20 | flutter test
21 | - name: Run Analysis
22 | uses: axel-op/dart-package-analyzer@v3
23 | id: analysis
24 | with:
25 | githubToken: ${{ secrets.GITHUB_TOKEN }}
26 | - name: Check Scores
27 | env:
28 | TOTAL: ${{ steps.analysis.outputs.total }}
29 | TOTAL_MAX: ${{ steps.analysis.outputs.total_max }}
30 | CONVENTIONS: ${{ steps.analysis.outputs.conventions }}
31 | CONVENTIONS_MAX: ${{ steps.analysis.outputs.conventions_max }}
32 | DOCUMENTATION: ${{ steps.analysis.outputs.documentation }}
33 | DOCUMENTATION_MAX: ${{ steps.analysis.outputs.documentation_max }}
34 | PLATFORMS: ${{ steps.analysis.outputs.platforms }}
35 | PLATFORMS_MAX: ${{ steps.analysis.outputs.platforms_max }}
36 | ANALYSIS: ${{ steps.analysis.outputs.analysis }}
37 | ANALYSIS_MAX: ${{ steps.analysis.outputs.analysis_max }}
38 | DEPENDENCIES: ${{ steps.analysis.outputs.dependencies }}
39 | DEPENDENCIES_MAX: ${{ steps.analysis.outputs.dependencies_max }}
40 | NULL_SAFETY: ${{ steps.analysis.outputs.null_safety }}
41 | NULL_SAFETY_MAX: ${{ steps.analysis.outputs.null_safety_max }}
42 | run: |
43 | # if (( $TOTAL < $TOTAL_MAX ))
44 | # then
45 | # exit 1
46 | # fi
47 | if (( $CONVENTIONS < $CONVENTIONS_MAX ))
48 | then
49 | echo Fail conventions section
50 | exit 1
51 | fi
52 | if (( $DOCUMENTATION < $DOCUMENTATION_MAX ))
53 | then
54 | echo Fail documentation section
55 | exit 1
56 | fi
57 | # if (( $PLATFORMS < $PLATFORMS_MAX ))
58 | # then
59 | # echo Fail platforms section
60 | # exit 1
61 | # fi
62 | if (( $ANALYSIS < $ANALYSIS_MAX ))
63 | then
64 | echo Fail analysis section
65 | exit 1
66 | fi
67 | if (( $DEPENDENCIES < $DEPENDENCIES_MAX ))
68 | then
69 | echo Fail dependencies section
70 | exit 1
71 | fi
72 | if (( $NULL_SAFETY < $NULL_SAFETY_MAX ))
73 | then
74 | echo Fail null_safety section
75 | exit 1
76 | fi
77 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/cu/fluttercuba/apklis_payment_checker/Verify.kt:
--------------------------------------------------------------------------------
1 | package cu.fluttercuba.apklis_payment_checker
2 |
3 | import android.content.Context
4 | import android.content.pm.PackageManager
5 | import android.net.Uri
6 | import android.os.RemoteException
7 |
8 | // Code from https://github.com/Z17-CU/apklischeckpayment
9 | class Verify {
10 | companion object {
11 |
12 | private const val APKLIS_PROVIDER = "content://cu.uci.android.apklis.PaymentProvider/app/"
13 | private const val APKLIS_PAID = "paid"
14 | private const val APKLIS_USER_NAME = "user_name"
15 |
16 | fun isPurchased(context: Context, packageId: String): Pair {
17 | var paid = false
18 | var userName: String? = null
19 | val providerURI: Uri = Uri.parse("$APKLIS_PROVIDER$packageId")
20 | try {
21 | val contentResolver =
22 | context.contentResolver.acquireContentProviderClient(providerURI)
23 | val cursor = contentResolver?.query(providerURI, null, null, null, null)
24 | cursor?.let {
25 | if (it.moveToFirst()) {
26 | paid = it.getInt(it.getColumnIndexOrThrow(APKLIS_PAID)) > 0
27 | userName = it.getString(it.getColumnIndexOrThrow(APKLIS_USER_NAME))
28 | }
29 | }
30 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
31 | contentResolver?.close()
32 | } else {
33 | contentResolver?.release()
34 | }
35 | cursor?.close()
36 | } catch (e: RemoteException) {
37 | e.printStackTrace()
38 | } catch (e: IllegalArgumentException) {
39 | return Pair(false, null)
40 | }
41 | return Pair(paid, userName)
42 | }
43 |
44 | fun getApklisInfo(context: Context): Triple {
45 | var isInstaller: Boolean
46 | var versionCode: Int? = null
47 | var versionName: String? = null
48 |
49 | val packageManager: PackageManager = context.packageManager
50 | try {
51 | isInstaller = true
52 | val info = packageManager.getPackageInfo(
53 | "cu.uci.android.apklis",
54 | PackageManager.GET_ACTIVITIES
55 | )
56 | versionName = info.versionName
57 |
58 | versionCode = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
59 | info.longVersionCode.toInt()
60 | } else {
61 | info.versionCode
62 | }
63 |
64 | } catch (e: PackageManager.NameNotFoundException) {
65 | isInstaller = false
66 | }
67 |
68 | return Triple(isInstaller, versionCode, versionName)
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Apklis Payment Checker para Flutter
2 |
3 | [](https://opensource.org/licenses/MIT)
4 | [](https://pub.dev/packages/apklis_payment_checker)
5 | [](https://github.com/fluttercuba/apklis-payment-checker-flutter/actions?query=workflow%3Atests)
6 | [](https://github.com/fluttercuba/apklis-payment-checker-flutter/commits)
7 | [](https://github.com/fluttercuba/apklis-payment-checker-flutter/commits)
8 | [](https://github.com/fluttercuba/apklis-payment-checker-flutter/stargazers)
9 | [](https://github.com/fluttercuba/apklis-payment-checker-flutter/network/members)
10 | [](https://github.com/fluttercuba/apklis-payment-checker-flutter)
11 | [](https://github.com/fluttercuba/apklis-payment-checker-flutter/graphs/contributors)
12 | [](https://pub.dev/packages/lint)
13 |
14 | Plugin de Flutter para el chequeo de pagos de Apklis
15 |
16 | Disponible en Pub.dev:
17 |
18 | ## Instalación
19 |
20 | Añade el plugin a las dependencias de tu proyecto:
21 |
22 | ```yaml
23 | dependencies:
24 | apklis_payment_checker: ^1.0.0
25 | ```
26 |
27 | 🚧 Si tu app se orienta a Android 11 (nivel de API 30) o versiones posteriores debes agregar las siguientes líneas en el archivo `AndroidManifest.xml`:
28 |
29 | 1. Agrega el permiso ``:
30 |
31 | ```xml
32 |
33 |
34 |
35 |
36 | ...
37 |
38 | ```
39 |
40 | 2. Agrega la bandera `android:exported="true"` al `activity` de la aplicación:
41 |
42 | ```xml
43 | ...
44 |
48 | ...
49 | ```
50 |
51 | Ver el [archivo](https://github.com/fluttercuba/apklis-payment-checker-flutter/blob/main/example/android/app/src/main/AndroidManifest.xml) `AndroidManifest.xml` del ejemplo de este repositorio.
52 |
53 | ## Uso
54 |
55 | ```dart
56 | var status = await ApklisPaymentChecker.isPurchased();
57 | print(status.paid);
58 | print(status.username);
59 | ```
60 |
61 | Si se desea usar un nombre de paquete diferente al de la aplicación el método `isPurchased` puede recibirlo como parámetro:
62 |
63 | ```dart
64 | final packageId = 'com.example.nova.prosalud';
65 | var status = await ApklisPaymentChecker.isPurchased(packageId);
66 | print(status.paid);
67 | print(status.username);
68 | ```
69 |
70 | Para conocer información sobre Apklis:
71 |
72 | ```dart
73 | var apklisInfo = await ApklisPaymentChecker.getApklistInfo();
74 | print(apklisInfo.isInstalled);
75 | print(apklisInfo.versionName);
76 | print(apklisInfo.versionCode);
77 | ```
78 |
79 | Ejemplo completo disponible en:
80 |
--------------------------------------------------------------------------------
/test/apklis_payment_checker_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:apklis_payment_checker/apklis_info.dart';
2 | import 'package:apklis_payment_checker/apklis_payment_checker.dart';
3 | import 'package:apklis_payment_checker/apklis_payment_status.dart';
4 | import 'package:flutter/services.dart';
5 | import 'package:flutter_test/flutter_test.dart';
6 |
7 | void main() {
8 | const MethodChannel channel = MethodChannel('apklis_payment_checker');
9 |
10 | const packageId = 'com.example.nova.prosalud';
11 |
12 | TestWidgetsFlutterBinding.ensureInitialized();
13 |
14 | tearDown(() {
15 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
16 | .setMockMethodCallHandler(channel, null);
17 | });
18 |
19 | test('channel have one instance', () {
20 | expect(channel, equals(const MethodChannel('apklis_payment_checker')));
21 | });
22 | // TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
23 | test('getPackageName', () async {
24 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
25 | .setMockMethodCallHandler(
26 | channel,
27 | (MethodCall methodCall) async {
28 | return {
29 | 'packageName': packageId,
30 | };
31 | },
32 | );
33 |
34 | final packageName = await ApklisPaymentChecker.getPackageName();
35 |
36 | expect(packageName, equals(packageId));
37 | });
38 |
39 | group('check isPunchased', () {
40 | test('when the packageId parameter is null and the app is not paid',
41 | () async {
42 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
43 | .setMockMethodCallHandler(
44 | channel,
45 | (MethodCall methodCall) async {
46 | if (methodCall.method == 'getPackageName') {
47 | return {
48 | 'packageName': packageId,
49 | };
50 | }
51 | return {
52 | 'paid': false,
53 | 'username': null,
54 | };
55 | },
56 | );
57 |
58 | final status = await ApklisPaymentChecker.isPurchased();
59 |
60 | expect(
61 | status,
62 | equals(ApklisPaymentStatus(paid: false, username: null)),
63 | );
64 | });
65 |
66 | test('when the app is not paid', () async {
67 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
68 | .setMockMethodCallHandler(
69 | channel,
70 | (MethodCall methodCall) async {
71 | return {
72 | 'paid': false,
73 | 'username': null,
74 | };
75 | },
76 | );
77 |
78 | final status = await ApklisPaymentChecker.isPurchased(packageId);
79 |
80 | expect(
81 | status,
82 | equals(ApklisPaymentStatus(paid: false, username: null)),
83 | );
84 | });
85 |
86 | test('when channel return null', () async {
87 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
88 | .setMockMethodCallHandler(
89 | channel,
90 | (MethodCall methodCall) async {
91 | return null;
92 | },
93 | );
94 |
95 | final status = await ApklisPaymentChecker.isPurchased(packageId);
96 |
97 | expect(
98 | status,
99 | equals(ApklisPaymentStatus(paid: false, username: null)),
100 | );
101 | });
102 |
103 | test('when the app is paid', () async {
104 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
105 | .setMockMethodCallHandler(
106 | channel,
107 | (MethodCall methodCall) async {
108 | return {
109 | 'paid': true,
110 | 'username': 'example',
111 | };
112 | },
113 | );
114 |
115 | final status = await ApklisPaymentChecker.isPurchased(packageId);
116 |
117 | expect(
118 | status,
119 | equals(ApklisPaymentStatus(paid: true, username: 'example')),
120 | );
121 | });
122 | });
123 |
124 | group('getApklisInfo', () {
125 | test('when the Apklis app is not intalled', () async {
126 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
127 | .setMockMethodCallHandler(
128 | channel,
129 | (MethodCall methodCall) async {
130 | return {
131 | 'isIntalled': false,
132 | 'versionCode': null,
133 | 'versionName': null,
134 | };
135 | },
136 | );
137 |
138 | final info = await ApklisPaymentChecker.getApklisInfo();
139 |
140 | expect(
141 | info,
142 | equals(
143 | ApklisInfo(
144 | isInstalled: false,
145 | versionCode: null,
146 | versionName: null,
147 | ),
148 | ),
149 | );
150 | });
151 |
152 | test('when the Apklis app is installed but no user is logged in', () async {
153 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
154 | .setMockMethodCallHandler(
155 | channel,
156 | (MethodCall methodCall) async {
157 | return {
158 | 'isIntalled': true,
159 | 'versionCode': null,
160 | 'versionName': null,
161 | };
162 | },
163 | );
164 |
165 | final info = await ApklisPaymentChecker.getApklisInfo();
166 |
167 | expect(
168 | info,
169 | equals(
170 | ApklisInfo(
171 | isInstalled: true,
172 | versionCode: null,
173 | versionName: null,
174 | ),
175 | ),
176 | );
177 | });
178 | });
179 | }
180 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 |
2 | # Código de Conducta convenido para Contribuyentes
3 |
4 | ## Nuestro compromiso
5 |
6 | Nosotros, como miembros, contribuyentes y administradores nos comprometemos a hacer de la participación en nuestra comunidad una experiencia libre de acoso para todo el mundo, independientemente de la edad, dimensión corporal, minusvalía visible o invisible, etnicidad, características sexuales, identidad y expresión de género, nivel de experiencia, educación, nivel socio-económico, nacionalidad, apariencia personal, raza, religión, o identidad u orientación sexual.
7 |
8 | Nos comprometemos a actuar e interactuar de maneras que contribuyan a una comunidad abierta, acogedora, diversa, inclusiva y sana.
9 |
10 | ## Nuestros estándares
11 |
12 | Ejemplos de comportamiento que contribuyen a crear un ambiente positivo para nuestra comunidad:
13 |
14 | * Demostrar empatía y amabilidad ante otras personas
15 | * Respeto a diferentes opiniones, puntos de vista y experiencias
16 | * Dar y aceptar adecuadamente retroalimentación constructiva
17 | * Aceptar la responsabilidad y disculparse ante quienes se vean afectados por nuestros errores, aprendiendo de la experiencia
18 | * Centrarse en lo que sea mejor no sólo para nosotros como individuos, sino para la comunidad en general
19 |
20 | Ejemplos de comportamiento inaceptable:
21 |
22 | * El uso de lenguaje o imágenes sexualizadas, y aproximaciones o
23 | atenciones sexuales de cualquier tipo
24 | * Comentarios despectivos (_trolling_), insultantes o derogatorios, y ataques personales o políticos
25 | * El acoso en público o privado
26 | * Publicar información privada de otras personas, tales como direcciones físicas o de correo
27 | electrónico, sin su permiso explícito
28 | * Otras conductas que puedan ser razonablemente consideradas como inapropiadas en un
29 | entorno profesional
30 |
31 | ## Aplicación de las responsabilidades
32 |
33 | Los administradores de la comunidad son responsables de aclarar y hacer cumplir nuestros estándares de comportamiento aceptable y tomarán acciones apropiadas y correctivas de forma justa en respuesta a cualquier comportamiento que consideren inapropiado, amenazante, ofensivo o dañino.
34 |
35 | Los administradores de la comunidad tendrán el derecho y la responsabilidad de eliminar, editar o rechazar comentarios, _commits_, código, ediciones de páginas de wiki, _issues_ y otras contribuciones que no se alineen con este Código de Conducta, y comunicarán las razones para sus decisiones de moderación cuando sea apropiado.
36 |
37 | ## Alcance
38 |
39 | Este código de conducta aplica tanto a espacios del proyecto como a espacios públicos donde un individuo esté en representación del proyecto o comunidad. Ejemplos de esto incluyen el uso de la cuenta oficial de correo electrónico, publicaciones a través de las redes sociales oficiales, o presentaciones con personas designadas en eventos en línea o no.
40 |
41 | ## Aplicación
42 |
43 | Instancias de comportamiento abusivo, acosador o inaceptable de otro modo podrán ser reportadas a los administradores de la comunidad responsables del cumplimiento a través de [INSERTAR MÉTODO DE CONTACTO]. Todas las quejas serán evaluadas e investigadas de una manera puntual y justa.
44 |
45 | Todos los administradores de la comunidad están obligados a respetar la privacidad y la seguridad de quienes reporten incidentes.
46 |
47 | ## Guías de Aplicación
48 |
49 | Los administradores de la comunidad seguirán estas Guías de Impacto en la Comunidad para determinar las consecuencias de cualquier acción que juzguen como un incumplimiento de este Código de Conducta:
50 |
51 | ### 1. Corrección
52 |
53 | **Impacto en la Comunidad**: El uso de lenguaje inapropiado u otro comportamiento considerado no profesional o no acogedor en la comunidad.
54 |
55 | **Consecuencia**: Un aviso escrito y privado por parte de los administradores de la comunidad, proporcionando claridad alrededor de la naturaleza de este incumplimiento y una explicación de por qué el comportamiento es inaceptable. Una disculpa pública podría ser solicitada.
56 |
57 | ### 2. Aviso
58 |
59 | **Impacto en la Comunidad**: Un incumplimiento causado por un único incidente o por una cadena de acciones.
60 |
61 | **Consecuencia**: Un aviso con consecuencias por comportamiento prolongado. No se interactúa con las personas involucradas, incluyendo interacción no solicitada con quienes se encuentran aplicando el Código de Conducta, por un periodo especificado de tiempo. Esto incluye evitar las interacciones en espacios de la comunidad, así como a través de canales externos como las redes sociales. Incumplir estos términos puede conducir a una expulsión temporal o permanente.
62 |
63 | ### 3. Expulsión temporal
64 |
65 | **Impacto en la Comunidad**: Una serie de incumplimientos de los estándares de la comunidad, incluyendo comportamiento inapropiado continuo.
66 |
67 | **Consecuencia**: Una expulsión temporal de cualquier forma de interacción o comunicación pública con la comunidad durante un intervalo de tiempo especificado. No se permite interactuar de manera pública o privada con las personas involucradas, incluyendo interacciones no solicitadas con quienes se encuentran aplicando el Código de Conducta, durante este periodo. Incumplir estos términos puede conducir a una expulsión permanente.
68 |
69 | ### 4. Expulsión permanente
70 |
71 | **Impacto en la Comunidad**: Demostrar un patrón sistemático de incumplimientos de los estándares de la comunidad, incluyendo conductas inapropiadas prolongadas en el tiempo, acoso de individuos, o agresiones o menosprecio a grupos de individuos.
72 |
73 | **Consecuencia**: Una expulsión permanente de cualquier tipo de interacción pública con la comunidad del proyecto.
74 |
75 | ## Atribución
76 |
77 | Este Código de Conducta es una adaptación del [Contributor Covenant][homepage], versión 2.0,
78 | disponible en https://www.contributor-covenant.org/es/version/2/0/code_of_conduct.html
79 |
80 | Las Guías de Impacto en la Comunidad están inspiradas en la [escalera de aplicación del código de conducta de Mozilla](https://github.com/mozilla/diversity).
81 |
82 | [homepage]: https://www.contributor-covenant.org
83 |
84 | Para respuestas a las preguntas frecuentes de este código de conducta, consulta las FAQ en
85 | https://www.contributor-covenant.org/faq. Hay traducciones disponibles en https://www.contributor-covenant.org/translations
86 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:developer';
3 |
4 | import 'package:apklis_payment_checker/apklis_info.dart';
5 | import 'package:apklis_payment_checker/apklis_payment_checker.dart';
6 | import 'package:apklis_payment_checker/apklis_payment_status.dart';
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/services.dart';
9 |
10 | void main() {
11 | runApp(ExampleApp());
12 | }
13 |
14 | class ExampleApp extends StatefulWidget {
15 | @override
16 | ExampleAppState createState() => ExampleAppState();
17 | }
18 |
19 | class ExampleAppState extends State {
20 | final keyForm = GlobalKey();
21 | final controller = TextEditingController();
22 | ApklisPaymentStatus? status;
23 | ApklisInfo? apklisInfo;
24 |
25 | @override
26 | void initState() {
27 | super.initState();
28 | setPackageName();
29 | }
30 |
31 | @override
32 | void dispose() {
33 | controller.dispose();
34 | super.dispose();
35 | }
36 |
37 | Future setPackageName() async {
38 | try {
39 | final packageName = await ApklisPaymentChecker.getPackageName();
40 | setState(() => controller.text = packageName);
41 | } on PlatformException catch (e) {
42 | log(e.toString());
43 | }
44 | }
45 |
46 | Future requestPaymentStatus(String packageId) async {
47 | try {
48 | final status = await ApklisPaymentChecker.isPurchased(packageId);
49 | setState(() => this.status = status);
50 | } on PlatformException catch (e) {
51 | log(e.toString());
52 | }
53 | }
54 |
55 | Future getApklisInfo() async {
56 | final apklisInfo = await ApklisPaymentChecker.getApklisInfo();
57 | setState(() => this.apklisInfo = apklisInfo);
58 | }
59 |
60 | @override
61 | Widget build(BuildContext context) {
62 | return MaterialApp(
63 | home: Scaffold(
64 | appBar: AppBar(
65 | centerTitle: true,
66 | title: const Text('Apklis Payment Checker'),
67 | ),
68 | body: Form(
69 | key: keyForm,
70 | autovalidateMode: AutovalidateMode.always,
71 | child: Column(
72 | children: [
73 | Container(
74 | margin:
75 | const EdgeInsets.symmetric(vertical: 15, horizontal: 10),
76 | child: Row(
77 | children: [
78 | Expanded(
79 | child: TextFormField(
80 | controller: controller,
81 | decoration: const InputDecoration(
82 | border: OutlineInputBorder(
83 | borderRadius: BorderRadius.all(
84 | Radius.circular(10.0),
85 | ),
86 | ),
87 | labelText: 'Package Id',
88 | hintText: 'com.example.nova.prosalud',
89 | ),
90 | keyboardType: TextInputType.text,
91 | validator: (value) {
92 | if (value == null || value.isEmpty) {
93 | return 'Is required';
94 | }
95 | return null;
96 | },
97 | ),
98 | ),
99 | ],
100 | ),
101 | ),
102 | if (status != null && apklisInfo != null)
103 | Column(
104 | children: [
105 | Container(
106 | margin: const EdgeInsets.all(5),
107 | child: const Text('Apklis is installed:'),
108 | ),
109 | Container(
110 | margin: const EdgeInsets.all(5),
111 | child: Text(
112 | apklisInfo?.isInstalled.toString() ?? 'false',
113 | style: const TextStyle(
114 | fontWeight: FontWeight.bold,
115 | fontSize: 20,
116 | ),
117 | ),
118 | ),
119 | if (apklisInfo?.isInstalled ?? false)
120 | Column(
121 | children: [
122 | Container(
123 | margin: const EdgeInsets.all(5),
124 | child: const Text('Apklis version code:'),
125 | ),
126 | Container(
127 | margin: const EdgeInsets.all(5),
128 | child: Text(
129 | apklisInfo?.versionCode.toString() ?? '',
130 | style: const TextStyle(
131 | fontWeight: FontWeight.bold,
132 | fontSize: 20,
133 | ),
134 | ),
135 | ),
136 | Container(
137 | margin: const EdgeInsets.all(5),
138 | child: const Text('Apklis version name:'),
139 | ),
140 | Container(
141 | margin: const EdgeInsets.all(5),
142 | child: Text(
143 | apklisInfo?.versionName ?? 'Unknown',
144 | style: const TextStyle(
145 | fontWeight: FontWeight.bold,
146 | fontSize: 20,
147 | ),
148 | ),
149 | ),
150 | Container(
151 | margin: const EdgeInsets.all(5),
152 | child: const Text('Username registered in Apklis:'),
153 | ),
154 | Container(
155 | margin: const EdgeInsets.all(5),
156 | child: Text(
157 | status?.username ?? 'Unknow',
158 | style: const TextStyle(
159 | fontWeight: FontWeight.bold,
160 | fontSize: 20,
161 | ),
162 | ),
163 | ),
164 | Container(
165 | margin: const EdgeInsets.all(5),
166 | child: const Text('App payment status:'),
167 | ),
168 | Container(
169 | margin: const EdgeInsets.all(5),
170 | child: Text(
171 | status?.paid.toString() ?? 'Unknow',
172 | style: const TextStyle(
173 | fontWeight: FontWeight.bold,
174 | fontSize: 20,
175 | ),
176 | ),
177 | ),
178 | ],
179 | ),
180 | ],
181 | ),
182 | ],
183 | ),
184 | ),
185 | floatingActionButton: FloatingActionButton(
186 | child: const Icon(Icons.search),
187 | onPressed: () {
188 | if (keyForm.currentState?.validate() ?? false) {
189 | final packageId = controller.text.trim();
190 | requestPaymentStatus(packageId);
191 | getApklisInfo();
192 | }
193 | },
194 | ),
195 | ),
196 | );
197 | }
198 | }
199 |
--------------------------------------------------------------------------------