
Community-driven database offers kosher filtering rules for applications, adapting app listings based on user modes. Supports host-based rules, mode-specific policies, and sensitive app flags for informed usage.
Welcome to the community-driven database of kosher filtering rules for applications. This guide is primarily used by KDroid Filter but is freely available for anyone to use. Licensed under the LGPL, you may integrate these policies even in closed-source applications. At this stage, it is recommended to contribute only host-based rules, as the tools for detecting apps and UI nodes are not yet available.
The KDroid app store dynamically adapts its application listings based on the current UserMode (levels 0 to 5) to only show apps that are appropriate for each level:
For applications using a ModeBasedPolicy, if a rule is defined for a lower level (e.g. 1 or 2), any higher levels (3, 4, or 5) without an explicit configuration will automatically inherit that rule.
AppPolicy
βββ FixedPolicy
β βββ "type": "Fixed"
β βββ networkPolicy
β β βββ mode: FULL_OPEN | BLACKLIST | WHITELIST | LOCAL_ONLY | OFFLINE
β β βββ spec: None | HostList{hostsβ¦}
β βββ detectionRules [β¦]
β
βββ ModeBasedPolicy
β βββ "type": "ModeBased"
β βββ modePolicies
β β βββ OFFLINE β NetworkPolicy{β¦}
β β βββ NAVIGATION_ONLY β NetworkPolicy{β¦}
β β βββ NAVIGATION_AND_MAIL_ONLY β NetworkPolicy{β¦}
β β βββ REDUCED_RISK β NetworkPolicy{β¦}
β β βββ MOST_OPEN β NetworkPolicy{β¦}
β βββ detectionRules [β¦]
β
βββ MultiModePolicy
βββ "type": "MultiMode"
βββ modeVariants
β βββ userMode: GPS_ONLY
β β βββ variants
β β β βββ id: "strict", policy: {mode: LOCAL_ONLY}
β β β βββ id: "balanced", policy: {mode: WHITELIST, spec: HostList[β¦]}
β β βββ defaultVariantId: "balanced"
β βββ userMode: MOST_OPEN
β βββ variants
β β βββ id: "open", policy: {mode: FULL_OPEN}
β βββ defaultVariantId: "open"
βββ detectionRules [β¦]
Place your JSON file under:
app-policies/<category>/<packageName>.json
Example:
app-policies/navigation/com.example.app.json
Each category folder (e.g., communication, navigation, video) helps avoid merge conflicts and keeps things tidy. π
Below are the three policy types. Copy the template that matches your use case and fill in your data.
Use when the same network rules apply to all modes.
{
"type": "Fixed",
"packageName": "com.waze",
"category": "NAVIGATION",
"networkPolicy": {
"mode": "BLACKLIST",
"spec": {
"type": "HostList",
"hosts": [
"*.waze.com",
"venue-image.waze.com",
"ads-resources.waze.com",
"ads-resources-legacy.waze.com",
"adsassets.waze.com",
"social.waze.co.il"
]
}
},
"minimumVersionCode": 1030416
}Use when you need different rules per user mode.
{
"type": "ModeBased",
"packageName": "com.google.android.gm",
"category": "MAIL",
"minimumVersionCode": 0,
"modePolicies": {
"NAVIGATION_AND_MAIL_ONLY": {
"mode": "BLACKLIST",
"desc": "Allow only mails and block Google Chat",
"spec": {
"type": "HostList",
"hosts": [
"HOST_OF_GOOGLE_CHAT"
]
}
},
"REDUCED_RISK": {
"mode": "FULL_OPEN"
}
}
}π Optional Key:
descYou can add a"desc"field at the same level asmodeorspecto describe what this policy does. It is intended for human readers and will be stripped out at compile time.π Mode Inheritance If you define a policy for
REDUCED_RISKbut do not provide one for a higher mode (e.g.,MOST_OPEN), theREDUCED_RISKpolicy will automatically apply to those modes when no other configuration is available.
Use when each user mode has multiple variants, each with its own rules and optional activity/node detections.
{
"type": "MultiMode",
"packageName": "com.whatsapp",
"category": "COMMUNICATION",
"minimumVersionCode": 0,
"modeVariants": [
{
"userMode": "MOST_OPEN",
"variants": [
{
"id": "open",
"label": "Fully open",
"policy": { "mode": "FULL_OPEN" }
},
{
"id": "restricted",
"label": "Only messages, no photos, videos and calling",
"policy": {
"mode": "WHITELIST",
"spec": {
"type": "HostList",
"hosts": [
"v.whatsapp.net",
"static.whatsapp.net"
]
}
}
},
{
"id": "block_groups",
"label": "Block groups",
"policy": { "mode": "FULL_OPEN" },
"detectionRules": [
{
"type": "NODE",
"targets": ["TODO"],
"condition": "ONLY_IF",
"action": "KILL_APP"
}
],
"overrideDefaultRules": false,
"configurationRequired": true,
"configurationKey": "whatsapp_groups_prefs"
}
],
"defaultVariantId": "open"
}
],
"detectionRules": [
{
"type": "NODE",
"targets": [
"com.whatsapp:id/newsletter_quick_forwarding_pill_container_key"
],
"condition": "ONLY_IF",
"action": "KILL_APP",
"desc": "Kill app when entering the WhatsApp Update channel"
}
]
}Root-level detectionRules apply across all variants.
Within each variant:
detectionRules: rules specific to that variant.overrideDefaultRules: true (default) to use only variant rules, false to merge with root rules.minimumVersionCode) for each app. This is imperative for proper app validation. While our system can try to determine this automatically, it's not 100% reliable and will always use the latest version available.sha1) of the app's certificate. This is crucial for security verification. Our system can attempt to retrieve this, but it's not always reliable.Note: For system apps (category
SYSTEM), the minimum version code and SHA1 signature are not required.Important: If our system cannot determine the minimum version code or signature for a non-system app, the CI will fail. Make sure these values are either provided in the policy file or can be reliably retrieved from the Aptoide API.
CI will reject invalid JSON or misplaced files. Good luck! π
The project includes several Gradle tasks to help with development and validation:
To validate all JSON policy files for correctness:
./gradlew :generators:policies:validateJsonThis task checks all JSON files in the app-policies directory to ensure they:
The task will report any validation errors found, making it easier to identify and fix issues before submitting.
To check policies for missing version codes and signatures:
./gradlew :generators:policies:checkPoliciesThis task verifies that all policy files have:
The system will attempt to retrieve missing values from the Aptoide API, but this is not always reliable. The task will report any policies that fail these checks, except for system apps which are exempt.
Note: This task is run as part of the CI pipeline. If the system cannot determine the minimum version code or signature for a non-system app, the CI will fail.
Both modes block all outbound Internet traffic; the distinction is mainly about the user experience:
| Mode | Behaviour | When to choose it? |
|---|---|---|
| LOCAL_ONLY | KDroid filters the connection as soon as the app is opened and shows a notification prompting the user to enable βLocal modeβ. Only local network traffic (WiβFi/LANβ―ββ―e.g. 192.168.x.x) is allowed. | Apps whose main purpose relies on the local network, such as smartβhome controllers, drone control apps, or WiβFi file transfer tools. |
| OFFLINE | No network traffic is allowed at all (neither Internet nor LAN). KDroid shows no notification. | Apps that are primarily offline and nearly never need local network access, e.g. video players, document viewers, or singleβplayer games. |
In short
LOCAL_ONLY when the user needs to talk to nearby devices (NAS, Chromecast, smart lights, etc.). The notification helps them enable local mode quickly.OFFLINE for apps that work perfectly without any network so you avoid showing an unnecessary notification.You can optionally include the following boolean flags in your policy files to help with sensitive app filtering and user awareness:
hasUnmodestImage: Set to true if the app contains unfiltered, inappropriate or immodest visual content (e.g. uncovered women in media banners, icons, or previews). This indicates that the user must explicitly accept the risk in order to use the app.
isPotentiallyDangerous: Set to true if the app can pose a technical or security risk, such as remote access tools or apps capable of controlling other devices over open internet connections. This flag helps apply stricter rules or prompt additional warnings.
requiresPlayStoreInstallation: Set to true if the app must be installed from the Google Play Store for specific reasons (e.g., licensing requirements, app integrity verification, or access to Play Store-specific features). This indicates that the app should not be sideloaded from alternative sources.
isRecommendedInStore: Set to true if the app should be recommended in the store. By default, this is set to false. When set to true, the app will be highlighted or featured in the store, making it more visible to users.
These fields are optional but enforced by default: apps with these flags will not appear in the store or be granted internet access unless the user has explicitly accepted the risk. Additionally, apps with hasUnmodestImage or isPotentiallyDangerous set to true will be excluded from the REDUCED_RISK mode.
Apps marked with any of these flags will only appear in the store or receive internet access if the user has explicitly acknowledged the risk and chosen to enable them manually.
Some applications must be installed exclusively from the Google Play Store for several important reasons:
License Verification: Many paid or subscription-based apps use Google Play's licensing services to verify purchases. When installed from alternative sources, these apps may not function properly as they cannot validate the purchase.
App Integrity & Security: The Play Store provides app signing and verification mechanisms that help ensure the app hasn't been tampered with. Apps handling sensitive data (like banking or payment apps) often require this security layer.
Google Play Services Dependencies: Some apps rely heavily on specific Google Play Services features that are only fully available for apps installed through official channels.
In-App Purchases: Applications that offer in-app purchases typically use Google Play's billing system, which may not function correctly when the app is sideloaded.
Auto-Updates: Apps installed from the Play Store can receive automatic updates, ensuring users always have the latest security patches and features.
When you mark an app with requiresPlayStoreInstallation: true, you're indicating to users that the app should not be sideloaded from alternative sources, as this could lead to functionality issues, security risks, or licensing problems.
{
"type": "Fixed",
"packageName": "com.example.fakebank",
"category": "FINANCE",
"minimumVersionCode": 100,
"hasUnmodestImage": true,
"isRecommendedInStore": false,
"networkPolicy": {
"mode": "FULL_OPEN"
}
}{
"type": "Fixed",
"packageName": "com.example.remotecontrol",
"category": "TOOLS",
"minimumVersionCode": 50,
"isPotentiallyDangerous": true,
"networkPolicy": {
"mode": "FULL_OPEN"
}
}{
"type": "Fixed",
"packageName": "com.example.licensedapp",
"category": "PRODUCTIVITY",
"minimumVersionCode": 75,
"requiresPlayStoreInstallation": true,
"networkPolicy": {
"mode": "FULL_OPEN"
}
}All of these apps are tagged for additional caution. They will only be functional or visible if the user has agreed to unlock them by accepting the risks.
KDroid Database provides multiple modules that you can use in your own projects:
The core module contains the essential data structures and enums for the KDroid Database, including the AppCategory enum and policy definitions.
dependencies {
implementation("io.github.kdroidfilter.database:core:<version>")
}The localization module extends the core module to provide localized category names in multiple languages (English, Hebrew, and French). It includes platform-specific extensions for Android and JVM.
dependencies {
implementation("io.github.kdroidfilter.database:localization:<version>")
}The downloader module provides functionality to download the latest store and policies databases from GitHub releases. It includes methods to download databases for multiple languages.
dependencies {
implementation("io.github.kdroidfilter.database.downloader:core:<version>")
}// Create a DatabaseDownloader instance
val databaseDownloader = DatabaseDownloader()
// Download store databases for all languages (en, fr, he)
val outputDir = "path/to/output/directory"
val storeResults = databaseDownloader.downloadLatestStoreDatabases(outputDir)
// Check download results
storeResults.forEach { (language, success) ->
if (success) {
println("Successfully downloaded store database for $language")
} else {
println("Failed to download store database for $language")
}
}
// Download policies database
val policiesResult = databaseDownloader.downloadLatestPoliciesDatabase(outputDir)
if (policiesResult) {
println("Successfully downloaded policies database")
} else {
println("Failed to download policies database")
}The DAO (Data Access Object) module provides a clean interface for database operations, abstracting away direct SQL queries. It includes DAOs for accessing application data and version information, as well as utility classes for working with the data.
dependencies {
implementation("io.github.kdroidfilter.database.dao:core:<version>")
}isRecommendedInStore flag synchronization// Load applications from the database
val applications = ApplicationsDao.loadApplicationsFromDatabase(
database = database,
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Search for applications in the database
val searchResults = ApplicationsDao.searchApplicationsInDatabase(
database = database,
query = "calculator",
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Check if an application is recommended in the store
val isRecommended = ApplicationsDao.isRecommendedInStore(
database = database,
appId = "com.example.app"
)
// Get all applications that are recommended in the store
val recommendedApps = ApplicationsDao.getRecommendedApplications(
database = database,
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Get all categories with localized names
val categories = CategoriesDao.getAllCategories(
database = database,
deviceLanguage = "en"
)
// Get applications by category ID
val appsByCategoryId = CategoriesDao.getApplicationsByCategoryId(
database = database,
categoryId = 1,
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Get applications by category name
val appsByCategoryName = CategoriesDao.getApplicationsByCategoryName(
database = database,
categoryName = "NAVIGATION",
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Get applications by category enum
val appsByCategory = CategoriesDao.getApplicationsByCategory(
database = database,
category = AppCategory.NAVIGATION,
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Get the current database version
val currentVersion = VersionDao.getCurrentVersion(database)
// Update the database version
val updateSuccess = VersionDao.updateVersion(database, "NEWVERSION")
For a simplified overview of how to use the database, please consult the example in the sample directory. The sample demonstrates basic database operations including downloading, querying, and displaying data.
β οΈ Important Warning: The sample code usesrunBlockingfor database downloads, which is prohibited in production code. This is only done for demonstration purposes. In real applications, always use proper coroutine scopes and avoid blocking the main thread.
The DAO module is actively evolving to satisfy more needs and use cases. Contributions and pull requests are welcome to enhance its functionality and performance.
Welcome to the community-driven database of kosher filtering rules for applications. This guide is primarily used by KDroid Filter but is freely available for anyone to use. Licensed under the LGPL, you may integrate these policies even in closed-source applications. At this stage, it is recommended to contribute only host-based rules, as the tools for detecting apps and UI nodes are not yet available.
The KDroid app store dynamically adapts its application listings based on the current UserMode (levels 0 to 5) to only show apps that are appropriate for each level:
For applications using a ModeBasedPolicy, if a rule is defined for a lower level (e.g. 1 or 2), any higher levels (3, 4, or 5) without an explicit configuration will automatically inherit that rule.
AppPolicy
βββ FixedPolicy
β βββ "type": "Fixed"
β βββ networkPolicy
β β βββ mode: FULL_OPEN | BLACKLIST | WHITELIST | LOCAL_ONLY | OFFLINE
β β βββ spec: None | HostList{hostsβ¦}
β βββ detectionRules [β¦]
β
βββ ModeBasedPolicy
β βββ "type": "ModeBased"
β βββ modePolicies
β β βββ OFFLINE β NetworkPolicy{β¦}
β β βββ NAVIGATION_ONLY β NetworkPolicy{β¦}
β β βββ NAVIGATION_AND_MAIL_ONLY β NetworkPolicy{β¦}
β β βββ REDUCED_RISK β NetworkPolicy{β¦}
β β βββ MOST_OPEN β NetworkPolicy{β¦}
β βββ detectionRules [β¦]
β
βββ MultiModePolicy
βββ "type": "MultiMode"
βββ modeVariants
β βββ userMode: GPS_ONLY
β β βββ variants
β β β βββ id: "strict", policy: {mode: LOCAL_ONLY}
β β β βββ id: "balanced", policy: {mode: WHITELIST, spec: HostList[β¦]}
β β βββ defaultVariantId: "balanced"
β βββ userMode: MOST_OPEN
β βββ variants
β β βββ id: "open", policy: {mode: FULL_OPEN}
β βββ defaultVariantId: "open"
βββ detectionRules [β¦]
Place your JSON file under:
app-policies/<category>/<packageName>.json
Example:
app-policies/navigation/com.example.app.json
Each category folder (e.g., communication, navigation, video) helps avoid merge conflicts and keeps things tidy. π
Below are the three policy types. Copy the template that matches your use case and fill in your data.
Use when the same network rules apply to all modes.
{
"type": "Fixed",
"packageName": "com.waze",
"category": "NAVIGATION",
"networkPolicy": {
"mode": "BLACKLIST",
"spec": {
"type": "HostList",
"hosts": [
"*.waze.com",
"venue-image.waze.com",
"ads-resources.waze.com",
"ads-resources-legacy.waze.com",
"adsassets.waze.com",
"social.waze.co.il"
]
}
},
"minimumVersionCode": 1030416
}Use when you need different rules per user mode.
{
"type": "ModeBased",
"packageName": "com.google.android.gm",
"category": "MAIL",
"minimumVersionCode": 0,
"modePolicies": {
"NAVIGATION_AND_MAIL_ONLY": {
"mode": "BLACKLIST",
"desc": "Allow only mails and block Google Chat",
"spec": {
"type": "HostList",
"hosts": [
"HOST_OF_GOOGLE_CHAT"
]
}
},
"REDUCED_RISK": {
"mode": "FULL_OPEN"
}
}
}π Optional Key:
descYou can add a"desc"field at the same level asmodeorspecto describe what this policy does. It is intended for human readers and will be stripped out at compile time.π Mode Inheritance If you define a policy for
REDUCED_RISKbut do not provide one for a higher mode (e.g.,MOST_OPEN), theREDUCED_RISKpolicy will automatically apply to those modes when no other configuration is available.
Use when each user mode has multiple variants, each with its own rules and optional activity/node detections.
{
"type": "MultiMode",
"packageName": "com.whatsapp",
"category": "COMMUNICATION",
"minimumVersionCode": 0,
"modeVariants": [
{
"userMode": "MOST_OPEN",
"variants": [
{
"id": "open",
"label": "Fully open",
"policy": { "mode": "FULL_OPEN" }
},
{
"id": "restricted",
"label": "Only messages, no photos, videos and calling",
"policy": {
"mode": "WHITELIST",
"spec": {
"type": "HostList",
"hosts": [
"v.whatsapp.net",
"static.whatsapp.net"
]
}
}
},
{
"id": "block_groups",
"label": "Block groups",
"policy": { "mode": "FULL_OPEN" },
"detectionRules": [
{
"type": "NODE",
"targets": ["TODO"],
"condition": "ONLY_IF",
"action": "KILL_APP"
}
],
"overrideDefaultRules": false,
"configurationRequired": true,
"configurationKey": "whatsapp_groups_prefs"
}
],
"defaultVariantId": "open"
}
],
"detectionRules": [
{
"type": "NODE",
"targets": [
"com.whatsapp:id/newsletter_quick_forwarding_pill_container_key"
],
"condition": "ONLY_IF",
"action": "KILL_APP",
"desc": "Kill app when entering the WhatsApp Update channel"
}
]
}Root-level detectionRules apply across all variants.
Within each variant:
detectionRules: rules specific to that variant.overrideDefaultRules: true (default) to use only variant rules, false to merge with root rules.minimumVersionCode) for each app. This is imperative for proper app validation. While our system can try to determine this automatically, it's not 100% reliable and will always use the latest version available.sha1) of the app's certificate. This is crucial for security verification. Our system can attempt to retrieve this, but it's not always reliable.Note: For system apps (category
SYSTEM), the minimum version code and SHA1 signature are not required.Important: If our system cannot determine the minimum version code or signature for a non-system app, the CI will fail. Make sure these values are either provided in the policy file or can be reliably retrieved from the Aptoide API.
CI will reject invalid JSON or misplaced files. Good luck! π
The project includes several Gradle tasks to help with development and validation:
To validate all JSON policy files for correctness:
./gradlew :generators:policies:validateJsonThis task checks all JSON files in the app-policies directory to ensure they:
The task will report any validation errors found, making it easier to identify and fix issues before submitting.
To check policies for missing version codes and signatures:
./gradlew :generators:policies:checkPoliciesThis task verifies that all policy files have:
The system will attempt to retrieve missing values from the Aptoide API, but this is not always reliable. The task will report any policies that fail these checks, except for system apps which are exempt.
Note: This task is run as part of the CI pipeline. If the system cannot determine the minimum version code or signature for a non-system app, the CI will fail.
Both modes block all outbound Internet traffic; the distinction is mainly about the user experience:
| Mode | Behaviour | When to choose it? |
|---|---|---|
| LOCAL_ONLY | KDroid filters the connection as soon as the app is opened and shows a notification prompting the user to enable βLocal modeβ. Only local network traffic (WiβFi/LANβ―ββ―e.g. 192.168.x.x) is allowed. | Apps whose main purpose relies on the local network, such as smartβhome controllers, drone control apps, or WiβFi file transfer tools. |
| OFFLINE | No network traffic is allowed at all (neither Internet nor LAN). KDroid shows no notification. | Apps that are primarily offline and nearly never need local network access, e.g. video players, document viewers, or singleβplayer games. |
In short
LOCAL_ONLY when the user needs to talk to nearby devices (NAS, Chromecast, smart lights, etc.). The notification helps them enable local mode quickly.OFFLINE for apps that work perfectly without any network so you avoid showing an unnecessary notification.You can optionally include the following boolean flags in your policy files to help with sensitive app filtering and user awareness:
hasUnmodestImage: Set to true if the app contains unfiltered, inappropriate or immodest visual content (e.g. uncovered women in media banners, icons, or previews). This indicates that the user must explicitly accept the risk in order to use the app.
isPotentiallyDangerous: Set to true if the app can pose a technical or security risk, such as remote access tools or apps capable of controlling other devices over open internet connections. This flag helps apply stricter rules or prompt additional warnings.
requiresPlayStoreInstallation: Set to true if the app must be installed from the Google Play Store for specific reasons (e.g., licensing requirements, app integrity verification, or access to Play Store-specific features). This indicates that the app should not be sideloaded from alternative sources.
isRecommendedInStore: Set to true if the app should be recommended in the store. By default, this is set to false. When set to true, the app will be highlighted or featured in the store, making it more visible to users.
These fields are optional but enforced by default: apps with these flags will not appear in the store or be granted internet access unless the user has explicitly accepted the risk. Additionally, apps with hasUnmodestImage or isPotentiallyDangerous set to true will be excluded from the REDUCED_RISK mode.
Apps marked with any of these flags will only appear in the store or receive internet access if the user has explicitly acknowledged the risk and chosen to enable them manually.
Some applications must be installed exclusively from the Google Play Store for several important reasons:
License Verification: Many paid or subscription-based apps use Google Play's licensing services to verify purchases. When installed from alternative sources, these apps may not function properly as they cannot validate the purchase.
App Integrity & Security: The Play Store provides app signing and verification mechanisms that help ensure the app hasn't been tampered with. Apps handling sensitive data (like banking or payment apps) often require this security layer.
Google Play Services Dependencies: Some apps rely heavily on specific Google Play Services features that are only fully available for apps installed through official channels.
In-App Purchases: Applications that offer in-app purchases typically use Google Play's billing system, which may not function correctly when the app is sideloaded.
Auto-Updates: Apps installed from the Play Store can receive automatic updates, ensuring users always have the latest security patches and features.
When you mark an app with requiresPlayStoreInstallation: true, you're indicating to users that the app should not be sideloaded from alternative sources, as this could lead to functionality issues, security risks, or licensing problems.
{
"type": "Fixed",
"packageName": "com.example.fakebank",
"category": "FINANCE",
"minimumVersionCode": 100,
"hasUnmodestImage": true,
"isRecommendedInStore": false,
"networkPolicy": {
"mode": "FULL_OPEN"
}
}{
"type": "Fixed",
"packageName": "com.example.remotecontrol",
"category": "TOOLS",
"minimumVersionCode": 50,
"isPotentiallyDangerous": true,
"networkPolicy": {
"mode": "FULL_OPEN"
}
}{
"type": "Fixed",
"packageName": "com.example.licensedapp",
"category": "PRODUCTIVITY",
"minimumVersionCode": 75,
"requiresPlayStoreInstallation": true,
"networkPolicy": {
"mode": "FULL_OPEN"
}
}All of these apps are tagged for additional caution. They will only be functional or visible if the user has agreed to unlock them by accepting the risks.
KDroid Database provides multiple modules that you can use in your own projects:
The core module contains the essential data structures and enums for the KDroid Database, including the AppCategory enum and policy definitions.
dependencies {
implementation("io.github.kdroidfilter.database:core:<version>")
}The localization module extends the core module to provide localized category names in multiple languages (English, Hebrew, and French). It includes platform-specific extensions for Android and JVM.
dependencies {
implementation("io.github.kdroidfilter.database:localization:<version>")
}The downloader module provides functionality to download the latest store and policies databases from GitHub releases. It includes methods to download databases for multiple languages.
dependencies {
implementation("io.github.kdroidfilter.database.downloader:core:<version>")
}// Create a DatabaseDownloader instance
val databaseDownloader = DatabaseDownloader()
// Download store databases for all languages (en, fr, he)
val outputDir = "path/to/output/directory"
val storeResults = databaseDownloader.downloadLatestStoreDatabases(outputDir)
// Check download results
storeResults.forEach { (language, success) ->
if (success) {
println("Successfully downloaded store database for $language")
} else {
println("Failed to download store database for $language")
}
}
// Download policies database
val policiesResult = databaseDownloader.downloadLatestPoliciesDatabase(outputDir)
if (policiesResult) {
println("Successfully downloaded policies database")
} else {
println("Failed to download policies database")
}The DAO (Data Access Object) module provides a clean interface for database operations, abstracting away direct SQL queries. It includes DAOs for accessing application data and version information, as well as utility classes for working with the data.
dependencies {
implementation("io.github.kdroidfilter.database.dao:core:<version>")
}isRecommendedInStore flag synchronization// Load applications from the database
val applications = ApplicationsDao.loadApplicationsFromDatabase(
database = database,
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Search for applications in the database
val searchResults = ApplicationsDao.searchApplicationsInDatabase(
database = database,
query = "calculator",
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Check if an application is recommended in the store
val isRecommended = ApplicationsDao.isRecommendedInStore(
database = database,
appId = "com.example.app"
)
// Get all applications that are recommended in the store
val recommendedApps = ApplicationsDao.getRecommendedApplications(
database = database,
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Get all categories with localized names
val categories = CategoriesDao.getAllCategories(
database = database,
deviceLanguage = "en"
)
// Get applications by category ID
val appsByCategoryId = CategoriesDao.getApplicationsByCategoryId(
database = database,
categoryId = 1,
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Get applications by category name
val appsByCategoryName = CategoriesDao.getApplicationsByCategoryName(
database = database,
categoryName = "NAVIGATION",
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Get applications by category enum
val appsByCategory = CategoriesDao.getApplicationsByCategory(
database = database,
category = AppCategory.NAVIGATION,
deviceLanguage = "en",
creator = { id, categoryLocalizedName, appInfo ->
AppInfoWithExtras(
id = id,
categoryLocalizedName = categoryLocalizedName,
app = appInfo
)
}
)
// Get the current database version
val currentVersion = VersionDao.getCurrentVersion(database)
// Update the database version
val updateSuccess = VersionDao.updateVersion(database, "NEWVERSION")
For a simplified overview of how to use the database, please consult the example in the sample directory. The sample demonstrates basic database operations including downloading, querying, and displaying data.
β οΈ Important Warning: The sample code usesrunBlockingfor database downloads, which is prohibited in production code. This is only done for demonstration purposes. In real applications, always use proper coroutine scopes and avoid blocking the main thread.
The DAO module is actively evolving to satisfy more needs and use cases. Contributions and pull requests are welcome to enhance its functionality and performance.