| #!/bin/bash |
| |
| |
| set -e |
|
|
| WORK_DIR="$1" |
| APP_NAME="$2" |
| PKG_NAME="$3" |
| KEYSTORE="$4" |
|
|
| ANDROID_SDK=/opt/android-sdk |
| BUILD_TOOLS=$ANDROID_SDK/build-tools/33.0.0 |
| PLATFORM=$ANDROID_SDK/platforms/android-33 |
|
|
| echo "[HtStudio Java APK] Başlıyor: $APP_NAME ($PKG_NAME)" |
|
|
| |
| mkdir -p "$WORK_DIR/src/$( echo $PKG_NAME | tr '.' '/' )" |
| mkdir -p "$WORK_DIR/res/layout" |
| mkdir -p "$WORK_DIR/res/values" |
| mkdir -p "$WORK_DIR/res/mipmap-mdpi" "$WORK_DIR/res/mipmap-hdpi" "$WORK_DIR/res/mipmap-xhdpi" "$WORK_DIR/res/mipmap-xxhdpi" "$WORK_DIR/res/mipmap-xxxhdpi" |
| mkdir -p "$WORK_DIR/bin" |
| mkdir -p "$WORK_DIR/obj" |
| mkdir -p "$WORK_DIR/gen" |
| mkdir -p "$WORK_DIR/assets" |
|
|
| |
| |
| |
| |
| if [ -f "$WORK_DIR/has_logo" ]; then |
| echo "[HtStudio Java APK] Kullanıcı logosu kullanılıyor" |
| cp "$WORK_DIR/icons/mipmap-mdpi/ic_launcher.png" "$WORK_DIR/res/mipmap-mdpi/ic_launcher.png" |
| cp "$WORK_DIR/icons/mipmap-hdpi/ic_launcher.png" "$WORK_DIR/res/mipmap-hdpi/ic_launcher.png" |
| cp "$WORK_DIR/icons/mipmap-xhdpi/ic_launcher.png" "$WORK_DIR/res/mipmap-xhdpi/ic_launcher.png" |
| cp "$WORK_DIR/icons/mipmap-xxhdpi/ic_launcher.png" "$WORK_DIR/res/mipmap-xxhdpi/ic_launcher.png" |
| cp "$WORK_DIR/icons/mipmap-xxxhdpi/ic_launcher.png" "$WORK_DIR/res/mipmap-xxxhdpi/ic_launcher.png" |
| else |
| echo "[HtStudio Java APK] Varsayılan ikon kullanılıyor" |
| cp /opt/default_icons/mdpi/ic_launcher.png "$WORK_DIR/res/mipmap-mdpi/ic_launcher.png" |
| cp /opt/default_icons/hdpi/ic_launcher.png "$WORK_DIR/res/mipmap-hdpi/ic_launcher.png" |
| cp /opt/default_icons/xhdpi/ic_launcher.png "$WORK_DIR/res/mipmap-xhdpi/ic_launcher.png" |
| cp /opt/default_icons/xxhdpi/ic_launcher.png "$WORK_DIR/res/mipmap-xxhdpi/ic_launcher.png" |
| cp /opt/default_icons/xxxhdpi/ic_launcher.png "$WORK_DIR/res/mipmap-xxxhdpi/ic_launcher.png" |
| fi |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| SRC_DIR="$WORK_DIR/src/$( echo $PKG_NAME | tr '.' '/' )" |
|
|
| |
| |
| |
| if grep -q "^package " "$WORK_DIR/Main.java"; then |
| sed -i "s/^package .*/package ${PKG_NAME};/" "$WORK_DIR/Main.java" |
| else |
| sed -i "1i package ${PKG_NAME};" "$WORK_DIR/Main.java" |
| fi |
|
|
| if grep -qE "class[[:space:]]+MainActivity\b" "$WORK_DIR/Main.java"; then |
| echo "[HtStudio Java APK] Tam Activity modu (kullanıcı kendi MainActivity'sini yazmış)" |
| cp "$WORK_DIR/Main.java" "$SRC_DIR/MainActivity.java" |
| else |
| echo "[HtStudio Java APK] Konsol modu (Main.main() çıktısı sarmalanıyor)" |
| cp "$WORK_DIR/Main.java" "$SRC_DIR/Main.java" |
|
|
| cat > "$SRC_DIR/MainActivity.java" << JAVA |
| package $PKG_NAME; |
| |
| import android.app.Activity; |
| import android.os.Bundle; |
| import android.widget.ScrollView; |
| import android.widget.TextView; |
| import java.io.ByteArrayOutputStream; |
| import java.io.PrintStream; |
| |
| public class MainActivity extends Activity { |
| @Override |
| protected void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| ScrollView sv = new ScrollView(this); |
| TextView tv = new TextView(this); |
| tv.setPadding(32, 32, 32, 32); |
| tv.setTextSize(14f); |
| tv.setTextColor(0xFFCDD6F4); |
| tv.setBackgroundColor(0xFF1E1E2E); |
| tv.setTypeface(android.graphics.Typeface.MONOSPACE); |
| sv.addView(tv); |
| setContentView(sv); |
| sv.setBackgroundColor(0xFF1E1E2E); |
| |
| // Kullanıcının main metodunu çalıştır, stdout'u yakala |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| PrintStream ps = new PrintStream(baos); |
| PrintStream old = System.out; |
| System.setOut(ps); |
| try { |
| Main.main(new String[]{}); |
| } catch (Exception e) { |
| System.out.println("Hata: " + e.getMessage()); |
| } finally { |
| System.out.flush(); |
| System.setOut(old); |
| } |
| tv.setText(baos.toString()); |
| } |
| } |
| JAVA |
| fi |
|
|
| |
| cat > "$WORK_DIR/AndroidManifest.xml" << XML |
| <?xml version="1.0" encoding="utf-8"?> |
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| package="$PKG_NAME" |
| android:versionCode="1" |
| android:versionName="1.0"> |
| <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33"/> |
| <application android:label="$APP_NAME" android:icon="@mipmap/ic_launcher" android:allowBackup="true"> |
| <activity android:name=".MainActivity" android:exported="true" |
| android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> |
| <intent-filter> |
| <action android:name="android.intent.action.MAIN"/> |
| <category android:name="android.intent.category.LAUNCHER"/> |
| </intent-filter> |
| </activity> |
| </application> |
| </manifest> |
| XML |
|
|
| |
| $BUILD_TOOLS/aapt2 compile --dir "$WORK_DIR/res" -o "$WORK_DIR/res_compiled.zip" 2>&1 |
| $BUILD_TOOLS/aapt2 link \ |
| --manifest "$WORK_DIR/AndroidManifest.xml" \ |
| -I "$PLATFORM/android.jar" \ |
| --java "$WORK_DIR/gen" \ |
| -A "$WORK_DIR/assets" \ |
| -o "$WORK_DIR/resources.apk" \ |
| "$WORK_DIR/res_compiled.zip" \ |
| --auto-add-overlay 2>&1 |
|
|
| echo "[HtStudio Java APK] javac ile derleniyor..." |
|
|
| |
| find "$WORK_DIR/src" -name "*.java" > "$WORK_DIR/sources.txt" |
| find "$WORK_DIR/gen" -name "*.java" >> "$WORK_DIR/sources.txt" 2>/dev/null || true |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| mkdir -p "$WORK_DIR/libs_extracted" |
| for AAR in "$WORK_DIR"/libs/*.aar; do |
| [ -e "$AAR" ] || continue |
| AAR_NAME=$(basename "$AAR" .aar) |
| echo "[HtStudio Java APK] AAR açılıyor: $AAR_NAME" |
| TMP_EXTRACT="$WORK_DIR/libs_extracted/${AAR_NAME}_tmp" |
| mkdir -p "$TMP_EXTRACT" |
| unzip -o -q "$AAR" classes.jar -d "$TMP_EXTRACT" 2>&1 || true |
| if [ -f "$TMP_EXTRACT/classes.jar" ]; then |
| mv "$TMP_EXTRACT/classes.jar" "$WORK_DIR/libs_extracted/${AAR_NAME}.jar" |
| else |
| echo "[UYARI] $AAR_NAME.aar içinde classes.jar bulunamadı, atlanıyor" |
| fi |
| rm -rf "$TMP_EXTRACT" |
| done |
|
|
| LIB_JARS=$(find "$WORK_DIR/libs" "$WORK_DIR/libs_extracted" -name "*.jar" 2>/dev/null | tr '\n' ':') |
| if [ -n "$LIB_JARS" ]; then |
| echo "[HtStudio Java APK] Kütüphaneler classpath'e ekleniyor: $LIB_JARS" |
| CLASSPATH="$PLATFORM/android.jar:${LIB_JARS}" |
| else |
| CLASSPATH="$PLATFORM/android.jar" |
| fi |
|
|
| javac -source 8 -target 8 \ |
| -cp "$CLASSPATH" \ |
| -d "$WORK_DIR/obj" \ |
| @"$WORK_DIR/sources.txt" 2>&1 |
|
|
| echo "[HtStudio Java APK] d8 ile dex oluşturuluyor..." |
| |
| |
| |
| |
| $BUILD_TOOLS/d8 \ |
| --lib "$PLATFORM/android.jar" \ |
| --output "$WORK_DIR/bin" \ |
| $(find "$WORK_DIR/obj" -name "*.class") \ |
| $(find "$WORK_DIR/libs" "$WORK_DIR/libs_extracted" -name "*.jar" 2>/dev/null) 2>&1 |
|
|
| echo "[HtStudio Java APK] APK paketleniyor..." |
| cd "$WORK_DIR" |
| cp resources.apk unsigned.apk 2>/dev/null || $BUILD_TOOLS/aapt package -f \ |
| -M AndroidManifest.xml \ |
| -I "$PLATFORM/android.jar" \ |
| -F unsigned.apk 2>&1 |
|
|
| |
| zip -j unsigned.apk bin/classes.dex 2>&1 |
|
|
| echo "[HtStudio Java APK] Hizalanıyor (zipalign)..." |
| $BUILD_TOOLS/zipalign -f -p 4 unsigned.apk aligned.apk 2>&1 |
| mv aligned.apk unsigned.apk |
|
|
| echo "[HtStudio Java APK] İmzalanıyor..." |
| $BUILD_TOOLS/apksigner sign \ |
| --ks "$KEYSTORE" \ |
| --ks-pass pass:android \ |
| --key-pass pass:android \ |
| --ks-key-alias androiddebugkey \ |
| --out output.apk \ |
| unsigned.apk 2>&1 |
|
|
| echo "[HtStudio Java APK] Başarılı: $WORK_DIR/output.apk" |
|
|