Carved out from the app-store monorepo. Kotlin + Material 3 client that browses the private distribution server and installs APKs via PackageInstaller. Keystore password redacted from docs.
3.1 KiB
Upload Android App to Local App Store (Remote)
Use this skill to upload a built Android APK to the Local App Store server remotely via HTTP. The server is at 192.168.8.128:9800.
Prerequisites
- A signed release APK file (
.apk) curlavailable on the machine running this skill
Step 1: Create Metadata JSON
Create a JSON file with app metadata. All fields except screenshots are required:
{
"name": "App Display Name",
"description": "One or two sentences describing the app.",
"icon": null,
"screenshots": [],
"package_name": "com.your.package",
"version_name": "1.0",
"version_code": 1,
"min_sdk": 26,
"target_sdk": 34,
"permissions": ["android.permission.INTERNET"]
}
Note: version_code, min_sdk, and target_sdk can be integers or strings — the server converts them automatically.
Field notes:
name: Human-readable display name shown in the storedescription: Short description shown in app detailsicon:nullif no PNG icon in the APK, otherwise the resource path inside the APK (e.g.,res/drawable-mdpi/ic_launcher.png). If the APK only has XML vector drawables, usenull.package_name: Must matchapplicationIdinbuild.gradleversion_name/version_code: Must matchbuild.gradledefaultConfigmin_sdk/target_sdk: Must matchbuild.gradledefaultConfigpermissions: Array of<uses-permission android:name="..." />values fromAndroidManifest.xml, or[]if nonescreenshots:[]unless you have screenshot PNG files to upload separately
Save this as metadata.json.
Step 2: Choose App ID
Pick a lowercase, hyphen-separated ID for the app (e.g., my-app, hello-world, flappy-bird). This becomes the app's identifier in the store.
Step 3: Upload via curl
curl -X POST http://192.168.8.128:9800/api/upload \
-F "apk=@/path/to/app-release.apk" \
-F "app_id=YOUR_APP_ID" \
-F "metadata=@/path/to/metadata.json"
Expected response (HTTP 200):
{
"id": "YOUR_APP_ID",
"name": "App Display Name",
"package_name": "com.your.package",
"version_name": "1.0",
"version_code": "1",
"message": "App 'YOUR_APP_ID' uploaded successfully"
}
Error responses:
400— Metadata JSON is missing required fields (name,description) or APK is invalid409— Same app_id + version_code already exists in the store (use a different app_id or bump version)
Step 4: Verify
curl -s http://192.168.8.128:9800/api/apps | python3 -c "
import json, sys
data = json.load(sys.stdin)
for app in data['apps']:
if app['id'] == 'YOUR_APP_ID':
print('SUCCESS: Found', app['name'], '(v' + app['version_name'] + ')')
sys.exit(0)
print('FAILURE: App not found')
"
Updating an Existing App
To push a new version of an existing app, use the same app_id but with updated version_name and version_code in the metadata JSON. The server will replace the APK if the new version_code is higher.
Download the Uploaded APK (Optional)
After upload, the APK is also available for browser download at:
http://192.168.8.128:9800/dl/YOUR_APP_ID.apk