
Facilitates extraction of comprehensive Google Play Store app data, including descriptions, developer info, categories, reviews, and metadata, using JSON parsing and HTTP requests.
StoreKit is a comprehensive Kotlin multiplatform library for extracting detailed information about applications from various Android app stores. Currently, it supports:
With this library, you can fetch details such as application descriptions, developer information, categories, reviews, ratings, and more from multiple app stores using a consistent API.
This library is built using Kotlin Multiplatform and leverages kotlinx.serialization for parsing JSON data and Ktor for HTTP requests.
The Google Play modules are available on Maven Central:
For scraping data from the Google Play Store:
dependencies {
implementation("io.github.kdroidfilter:storekit-gplay-scrapper:<version>")
}If you only need the model classes (like GooglePlayApplicationInfo and GooglePlayCategory) without the scraping functionality:
dependencies {
implementation("io.github.kdroidfilter:storekit-gplay-core:<version>")
}To fetch detailed information about a specific app from Google Play, you can use the getGooglePlayApplicationInfo function. This function requires the app ID as a parameter and optionally takes the language and country codes.
appId: String (mandatory): The unique identifier of the app.lang: String (optional, default = "en"): Language code for the app details (ISO 639-1).country: String (optional, default = "us"): Country code for the app details (ISO 3166).fun main() {
val json = Json {
prettyPrint = true
ignoreUnknownKeys = true
encodeDefaults = true
}
runBlocking {
val appId = "com.android.chrome"
val appInfo = getGooglePlayApplicationInfo(appId)
println(json.encodeToString(appInfo))
}
}The GooglePlayApplicationInfo class is a comprehensive data model that represents detailed information about an application on the Google Play Store. It contains the following fields:
title: String - The title/name of the applicationdescription: String - Plain text description of the applicationdescriptionHTML: String - HTML-formatted description of the applicationsummary: String - A short summary of the applicationinstalls: String - Number of installs as a formatted string (e.g., "10,000,000+")minInstalls: Long - Minimum number of installs as a numeric valuerealInstalls: Long - Estimated real number of installsscore: Double - Overall rating score (0.0 to 5.0)ratings: Long - Total number of ratingsreviews: Long - Total number of reviewshistogram: List<Long> - Distribution of ratings (1-5 stars)price: Double - Price of the application in the specified currencyfree: Boolean - Whether the application is freecurrency: String - Currency code for the price (e.g., "USD")sale: Boolean - Whether the application is on salesaleTime: Long? - Duration of the sale in millisecondsoriginalPrice: Double? - Original price before the salesaleText: String? - Text describing the saleoffersIAP: Boolean - Whether the application offers in-app purchasesinAppProductPrice: String - Price range for in-app purchasesdeveloper: String - Name of the developerdeveloperId: String - Unique identifier of the developerdeveloperEmail: String - Contact email of the developerdeveloperWebsite: String - Website of the developerdeveloperAddress: String - Physical address of the developerprivacyPolicy: String - URL to the privacy policygenre: String - Primary genre of the applicationgenreId: String - Identifier of the primary genrecategories: List<GooglePlayCategory> - List of categories the application belongs toicon: String - URL to the application iconheaderImage: String - URL to the header imagescreenshots: List<String> - URLs to the application screenshotsvideo: String - URL to the promotional videovideoImage: String - URL to the video thumbnailcontentRating: String - Content rating (e.g., "Everyone", "Teen")contentRatingDescription: String - Description of the content ratingadSupported: Boolean - Whether the application is supported by adscontainsAds: Boolean - Whether the application contains adsreleased: String - Release date of the applicationupdated: Long - Last update timestampversion: String - Current version of the applicationcomments: List<String> - List of user commentsappId: String - Unique identifier of the applicationurl: String - URL to the application's page on Google PlayThe GooglePlayCategory class represents a category on the Google Play Store with the following fields:
name: String - Name of the categoryid: String - Unique identifier of the categoryThe F-Droid modules are available on Maven Central:
For accessing the F-Droid API:
dependencies {
implementation("io.github.kdroidfilter:storekit-fdroid-api:<version>")
}If you only need the model classes (like FDroidPackageInfo) without the API client:
dependencies {
implementation("io.github.kdroidfilter:storekit-fdroid-core:<version>")
}To fetch detailed information about a specific package from F-Droid, you can use the FDroidService class. The class provides a method to retrieve package information using the package name.
Fetches package information using the package name.
Parameters:
packageName: String (mandatory): The package name of the application.Returns: An instance of FDroidPackageInfo containing the package information.
Throws: IllegalArgumentException if the package with the given package name does not exist or is not accessible.
fun main() {
val json = Json {
prettyPrint = true
encodeDefaults = true
}
runBlocking {
try {
val fdroidService = FDroidService()
// Fetch package information by package name
val packageInfo = fdroidService.getPackageInfo("net.thunderbird.android")
println(json.encodeToString(packageInfo))
// Get download link for the suggested version
val downloadLink = packageInfo.getSuggestedVersionDownloadLink()
println("Download link: $downloadLink")
} catch (e: Exception) {
println("Error fetching package information: ${e.message}")
e.printStackTrace()
}
}
}The FDroidPackageInfo class represents detailed information about a package on the F-Droid store. It contains the following fields:
packageName: String - The package name of the applicationsuggestedVersionCode: Long - The suggested version code of the applicationpackages: List<FDroidPackageVersion> - List of available package versionsgetDownloadLink(versionCode: Long): String? - Gets the download link for the package with the specified version code. Returns null if the version code doesn't exist in the packages list.getSuggestedVersionDownloadLink(): String? - Gets the download link for the suggested version of the package. Returns null if the suggested version doesn't exist in the packages list.The FDroidPackageVersion class represents a version of a package in F-Droid with the following fields:
versionName: String - The version name of the package (e.g., "1.9")versionCode: Long - The version code of the package (e.g., 1009000)The Aptoide modules are available on Maven Central:
For accessing the Aptoide API:
dependencies {
implementation("io.github.kdroidfilter:storekit-aptoide-api:<version>")
}If you only need the model classes (like AptoideApplicationInfo) without the API client:
dependencies {
implementation("io.github.kdroidfilter:storekit-aptoide-core:<version>")
}To fetch detailed information about a specific app from Aptoide, you can use the AptoideService class. The class provides several methods to retrieve app information using different identifiers.
Fetches application metadata using the package name.
Parameters:
packageName: String (mandatory): The package name of the application.language: String (optional, default = "en"): Language code for the content localization.Returns: An instance of AptoideApplicationInfo containing the application's metadata.
Fetches application metadata using the app ID.
Parameters:
appId: Long (mandatory): The ID of the application.language: String (optional, default = "en"): Language code for the content localization.Returns: An instance of AptoideApplicationInfo containing the application's metadata.
Fetches application metadata using the APK MD5 sum.
Parameters:
md5sum: String (mandatory): The MD5 sum of the APK file.language: String (optional, default = "en"): Language code for the content localization.Returns: An instance of AptoideApplicationInfo containing the application's metadata.
fun main() {
val json = Json { prettyPrint = true }
val aptoideService = AptoideService()
runBlocking {
try {
// Fetch app metadata by package name
val appInfo = aptoideService.getAppMetaByPackageName("com.waze", "en")
println(json.encodeToString(appInfo))
// Fetch app metadata by app ID
val appInfoById = aptoideService.getAppMetaById(12345, "en")
println(json.encodeToString(appInfoById))
// Fetch app metadata by APK MD5 sum
val appInfoByMd5 = aptoideService.getAppMetaByMd5sum("abcdef1234567890abcdef1234567890", "en")
println(json.encodeToString(appInfoByMd5))
} catch (e: Exception) {
println("Error fetching app metadata: ${e.message}")
e.printStackTrace()
}
}
}The AptoideApplicationInfo class is a comprehensive data model that represents detailed information about an application on the Aptoide store. It contains the following fields:
id: Long - Unique identifier of the applicationname: String - Name of the applicationpackageName: String - Package name of the applicationuname: String - Unique name of the applicationsize: Long - Size of the application in bytesicon: String - URL to the application icongraphic: String - URL to the application graphicadded: String - Date when the application was addedmodified: String - Date when the application was last modifiedupdated: String - Date when the application was last updatedmain_package: String? - Main package name if differentage: AptoideAge - Age rating informationdeveloper: AptoideDeveloper - Developer informationstore: AptoideStore - Store informationfile: AptoideFile - File informationmedia: AptoideMedia - Media assetsurls: AptoideUrls - URLs related to the applicationstats: AptoideStats - Statistics about the applicationaab: String? - Android App Bundle informationobb: String? - OBB file informationpay: String? - Payment informationappcoins: AptoideAppcoins - AppCoins informationsoft_locks: List<String> - Soft locks informationThe AptoideAge class contains age rating information with the following fields:
name: String - Name of the age ratingtitle: String - Title of the age ratingpegi: String - PEGI ratingrating: Int - Numeric ratingThe AptoideDeveloper class contains information about the developer with the following fields:
id: Long - Unique identifier of the developername: String - Name of the developerwebsite: String - Website of the developeremail: String - Email of the developerprivacy: String? - Privacy policy URLThe AptoideStore class contains information about the store with the following fields:
id: Long - Unique identifier of the storename: String - Name of the storeavatar: String - URL to the store avatarappearance: AptoideAppearance - Appearance informationstats: AptoideStoreStats - Statistics about the storeThe AptoideAppearance class contains information about the store appearance with the following fields:
theme: String - Theme of the storedescription: String - Description of the storeThe AptoideStoreStats class contains statistics about the store with the following fields:
apps: Int - Number of applications in the storesubscribers: Int - Number of subscribers to the storedownloads: Int - Number of downloads from the storeThe AptoideFile class contains information about the application file with the following fields:
vername: String - Version namevercode: Int - Version codemd5sum: String - MD5 checksumfilesize: Long - File size in bytessignature: AptoideSignature - Signature informationadded: String - Date when the file was addedpath: String - Path to the filepath_alt: String - Alternative path to the filehardware: AptoideHardware - Hardware requirementsmalware: AptoideMalware - Malware scanning informationflags: AptoideFlags - Flags informationused_features: List<String> - List of used featuresused_permissions: List<String> - List of used permissionstags: List<String> - List of tagsThe AptoideSignature class contains signature information with the following fields:
sha1: String - SHA1 hash of the signatureowner: String - Owner of the signaturetoFormattedSha1() - Converts the SHA1 signature format from "XX:XX:XX..." to a continuous lowercase hex string.
Example: "35:B4:38:FE:1B:C6:9D:97:5D:C8:70:2D:C1:6A:B6:9E:BF:65:F2:6F" becomes "35b438fe1bc69d975dc8702dc16ab69ebf65f26f"The AptoideHardware class contains hardware requirements with the following fields:
sdk: Int - Minimum SDK versionscreen: String - Screen requirementsgles: Int - OpenGL ES versioncpus: List<String> - Supported CPUsdensities: List<String> - Supported screen densitiesdependencies: List<AptoideDependency> - List of dependenciesThe AptoideDependency class contains dependency information with the following fields:
type: String - Type of dependencylevel: String - Level of dependencyThe AptoideMalware class contains malware scanning information with the following fields:
rank: String - Malware rankreason: AptoideMalwareReason - Reason for the malware rankadded: String - Date when the malware scan was addedmodified: String - Date when the malware scan was modifiedThe AptoideMalwareReason class contains the reason for the malware rank with the following fields:
signature_validated: AptoideSignatureValidated - Signature validation informationThe AptoideSignatureValidated class contains signature validation information with the following fields:
date: String - Date of validationstatus: String - Status of validationsignature_from: String - Source of the signatureThe AptoideFlags class contains flags information with the following fields:
votes: List<AptoideVote> - List of votesThe AptoideVote class contains vote information with the following fields:
type: String - Type of votecount: Int - Number of votesThe AptoideMedia class contains media assets with the following fields:
keywords: List<String> - List of keywordsdescription: String - Description of the applicationsummary: String - Summary of the applicationnews: String - News about the applicationvideos: List<AptoideVideo> - List of videosscreenshots: List<AptoideScreenshot> - List of screenshotsThe AptoideVideo class contains video information with the following fields:
type: String - Type of videourl: String - URL to the videoThe AptoideScreenshot class contains screenshot information with the following fields:
url: String - URL to the screenshotheight: Int - Height of the screenshotwidth: Int - Width of the screenshotThe AptoideUrls class contains URLs related to the application with the following fields:
w: String - Web URLm: String - Mobile URLThe AptoideStats class contains statistics about the application with the following fields:
rating: AptoideRating - Rating informationprating: AptoideRating - Previous rating informationdownloads: Int - Number of downloadspdownloads: Int - Previous number of downloadsThe AptoideRating class contains rating information with the following fields:
avg: Double - Average ratingtotal: Int - Total number of ratingsvotes: List<AptoideRatingVote> - List of votesThe AptoideRatingVote class contains rating vote information with the following fields:
value: Int - Rating valuecount: Int - Number of votesThe AptoideAppcoins class contains AppCoins information with the following fields:
advertising: Boolean - Whether the application supports AppCoins advertisingbilling: Boolean - Whether the application supports AppCoins billingflags: List<String> - List of AppCoins flagsThe AptoideResponse class is the top-level response from the Aptoide API with the following fields:
info: AptoideInfo - Information about the responsedata: AptoideApplicationInfo - Application informationThe AptoideInfo class contains information about the response with the following fields:
status: String - Status of the responsetime: AptoideTime - Time informationThe AptoideTime class contains time information with the following fields:
seconds: Double - Time in secondshuman: String - Human-readable timeThe APKCombo modules are available on Maven Central:
For scraping data from the APKCombo website:
dependencies {
implementation("io.github.kdroidfilter:storekit-apkcombo-scraper:<version>")
}If you only need the model classes (like ApkComboApplicationInfo) without the scraping functionality:
dependencies {
implementation("io.github.kdroidfilter:storekit-apkcombo-core:<version>")
}To fetch detailed information about a specific app from APKCombo, you can use the getApkComboApplicationInfo function. This function requires the package name as a parameter.
packageName: String (mandatory): The package name of the application.An instance of ApkComboApplicationInfo containing the application's information.
IllegalArgumentException if the application with the given package name does not exist or is not accessible.
fun main() {
val json = Json {
prettyPrint = true
}
runBlocking {
try {
// Fetch app information by package name
val appInfo = getApkComboApplicationInfo("com.google.android.gm")
println(json.encodeToString(appInfo))
// Get direct download link
println("Download link: ${appInfo.downloadLink}")
} catch (e: Exception) {
println("Error fetching app information: ${e.message}")
e.printStackTrace()
}
}
}The ApkComboApplicationInfo class represents detailed information about an application on the APKCombo website. It contains the following fields:
title: String - The title/name of the applicationversion: String - Current version of the applicationversionCode: String - Version code of the applicationdownloadLink: String - Direct download link for the APKappId: String - Unique identifier of the application (package name)url: String - URL to the application's page on APKComboThe APK Link Resolver module provides a unified way to retrieve APK download links from multiple sources (APKPure, APKCombo, Aptoide, and F-Droid) with configurable priority.
Neither Aptoide, APKCombo, nor F-Droid can guarantee obtaining an APK link for every application. This module solves this problem by providing a simple way to check one source first, and if the APK is not found there, automatically check the next source. This approach significantly increases the chances of successfully retrieving an APK download link without requiring you to implement fallback logic in your application.
The APK Link Resolver module is available on Maven Central:
dependencies {
implementation("io.github.kdroidfilter:storekit-apklinkresolver-core:<version>")
}You can configure the priority order of APK sources using the ApkSourcePriority singleton:
// Exemple: essayer d'abord APKPure, puis APKCombo, puis F-Droid (les autres sources non précisées seront ajoutées à la fin dans l'ordre par défaut)
ApkSourcePriority.setPriorityOrder(listOf(ApkSource.APKPURE, ApkSource.APKCOMBO, ApkSource.FDROID))
// Get the current priority order
val currentPriority = ApkSourcePriority.getPriorityOrder()
println("Current priority: $currentPriority")
// Réinitialiser l'ordre par défaut (APKPure, APKCombo, FDroid, Aptoide)
ApkSourcePriority.resetToDefault()To retrieve an APK download link for a specific package, use the ApkLinkResolverService:
fun main() {
runBlocking {
try {
val service = ApkLinkResolverService()
// Get download link for a package
val downloadInfo = service.getApkDownloadLink("com.google.android.gm")
println("Download link: ${downloadInfo.downloadLink}")
println("Source: ${downloadInfo.source}")
println("Version: ${downloadInfo.version}")
println("Title: ${downloadInfo.title}")
println("File size: ${downloadInfo.fileSize} bytes")
} catch (e: Exception) {
println("Error retrieving download link: ${e.message}")
e.printStackTrace()
}
}
}The service will try to retrieve the download link from each source in the order specified by the ApkSourcePriority configuration. You can specify a partial priority list; any unspecified sources are appended automatically in the default order (by default: APKPURE, APKCOMBO, FDROID, APTOIDE). If a source fails, it will try the next one. If all sources fail, it will throw an IllegalArgumentException with details about the failures.
The ApkSource enum represents the available APK sources:
APKPURE - The APKPure websiteAPKCOMBO - The APKCombo websiteAPTOIDE - The Aptoide storeFDROID - The F-Droid storeThe ApkLinkInfo class represents information about an APK download with the following fields:
packageName: String - The package name of the applicationdownloadLink: String - The direct download link for the APKsource: String - The source of the download link (e.g., "APKPURE", "APKCOMBO", "APTOIDE", "FDROID")version: String - The version of the application (if available)versionCode: String - The version code of the application (if available)title: String - The title/name of the application (if available)fileSize: Long - The size of the APK file in bytes, or -1 if the size could not be determinedThe APKPure modules are available on Maven Central:
For scraping data from the APKPure website:
dependencies {
implementation("io.github.kdroidfilter:storekit-apkpure-api:<version>")
}If you only need the model classes (like ApkPureApplicationInfo) without the scraping functionality:
dependencies {
implementation("io.github.kdroidfilter:storekit-apkpure-core:<version>")
}To fetch application info (title, version, versionCode, signature, and a direct XAPK download link with version=latest) use getApkPureApplicationInfo:
fun main() {
val json = Json {
prettyPrint = true
encodeDefaults = true
}
runBlocking {
try {
val app = getApkPureApplicationInfo("com.waze")
println(json.encodeToString(app))
// The download link uses: https://d.apkpure.com/b/XAPK/<package>?version=latest
println("Direct link: ${'$'}{app.downloadLink}")
println("Signature: ${'$'}{app.signature}")
println("VersionCode: ${'$'}{app.versionCode}")
} catch (e: Exception) {
println("Error: ${'$'}{e.message}")
}
}
}title: Stringversion: StringversionCode: Stringsignature: StringdownloadLink: String (always uses version=latest)appId: Stringurl: StringThe App Authenticity module is available on Maven Central:
dependencies {
implementation("io.github.kdroidfilter:storekit-authenticity:<version>")
}To extract the SHA1 signature of an installed Android application, you can use the SignatureExtractor class:
// In your Android activity or fragment
fun extractSignature(context: Context) {
val packageName = "com.example.app" // Package name of the app
// Extract the SHA1 signature
val signature = SignatureExtractor.extractSha1Signature(context, packageName)
// Use the signature
if (signature != null) {
println("SHA1 Signature: $signature")
} else {
println("Failed to extract signature. App might not be installed.")
}
}Parameters:
context: The Android context.packageName: The package name of the application.Returns: The SHA1 signature of the application as a string, or null if the application is not installed or the signature cannot be extracted.
To validate if a string is a valid SHA1 signature, you can use the isValidSha1Signature function:
fun validateSignature() {
val sha1String = "38918a453d07199354f8b19af05ec6562ced5788" // Example SHA1 signature
// Validate the SHA1 signature
val isValid = SignatureExtractor.isValidSha1Signature(sha1String)
if (isValid) {
println("The signature is a valid SHA1 signature")
} else {
println("The signature is not a valid SHA1 signature")
}
}Parameters:
sha1String: The SHA1 string to verify.Returns: True if the string is a valid SHA1 signature (40 characters long and contains only hexadecimal digits), false otherwise.
To verify if an installed app's signature matches an expected SHA1 signature, you can use the verifyPackageSignature function. This function already validates the SHA1 signature internally, so you don't need to call isValidSha1Signature separately:
fun verifyAppSignature(context: Context) {
val packageName = "com.android.chrome" // Package name of the app
val expectedSignature = "38918a453d07199354f8b19af05ec6562ced5788" // Expected SHA1 signature
// Verify the app's signature
val isSignatureValid = SignatureExtractor.verifyPackageSignature(context, packageName, expectedSignature)
if (isSignatureValid) {
println("The app's signature matches the expected signature")
} else {
println("The app's signature does not match the expected signature, or the app is not installed")
}
}Parameters:
context: The Android context.packageName: The package name of the application to verify.expectedSha1: The expected SHA1 signature to compare against.Returns: True if the signatures match, false otherwise (including if the package is not installed or the signature cannot be extracted, or if the provided SHA1 is invalid).
The App Authenticity module also provides functionality to detect the installation source of Android applications using the InstallationSourceDetector class.
To detect the installation source of an Android application, you can use the detectInstallationSource method:
fun detectSource(context: Context) {
val packageName = "com.example.app" // Package name of the app
// Detect the installation source
val installationInfo = InstallationSourceDetector.detectInstallationSource(context, packageName)
// Use the installation information
println("Installation Source: ${installationInfo.source}")
println("Installer Name: ${installationInfo.installerName}")
println("Installer Package: ${installationInfo.installerPackage}")
println("Is System App: ${installationInfo.isSystemApp}")
}Parameters:
context: The Android context.packageName: The package name of the application.Returns: An InstallationInfo object containing information about the installation source.
To check if an application is a system app, you can use the isSystemApp method:
fun checkIfSystemApp(context: Context) {
val packageName = "com.example.app" // Package name of the app
// Check if the app is a system app
val isSystemApp = InstallationSourceDetector.isSystemApp(context, packageName)
if (isSystemApp) {
println("The app is a system app")
} else {
println("The app is not a system app")
}
}Parameters:
context: The Android context.packageName: The package name of the application.Returns: True if the application is a system app, false otherwise.
The InstallationSourceDetector can identify the following installation sources:
InstallationSource.GOOGLE_PLAY)InstallationSource.AMAZON)InstallationSource.SAMSUNG)InstallationSource.HUAWEI)InstallationSource.XIAOMI)InstallationSource.OPPO)InstallationSource.VIVO)InstallationSource.ONEPLUS)InstallationSource.SYSTEM)InstallationSource.SIDELOADED)InstallationSource.OTHER)The library includes a logger for debugging. You can customize or disable logging by modifying the logger configuration.
The library uses Ktor for network operations. Since Ktor dependencies are configured as compileOnly, you need to include the following Ktor dependencies in your project:
// Ktor dependencies - version 3.2.0 or later
implementation("io.ktor:ktor-client-core:$ktor_version")
implementation("io.ktor:ktor-client-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-client-serialization:$ktor_version")
implementation("io.ktor:ktor-client-logging:$ktor_version")
implementation("io.ktor:ktor-client-cio:$ktor_version")Also ensure that network permissions are properly configured for Android.
Contributions to the library are welcome. If you find a bug or want to request a feature, feel free to open an issue or submit a pull request on GitHub.
This library is licensed under the MIT License. See the LICENSE file for details.
The user assumes full responsibility for the use of this library and must verify the legality of such use in their country.
This library is intended for educational and personal use. Scraping data from app stores may violate their terms of service. Use responsibly and at your own risk.
StoreKit is a comprehensive Kotlin multiplatform library for extracting detailed information about applications from various Android app stores. Currently, it supports:
With this library, you can fetch details such as application descriptions, developer information, categories, reviews, ratings, and more from multiple app stores using a consistent API.
This library is built using Kotlin Multiplatform and leverages kotlinx.serialization for parsing JSON data and Ktor for HTTP requests.
The Google Play modules are available on Maven Central:
For scraping data from the Google Play Store:
dependencies {
implementation("io.github.kdroidfilter:storekit-gplay-scrapper:<version>")
}If you only need the model classes (like GooglePlayApplicationInfo and GooglePlayCategory) without the scraping functionality:
dependencies {
implementation("io.github.kdroidfilter:storekit-gplay-core:<version>")
}To fetch detailed information about a specific app from Google Play, you can use the getGooglePlayApplicationInfo function. This function requires the app ID as a parameter and optionally takes the language and country codes.
appId: String (mandatory): The unique identifier of the app.lang: String (optional, default = "en"): Language code for the app details (ISO 639-1).country: String (optional, default = "us"): Country code for the app details (ISO 3166).fun main() {
val json = Json {
prettyPrint = true
ignoreUnknownKeys = true
encodeDefaults = true
}
runBlocking {
val appId = "com.android.chrome"
val appInfo = getGooglePlayApplicationInfo(appId)
println(json.encodeToString(appInfo))
}
}The GooglePlayApplicationInfo class is a comprehensive data model that represents detailed information about an application on the Google Play Store. It contains the following fields:
title: String - The title/name of the applicationdescription: String - Plain text description of the applicationdescriptionHTML: String - HTML-formatted description of the applicationsummary: String - A short summary of the applicationinstalls: String - Number of installs as a formatted string (e.g., "10,000,000+")minInstalls: Long - Minimum number of installs as a numeric valuerealInstalls: Long - Estimated real number of installsscore: Double - Overall rating score (0.0 to 5.0)ratings: Long - Total number of ratingsreviews: Long - Total number of reviewshistogram: List<Long> - Distribution of ratings (1-5 stars)price: Double - Price of the application in the specified currencyfree: Boolean - Whether the application is freecurrency: String - Currency code for the price (e.g., "USD")sale: Boolean - Whether the application is on salesaleTime: Long? - Duration of the sale in millisecondsoriginalPrice: Double? - Original price before the salesaleText: String? - Text describing the saleoffersIAP: Boolean - Whether the application offers in-app purchasesinAppProductPrice: String - Price range for in-app purchasesdeveloper: String - Name of the developerdeveloperId: String - Unique identifier of the developerdeveloperEmail: String - Contact email of the developerdeveloperWebsite: String - Website of the developerdeveloperAddress: String - Physical address of the developerprivacyPolicy: String - URL to the privacy policygenre: String - Primary genre of the applicationgenreId: String - Identifier of the primary genrecategories: List<GooglePlayCategory> - List of categories the application belongs toicon: String - URL to the application iconheaderImage: String - URL to the header imagescreenshots: List<String> - URLs to the application screenshotsvideo: String - URL to the promotional videovideoImage: String - URL to the video thumbnailcontentRating: String - Content rating (e.g., "Everyone", "Teen")contentRatingDescription: String - Description of the content ratingadSupported: Boolean - Whether the application is supported by adscontainsAds: Boolean - Whether the application contains adsreleased: String - Release date of the applicationupdated: Long - Last update timestampversion: String - Current version of the applicationcomments: List<String> - List of user commentsappId: String - Unique identifier of the applicationurl: String - URL to the application's page on Google PlayThe GooglePlayCategory class represents a category on the Google Play Store with the following fields:
name: String - Name of the categoryid: String - Unique identifier of the categoryThe F-Droid modules are available on Maven Central:
For accessing the F-Droid API:
dependencies {
implementation("io.github.kdroidfilter:storekit-fdroid-api:<version>")
}If you only need the model classes (like FDroidPackageInfo) without the API client:
dependencies {
implementation("io.github.kdroidfilter:storekit-fdroid-core:<version>")
}To fetch detailed information about a specific package from F-Droid, you can use the FDroidService class. The class provides a method to retrieve package information using the package name.
Fetches package information using the package name.
Parameters:
packageName: String (mandatory): The package name of the application.Returns: An instance of FDroidPackageInfo containing the package information.
Throws: IllegalArgumentException if the package with the given package name does not exist or is not accessible.
fun main() {
val json = Json {
prettyPrint = true
encodeDefaults = true
}
runBlocking {
try {
val fdroidService = FDroidService()
// Fetch package information by package name
val packageInfo = fdroidService.getPackageInfo("net.thunderbird.android")
println(json.encodeToString(packageInfo))
// Get download link for the suggested version
val downloadLink = packageInfo.getSuggestedVersionDownloadLink()
println("Download link: $downloadLink")
} catch (e: Exception) {
println("Error fetching package information: ${e.message}")
e.printStackTrace()
}
}
}The FDroidPackageInfo class represents detailed information about a package on the F-Droid store. It contains the following fields:
packageName: String - The package name of the applicationsuggestedVersionCode: Long - The suggested version code of the applicationpackages: List<FDroidPackageVersion> - List of available package versionsgetDownloadLink(versionCode: Long): String? - Gets the download link for the package with the specified version code. Returns null if the version code doesn't exist in the packages list.getSuggestedVersionDownloadLink(): String? - Gets the download link for the suggested version of the package. Returns null if the suggested version doesn't exist in the packages list.The FDroidPackageVersion class represents a version of a package in F-Droid with the following fields:
versionName: String - The version name of the package (e.g., "1.9")versionCode: Long - The version code of the package (e.g., 1009000)The Aptoide modules are available on Maven Central:
For accessing the Aptoide API:
dependencies {
implementation("io.github.kdroidfilter:storekit-aptoide-api:<version>")
}If you only need the model classes (like AptoideApplicationInfo) without the API client:
dependencies {
implementation("io.github.kdroidfilter:storekit-aptoide-core:<version>")
}To fetch detailed information about a specific app from Aptoide, you can use the AptoideService class. The class provides several methods to retrieve app information using different identifiers.
Fetches application metadata using the package name.
Parameters:
packageName: String (mandatory): The package name of the application.language: String (optional, default = "en"): Language code for the content localization.Returns: An instance of AptoideApplicationInfo containing the application's metadata.
Fetches application metadata using the app ID.
Parameters:
appId: Long (mandatory): The ID of the application.language: String (optional, default = "en"): Language code for the content localization.Returns: An instance of AptoideApplicationInfo containing the application's metadata.
Fetches application metadata using the APK MD5 sum.
Parameters:
md5sum: String (mandatory): The MD5 sum of the APK file.language: String (optional, default = "en"): Language code for the content localization.Returns: An instance of AptoideApplicationInfo containing the application's metadata.
fun main() {
val json = Json { prettyPrint = true }
val aptoideService = AptoideService()
runBlocking {
try {
// Fetch app metadata by package name
val appInfo = aptoideService.getAppMetaByPackageName("com.waze", "en")
println(json.encodeToString(appInfo))
// Fetch app metadata by app ID
val appInfoById = aptoideService.getAppMetaById(12345, "en")
println(json.encodeToString(appInfoById))
// Fetch app metadata by APK MD5 sum
val appInfoByMd5 = aptoideService.getAppMetaByMd5sum("abcdef1234567890abcdef1234567890", "en")
println(json.encodeToString(appInfoByMd5))
} catch (e: Exception) {
println("Error fetching app metadata: ${e.message}")
e.printStackTrace()
}
}
}The AptoideApplicationInfo class is a comprehensive data model that represents detailed information about an application on the Aptoide store. It contains the following fields:
id: Long - Unique identifier of the applicationname: String - Name of the applicationpackageName: String - Package name of the applicationuname: String - Unique name of the applicationsize: Long - Size of the application in bytesicon: String - URL to the application icongraphic: String - URL to the application graphicadded: String - Date when the application was addedmodified: String - Date when the application was last modifiedupdated: String - Date when the application was last updatedmain_package: String? - Main package name if differentage: AptoideAge - Age rating informationdeveloper: AptoideDeveloper - Developer informationstore: AptoideStore - Store informationfile: AptoideFile - File informationmedia: AptoideMedia - Media assetsurls: AptoideUrls - URLs related to the applicationstats: AptoideStats - Statistics about the applicationaab: String? - Android App Bundle informationobb: String? - OBB file informationpay: String? - Payment informationappcoins: AptoideAppcoins - AppCoins informationsoft_locks: List<String> - Soft locks informationThe AptoideAge class contains age rating information with the following fields:
name: String - Name of the age ratingtitle: String - Title of the age ratingpegi: String - PEGI ratingrating: Int - Numeric ratingThe AptoideDeveloper class contains information about the developer with the following fields:
id: Long - Unique identifier of the developername: String - Name of the developerwebsite: String - Website of the developeremail: String - Email of the developerprivacy: String? - Privacy policy URLThe AptoideStore class contains information about the store with the following fields:
id: Long - Unique identifier of the storename: String - Name of the storeavatar: String - URL to the store avatarappearance: AptoideAppearance - Appearance informationstats: AptoideStoreStats - Statistics about the storeThe AptoideAppearance class contains information about the store appearance with the following fields:
theme: String - Theme of the storedescription: String - Description of the storeThe AptoideStoreStats class contains statistics about the store with the following fields:
apps: Int - Number of applications in the storesubscribers: Int - Number of subscribers to the storedownloads: Int - Number of downloads from the storeThe AptoideFile class contains information about the application file with the following fields:
vername: String - Version namevercode: Int - Version codemd5sum: String - MD5 checksumfilesize: Long - File size in bytessignature: AptoideSignature - Signature informationadded: String - Date when the file was addedpath: String - Path to the filepath_alt: String - Alternative path to the filehardware: AptoideHardware - Hardware requirementsmalware: AptoideMalware - Malware scanning informationflags: AptoideFlags - Flags informationused_features: List<String> - List of used featuresused_permissions: List<String> - List of used permissionstags: List<String> - List of tagsThe AptoideSignature class contains signature information with the following fields:
sha1: String - SHA1 hash of the signatureowner: String - Owner of the signaturetoFormattedSha1() - Converts the SHA1 signature format from "XX:XX:XX..." to a continuous lowercase hex string.
Example: "35:B4:38:FE:1B:C6:9D:97:5D:C8:70:2D:C1:6A:B6:9E:BF:65:F2:6F" becomes "35b438fe1bc69d975dc8702dc16ab69ebf65f26f"The AptoideHardware class contains hardware requirements with the following fields:
sdk: Int - Minimum SDK versionscreen: String - Screen requirementsgles: Int - OpenGL ES versioncpus: List<String> - Supported CPUsdensities: List<String> - Supported screen densitiesdependencies: List<AptoideDependency> - List of dependenciesThe AptoideDependency class contains dependency information with the following fields:
type: String - Type of dependencylevel: String - Level of dependencyThe AptoideMalware class contains malware scanning information with the following fields:
rank: String - Malware rankreason: AptoideMalwareReason - Reason for the malware rankadded: String - Date when the malware scan was addedmodified: String - Date when the malware scan was modifiedThe AptoideMalwareReason class contains the reason for the malware rank with the following fields:
signature_validated: AptoideSignatureValidated - Signature validation informationThe AptoideSignatureValidated class contains signature validation information with the following fields:
date: String - Date of validationstatus: String - Status of validationsignature_from: String - Source of the signatureThe AptoideFlags class contains flags information with the following fields:
votes: List<AptoideVote> - List of votesThe AptoideVote class contains vote information with the following fields:
type: String - Type of votecount: Int - Number of votesThe AptoideMedia class contains media assets with the following fields:
keywords: List<String> - List of keywordsdescription: String - Description of the applicationsummary: String - Summary of the applicationnews: String - News about the applicationvideos: List<AptoideVideo> - List of videosscreenshots: List<AptoideScreenshot> - List of screenshotsThe AptoideVideo class contains video information with the following fields:
type: String - Type of videourl: String - URL to the videoThe AptoideScreenshot class contains screenshot information with the following fields:
url: String - URL to the screenshotheight: Int - Height of the screenshotwidth: Int - Width of the screenshotThe AptoideUrls class contains URLs related to the application with the following fields:
w: String - Web URLm: String - Mobile URLThe AptoideStats class contains statistics about the application with the following fields:
rating: AptoideRating - Rating informationprating: AptoideRating - Previous rating informationdownloads: Int - Number of downloadspdownloads: Int - Previous number of downloadsThe AptoideRating class contains rating information with the following fields:
avg: Double - Average ratingtotal: Int - Total number of ratingsvotes: List<AptoideRatingVote> - List of votesThe AptoideRatingVote class contains rating vote information with the following fields:
value: Int - Rating valuecount: Int - Number of votesThe AptoideAppcoins class contains AppCoins information with the following fields:
advertising: Boolean - Whether the application supports AppCoins advertisingbilling: Boolean - Whether the application supports AppCoins billingflags: List<String> - List of AppCoins flagsThe AptoideResponse class is the top-level response from the Aptoide API with the following fields:
info: AptoideInfo - Information about the responsedata: AptoideApplicationInfo - Application informationThe AptoideInfo class contains information about the response with the following fields:
status: String - Status of the responsetime: AptoideTime - Time informationThe AptoideTime class contains time information with the following fields:
seconds: Double - Time in secondshuman: String - Human-readable timeThe APKCombo modules are available on Maven Central:
For scraping data from the APKCombo website:
dependencies {
implementation("io.github.kdroidfilter:storekit-apkcombo-scraper:<version>")
}If you only need the model classes (like ApkComboApplicationInfo) without the scraping functionality:
dependencies {
implementation("io.github.kdroidfilter:storekit-apkcombo-core:<version>")
}To fetch detailed information about a specific app from APKCombo, you can use the getApkComboApplicationInfo function. This function requires the package name as a parameter.
packageName: String (mandatory): The package name of the application.An instance of ApkComboApplicationInfo containing the application's information.
IllegalArgumentException if the application with the given package name does not exist or is not accessible.
fun main() {
val json = Json {
prettyPrint = true
}
runBlocking {
try {
// Fetch app information by package name
val appInfo = getApkComboApplicationInfo("com.google.android.gm")
println(json.encodeToString(appInfo))
// Get direct download link
println("Download link: ${appInfo.downloadLink}")
} catch (e: Exception) {
println("Error fetching app information: ${e.message}")
e.printStackTrace()
}
}
}The ApkComboApplicationInfo class represents detailed information about an application on the APKCombo website. It contains the following fields:
title: String - The title/name of the applicationversion: String - Current version of the applicationversionCode: String - Version code of the applicationdownloadLink: String - Direct download link for the APKappId: String - Unique identifier of the application (package name)url: String - URL to the application's page on APKComboThe APK Link Resolver module provides a unified way to retrieve APK download links from multiple sources (APKPure, APKCombo, Aptoide, and F-Droid) with configurable priority.
Neither Aptoide, APKCombo, nor F-Droid can guarantee obtaining an APK link for every application. This module solves this problem by providing a simple way to check one source first, and if the APK is not found there, automatically check the next source. This approach significantly increases the chances of successfully retrieving an APK download link without requiring you to implement fallback logic in your application.
The APK Link Resolver module is available on Maven Central:
dependencies {
implementation("io.github.kdroidfilter:storekit-apklinkresolver-core:<version>")
}You can configure the priority order of APK sources using the ApkSourcePriority singleton:
// Exemple: essayer d'abord APKPure, puis APKCombo, puis F-Droid (les autres sources non précisées seront ajoutées à la fin dans l'ordre par défaut)
ApkSourcePriority.setPriorityOrder(listOf(ApkSource.APKPURE, ApkSource.APKCOMBO, ApkSource.FDROID))
// Get the current priority order
val currentPriority = ApkSourcePriority.getPriorityOrder()
println("Current priority: $currentPriority")
// Réinitialiser l'ordre par défaut (APKPure, APKCombo, FDroid, Aptoide)
ApkSourcePriority.resetToDefault()To retrieve an APK download link for a specific package, use the ApkLinkResolverService:
fun main() {
runBlocking {
try {
val service = ApkLinkResolverService()
// Get download link for a package
val downloadInfo = service.getApkDownloadLink("com.google.android.gm")
println("Download link: ${downloadInfo.downloadLink}")
println("Source: ${downloadInfo.source}")
println("Version: ${downloadInfo.version}")
println("Title: ${downloadInfo.title}")
println("File size: ${downloadInfo.fileSize} bytes")
} catch (e: Exception) {
println("Error retrieving download link: ${e.message}")
e.printStackTrace()
}
}
}The service will try to retrieve the download link from each source in the order specified by the ApkSourcePriority configuration. You can specify a partial priority list; any unspecified sources are appended automatically in the default order (by default: APKPURE, APKCOMBO, FDROID, APTOIDE). If a source fails, it will try the next one. If all sources fail, it will throw an IllegalArgumentException with details about the failures.
The ApkSource enum represents the available APK sources:
APKPURE - The APKPure websiteAPKCOMBO - The APKCombo websiteAPTOIDE - The Aptoide storeFDROID - The F-Droid storeThe ApkLinkInfo class represents information about an APK download with the following fields:
packageName: String - The package name of the applicationdownloadLink: String - The direct download link for the APKsource: String - The source of the download link (e.g., "APKPURE", "APKCOMBO", "APTOIDE", "FDROID")version: String - The version of the application (if available)versionCode: String - The version code of the application (if available)title: String - The title/name of the application (if available)fileSize: Long - The size of the APK file in bytes, or -1 if the size could not be determinedThe APKPure modules are available on Maven Central:
For scraping data from the APKPure website:
dependencies {
implementation("io.github.kdroidfilter:storekit-apkpure-api:<version>")
}If you only need the model classes (like ApkPureApplicationInfo) without the scraping functionality:
dependencies {
implementation("io.github.kdroidfilter:storekit-apkpure-core:<version>")
}To fetch application info (title, version, versionCode, signature, and a direct XAPK download link with version=latest) use getApkPureApplicationInfo:
fun main() {
val json = Json {
prettyPrint = true
encodeDefaults = true
}
runBlocking {
try {
val app = getApkPureApplicationInfo("com.waze")
println(json.encodeToString(app))
// The download link uses: https://d.apkpure.com/b/XAPK/<package>?version=latest
println("Direct link: ${'$'}{app.downloadLink}")
println("Signature: ${'$'}{app.signature}")
println("VersionCode: ${'$'}{app.versionCode}")
} catch (e: Exception) {
println("Error: ${'$'}{e.message}")
}
}
}title: Stringversion: StringversionCode: Stringsignature: StringdownloadLink: String (always uses version=latest)appId: Stringurl: StringThe App Authenticity module is available on Maven Central:
dependencies {
implementation("io.github.kdroidfilter:storekit-authenticity:<version>")
}To extract the SHA1 signature of an installed Android application, you can use the SignatureExtractor class:
// In your Android activity or fragment
fun extractSignature(context: Context) {
val packageName = "com.example.app" // Package name of the app
// Extract the SHA1 signature
val signature = SignatureExtractor.extractSha1Signature(context, packageName)
// Use the signature
if (signature != null) {
println("SHA1 Signature: $signature")
} else {
println("Failed to extract signature. App might not be installed.")
}
}Parameters:
context: The Android context.packageName: The package name of the application.Returns: The SHA1 signature of the application as a string, or null if the application is not installed or the signature cannot be extracted.
To validate if a string is a valid SHA1 signature, you can use the isValidSha1Signature function:
fun validateSignature() {
val sha1String = "38918a453d07199354f8b19af05ec6562ced5788" // Example SHA1 signature
// Validate the SHA1 signature
val isValid = SignatureExtractor.isValidSha1Signature(sha1String)
if (isValid) {
println("The signature is a valid SHA1 signature")
} else {
println("The signature is not a valid SHA1 signature")
}
}Parameters:
sha1String: The SHA1 string to verify.Returns: True if the string is a valid SHA1 signature (40 characters long and contains only hexadecimal digits), false otherwise.
To verify if an installed app's signature matches an expected SHA1 signature, you can use the verifyPackageSignature function. This function already validates the SHA1 signature internally, so you don't need to call isValidSha1Signature separately:
fun verifyAppSignature(context: Context) {
val packageName = "com.android.chrome" // Package name of the app
val expectedSignature = "38918a453d07199354f8b19af05ec6562ced5788" // Expected SHA1 signature
// Verify the app's signature
val isSignatureValid = SignatureExtractor.verifyPackageSignature(context, packageName, expectedSignature)
if (isSignatureValid) {
println("The app's signature matches the expected signature")
} else {
println("The app's signature does not match the expected signature, or the app is not installed")
}
}Parameters:
context: The Android context.packageName: The package name of the application to verify.expectedSha1: The expected SHA1 signature to compare against.Returns: True if the signatures match, false otherwise (including if the package is not installed or the signature cannot be extracted, or if the provided SHA1 is invalid).
The App Authenticity module also provides functionality to detect the installation source of Android applications using the InstallationSourceDetector class.
To detect the installation source of an Android application, you can use the detectInstallationSource method:
fun detectSource(context: Context) {
val packageName = "com.example.app" // Package name of the app
// Detect the installation source
val installationInfo = InstallationSourceDetector.detectInstallationSource(context, packageName)
// Use the installation information
println("Installation Source: ${installationInfo.source}")
println("Installer Name: ${installationInfo.installerName}")
println("Installer Package: ${installationInfo.installerPackage}")
println("Is System App: ${installationInfo.isSystemApp}")
}Parameters:
context: The Android context.packageName: The package name of the application.Returns: An InstallationInfo object containing information about the installation source.
To check if an application is a system app, you can use the isSystemApp method:
fun checkIfSystemApp(context: Context) {
val packageName = "com.example.app" // Package name of the app
// Check if the app is a system app
val isSystemApp = InstallationSourceDetector.isSystemApp(context, packageName)
if (isSystemApp) {
println("The app is a system app")
} else {
println("The app is not a system app")
}
}Parameters:
context: The Android context.packageName: The package name of the application.Returns: True if the application is a system app, false otherwise.
The InstallationSourceDetector can identify the following installation sources:
InstallationSource.GOOGLE_PLAY)InstallationSource.AMAZON)InstallationSource.SAMSUNG)InstallationSource.HUAWEI)InstallationSource.XIAOMI)InstallationSource.OPPO)InstallationSource.VIVO)InstallationSource.ONEPLUS)InstallationSource.SYSTEM)InstallationSource.SIDELOADED)InstallationSource.OTHER)The library includes a logger for debugging. You can customize or disable logging by modifying the logger configuration.
The library uses Ktor for network operations. Since Ktor dependencies are configured as compileOnly, you need to include the following Ktor dependencies in your project:
// Ktor dependencies - version 3.2.0 or later
implementation("io.ktor:ktor-client-core:$ktor_version")
implementation("io.ktor:ktor-client-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-client-serialization:$ktor_version")
implementation("io.ktor:ktor-client-logging:$ktor_version")
implementation("io.ktor:ktor-client-cio:$ktor_version")Also ensure that network permissions are properly configured for Android.
Contributions to the library are welcome. If you find a bug or want to request a feature, feel free to open an issue or submit a pull request on GitHub.
This library is licensed under the MIT License. See the LICENSE file for details.
The user assumes full responsibility for the use of this library and must verify the legality of such use in their country.
This library is intended for educational and personal use. Scraping data from app stores may violate their terms of service. Use responsibly and at your own risk.