Androidlanat / app.py
Akwbw's picture
Update app.py
e6abcb7 verified
import streamlit as st
import os
import zipfile
import subprocess
import shutil
# Page Config
st.set_page_config(page_title="Android Build Server", layout="centered")
st.title("πŸ“± Android APK Generator (Final Production)")
st.markdown("Zip upload karein. Server APK banayega aur **Auto-Sign** karega.")
# --- HELPER: GENERATE KEY ---
def generate_keystore():
keystore_path = "debug.keystore"
if not os.path.exists(keystore_path):
cmd = [
"keytool", "-genkey", "-v",
"-keystore", keystore_path,
"-storepass", "android",
"-alias", "androiddebugkey",
"-keypass", "android",
"-keyalg", "RSA",
"-keysize", "2048",
"-validity", "10000",
"-dname", "CN=AndroidDebug,O=Android,C=US"
]
subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return keystore_path
uploaded_file = st.file_uploader("Project ZIP File Upload Karein", type=["zip"])
if uploaded_file is not None:
if st.button("πŸ”¨ Create & Sign APK"):
status_text = st.empty()
progress_bar = st.progress(0)
# 1. Cleanup
if os.path.exists("project_extract"):
shutil.rmtree("project_extract")
os.makedirs("project_extract", exist_ok=True)
# 2. Extract
status_text.info("Extracting ZIP file...")
with open("uploaded_project.zip", "wb") as f:
f.write(uploaded_file.getbuffer())
with zipfile.ZipFile("uploaded_project.zip", "r") as zip_ref:
zip_ref.extractall("project_extract")
progress_bar.progress(20)
# 3. Find Root
project_root = None
for root, dirs, files in os.walk("project_extract"):
if "gradlew" in files:
project_root = root
break
if not project_root:
st.error("❌ ZIP file mein 'gradlew' nahi mila.")
else:
# 4. Permissions
status_text.info("Setting up Gradle...")
gradlew_path = os.path.join(project_root, "gradlew")
subprocess.run(["chmod", "+x", gradlew_path])
# 5. Build
status_text.info("Building APK... (Wait karein)")
# Hum assembleRelease chala rahe hain
build_cmd = ["./gradlew", "assembleRelease", "--no-daemon", "--stacktrace"]
try:
result = subprocess.run(
build_cmd,
cwd=project_root,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
progress_bar.progress(60)
if result.returncode == 0:
status_text.info("βœ… Build Successful! Signing APK...")
# 6. Find Unsigned APK
unsigned_apk = None
for root, dirs, files in os.walk(project_root):
for file in files:
if file.endswith(".apk") and "release" in file:
unsigned_apk = os.path.join(root, file)
break
if unsigned_apk:
# 7. SIGNING (Direct System Commands)
keystore = generate_keystore()
signed_apk_name = "Installable_App.apk"
aligned_apk = "aligned.apk"
# Step A: ZipAlign (Important for installation)
try:
subprocess.run(["zipalign", "-v", "-p", "4", unsigned_apk, aligned_apk],
stdout=subprocess.DEVNULL, check=True)
apk_to_sign = aligned_apk
except:
# Agar align fail ho, to original use kar lo
apk_to_sign = unsigned_apk
# Step B: APKSigner
sign_cmd = [
"apksigner", "sign",
"--ks", keystore,
"--ks-pass", "pass:android",
"--out", signed_apk_name,
apk_to_sign
]
sign_result = subprocess.run(sign_cmd, capture_output=True, text=True)
if sign_result.returncode == 0:
status_text.success("πŸŽ‰ APK Signed & Ready to Install!")
progress_bar.progress(100)
with open(signed_apk_name, "rb") as f:
st.download_button(
label="⬇️ Download Installable APK",
data=f,
file_name=signed_apk_name,
mime="application/vnd.android.package-archive"
)
else:
st.error("Build hui magar Signing fail hogayi.")
st.text_area("Signing Log", sign_result.stderr)
else:
st.error("APK file generate nahi hui.")
else:
st.error("❌ Build Failed!")
st.text_area("Error Log", result.stderr, height=300)
except Exception as e:
st.error(f"System Error: {str(e)}")
if os.path.exists("uploaded_project.zip"):
os.remove("uploaded_project.zip")