From 1f8c7e46bb2b619c901c4cca3099d6d323d11251 Mon Sep 17 00:00:00 2001 From: Zachary Hall Date: Mon, 21 Oct 2024 13:28:38 -0700 Subject: [PATCH] Update Android project --- .CMakeLists.txt.swp | Bin 16384 -> 0 bytes .forgejo/workflows/compile.yaml | 6 +- sdl-android-project/.gitmodules | 28 ++ sdl-android-project/.project | 28 -- .../org.eclipse.buildship.core.prefs | 13 - sdl-android-project/app/.classpath | 6 - sdl-android-project/app/.project | 34 --- .../app/.settings/org.eclipse.jdt.core.prefs | 4 + sdl-android-project/app/build.gradle | 24 +- .../app/src/main/AndroidManifest.xml | 14 +- .../com/complecwaft/looper/MainActivity.java | 276 +++++++++++------- .../complecwaft/looper/PlaybackService.java | 57 ++++ sdl-android-project/gradle.properties | 1 + 13 files changed, 294 insertions(+), 197 deletions(-) delete mode 100644 .CMakeLists.txt.swp create mode 100644 sdl-android-project/.gitmodules delete mode 100644 sdl-android-project/.project delete mode 100644 sdl-android-project/.settings/org.eclipse.buildship.core.prefs delete mode 100644 sdl-android-project/app/.classpath delete mode 100644 sdl-android-project/app/.project create mode 100644 sdl-android-project/app/.settings/org.eclipse.jdt.core.prefs create mode 100644 sdl-android-project/app/src/main/java/com/complecwaft/looper/PlaybackService.java diff --git a/.CMakeLists.txt.swp b/.CMakeLists.txt.swp deleted file mode 100644 index 5de03fdbcd0f948ffedfc9bc460b38558366d24e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeHO+lwnn8Sg!-uCo^vS5bWG&Dn96Rz$Qj=*XNsrw< z=Qz6#DhLMzLGeFO^g&QTyuiXLsOYOGK8WaptoZ8l?t1xEcO{w2NhTf;5i9VUPFH>P z)mOjz`m6q`G6x%brmfyx+f?v*kD`3J_5S{6Z+}ba-F{5z#>J4O_j%3Sj~*AEzS@e1 z$*4b1aD6x`)_d&Ux=_46NYfLRt?PDt%&a6Y^0neK#XJqNPBI`FcytDyQSNMQZt(WE zYtO0AzBhVwRkEdIKr$d1kPJu$Bmtk20{}i8& zD1YHf{Xazgz9|3tmHNMn`nD*4^Gf|&qW%-2+!qFn?RZnv+oJw^SLz=ZjHlo&;_Izke6xfiD3=;Lpz}%CCTL051a`@Il~@Pb{A% z@FMUW@Wwk7<=4QsfzJak0V}{Q;CF9Vl#dkp_&$5~p+Sy3mQ(ATJCI=jTDO-pM9YVG+~u9u#xtGO2JJG$B2r>5<> zei&?LEbh_6WWZL+Z+Vesai6W+&ys@C@mAmUgVKVB`V|JF;mX)RCP^~*|s5V`n zwza?}J_=`<1p_S0ZBv`ruD?%PzS|CWwl`H+MmpReVo*PFLenOY33ps0*p9;HN5eEI zGW^D5B`+^w$_rNpY}7A~8fOK|`Ta#D&B)P1({+MvI*bQ{w7Y_9GQwXrgmEjh8sH%9 zU-&v0@d0t$J>PAb7NNw^8Wu6s=U>rnZI{qSWLgFd_dRm12BA-0j5JI2*`S>iM+Q4E zM~A7<;1f#=2z9+MxUn^hbEdlfjdIs}F-Rk7QPXL<^Bcpq)BdA%QTdT@tJOThp!Qt9 zVFsX^-`HMjbL$S~u)2N8G8^Kn+iFdUZP)OuXnG$Q*7lZ=!*{r&)*@wz<5I&6IPH{l zbmH+@q`DUBJEqeb&kygo^^wiHs@rU;x~A_Cwc)y!TB~tC)Cnfxb~%yNgu$lBYs?Ym zb6$yJ=0jJ%L6mnNc!YEokkjyR>hlcceRG96vBCxP*&b;vAQtQgA+agA-BMj=21nzr z`IDzv!2)V+(=aJ9_+>v_%AgqNZd}(3%9nD9uneEejz6`hRSgvMJEiz1(>aIcbfEvUjjzJuKe|~pW zK%++E#(`Il!%ag-Pl_ZR)u+Kom<44I+=*IKQpnx}1J2 z3ULjjcHmhRaoRt@EeWF*F}9B3Rzd@_~dSJxoHqd$+3Ko>)f4rWKh6 zUa`WRnU5h?G?CW~YknxbB<*_6zad@PVwvF$emk)RFI|Z0;SJL>5qA*V_7>G$2~%y} z3U_g+bJ;7yYlm7b&zdWDDL{&-;_8|u7R7l^cyo}w+PZRtOVNKuG=GTX!`F#RPS+`y zllhK$K}Ox$K=XK%6v@jhqX#^S(&Frd<#jF4998S}GM4ATSVFaUsm0>sX_3u~Y`pqs zXVb!v7lubXS(p|^4PF|JdJL%n>owR>d@o6}i2!2$s5?0AvHGN_jO!scXjvKH2jF$h z<13h2J%w1pBfJ258XlzayLaG5c(cRHp?|*K9pZQ6%SxGuoW$K@q%8HyD5w+5Llx>K z(f$-%sK^uwq!D5rVWVDhSjW5K5L9p#)oKHQa?#@1%-Z;kbGlHK>k8T-$Eu7KuUZIL zE*Gxf-kaQJk?JU+}UxJ6jW`o@D8#ShuKG zznfS0h#%m+SlwLPSldu7&1pqgpaNA_^-gD5De0m3QGPN!9ny?_`ZR&g`nc7dwXLmX zh3Ee~Xa5Pn^M9n_<>#-+^M3$*5eR|bAkY5=z<@R24aomew0n)Wl^@A~WI!??8ITM} z1|$QL0m*=5Kr$d1_zyBL$z6*$>$8G()8PqD@o1TXBkNB`c^x^V$QQk+VPPk_Oo@^2 ziZ+8}bWE#6Gr`8dHSs=Am&H%K{ - - sdl-android-project - Project sdl-android-project created by Buildship. - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.buildship.core.gradleprojectnature - - - - 1729361463965 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/sdl-android-project/.settings/org.eclipse.buildship.core.prefs b/sdl-android-project/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index 1382021..0000000 --- a/sdl-android-project/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,13 +0,0 @@ -arguments=--init-script /home/catmeow/.local/share/zed/extensions/work/java/jdt-language-server-1.40.0/configuration/org.eclipse.osgi/57/0/.cp/gradle/init/init.gradle -auto.sync=false -build.scans.enabled=false -connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) -connection.project.dir= -eclipse.preferences.version=1 -gradle.user.home= -java.home=/opt/openjdk-bin-21.0.4_p7 -jvm.arguments= -offline.mode=false -override.workspace.settings=true -show.console.view=true -show.executions.view=true diff --git a/sdl-android-project/app/.classpath b/sdl-android-project/app/.classpath deleted file mode 100644 index 0a3280e..0000000 --- a/sdl-android-project/app/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/sdl-android-project/app/.project b/sdl-android-project/app/.project deleted file mode 100644 index 7e1aa36..0000000 --- a/sdl-android-project/app/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - app - Project app created by Buildship. - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.buildship.core.gradleprojectnature - - - - 1729361463958 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/sdl-android-project/app/.settings/org.eclipse.jdt.core.prefs b/sdl-android-project/app/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e9186c3 --- /dev/null +++ b/sdl-android-project/app/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 +org.eclipse.jdt.core.compiler.source=21 diff --git a/sdl-android-project/app/build.gradle b/sdl-android-project/app/build.gradle index 982eb82..5c09d9f 100644 --- a/sdl-android-project/app/build.gradle +++ b/sdl-android-project/app/build.gradle @@ -6,7 +6,6 @@ if (buildAsApplication) { else { apply plugin: 'com.android.library' } - android { buildFeatures { prefab true @@ -19,8 +18,26 @@ android { defaultConfig { minSdkVersion 30 targetSdkVersion 34 - versionCode 1 - versionName "1.0" + def revListStdout = new ByteArrayOutputStream(); + exec { + executable "git" + commandLine "git", "rev-list", "--count", "HEAD" + standardOutput revListStdout + } + def revParseStdout = new ByteArrayOutputStream(); + def versionNameData = "" + exec { + commandLine "git", "rev-parse", "--abbref-rev", "HEAD" + standardOutput revParseStdout + } + versionNameData = revParseStdout.toString() + "-" + revParseStdout = new ByteArrayOutputStream() + exec { + commandLine "git", "rev-parse", "--short", "HEAD" + standardOutput revParseStdout + } + versionCode revListStdout.toString() as Integer + versionName versionNameData + revParseStdout.toString() externalNativeBuild { cmake { arguments "-DUSE_GLES=ON", "-DUSE_PORTALS=OFF", "-DDOWNLOAD_AUDIO_CODECS_DEPENDENCY=ON", "-DENABLE_DBUS=OFF", "-DBUILD_SDL=ON", "-DBUILD_SDL_IMAGE=ON", "-DDISABLE_GTK_UI=ON", "-DDISABLE_IMGUI_UI=OFF" @@ -66,6 +83,7 @@ android { } dependencies { + implementation "androidx.core:core:1.13.1" implementation fileTree(include: ['*.jar'], dir: 'libs') implementation group: 'com.getkeepsafe.relinker', name: 'relinker', version: '1.4.5' } diff --git a/sdl-android-project/app/src/main/AndroidManifest.xml b/sdl-android-project/app/src/main/AndroidManifest.xml index bbf805c..691b902 100644 --- a/sdl-android-project/app/src/main/AndroidManifest.xml +++ b/sdl-android-project/app/src/main/AndroidManifest.xml @@ -1,10 +1,7 @@ - + > @@ -53,13 +50,15 @@ - + + + - + = 0) { - os.write(buf, 0, len); - pos += len; - } - } catch (IOException e) { - e.printStackTrace(); - PickedFile = null; - loading = false; - return; - } - loading = false; - PickedFile = file.getAbsolutePath(); - } else { - PickedFile = null; - } - } - } - private static boolean loading; - public static boolean IsLoading() { - return loading; - } - private static String PickedFile = null; - public static String GetPickedFile() { - if (openDocumentIntent == null) { - return ""; - } else if (PickedFile == null) { - return ""; - } else { - return PickedFile; - } - } - public static void ClearSelected() { - PickedFile = null; - } +public class MainActivity extends SDLActivity { + + public static MainActivity mSingleton; + private static Intent mediaPlaybackService; + private static Intent requestPermissionLauncher; + @Override + protected void onCreate(Bundle savedInstanceState) { + if ( + this.getBaseContext().checkSelfPermission( + Manifest.permission.POST_NOTIFICATIONS + ) == + PackageManager.PERMISSION_GRANTED + ) { + this.onRequestPermissionsResult(PERMISSION_REQUEST, new String[] {Manifest.permission.POST_NOTIFICATIONS}, new int[] {PackageManager.PERMISSION_GRANTED}); + } else { + // You can directly ask for the permission. + // The registered ActivityResultCallback gets the result of this request. + this.requestPermissions( + new String[] {Manifest.permission.POST_NOTIFICATIONS}, + PERMISSION_REQUEST + ); + } + mSingleton = this; + super.onCreate(savedInstanceState); + } + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_DEFAULT; + NotificationChannel channel = new NotificationChannel( + "com.complecwaft.looper.MediaPlayback", + "Media Playback", + importance + ); + channel.setDescription( + "Notification for keeping playback in the foreground" + ); + NotificationManager notificationManager = getSystemService( + NotificationManager.class + ); + notificationManager.createNotificationChannel(channel); + } + mediaPlaybackService = new Intent(this, PlaybackService.class); + startService(mediaPlaybackService); + } + + @Override + protected void onDestroy() { + stopService(mediaPlaybackService); + super.onDestroy(); + mSingleton = null; + } + + private static Intent openDocumentIntent = null; + + public static String GetUserDir() { + return System.getProperty("user.home"); + } + + private static final int PICK_FILE = 0x33; + private static final int PERMISSION_REQUEST = 0x34; + + public static void OpenFilePicker(Object extraInitialUri) { + openDocumentIntent = new Intent(Intent.ACTION_GET_CONTENT); + openDocumentIntent.addCategory(Intent.CATEGORY_OPENABLE); + openDocumentIntent.setType("*/*"); + if (extraInitialUri instanceof String) { + openDocumentIntent.putExtra( + DocumentsContract.EXTRA_INITIAL_URI, + (String) extraInitialUri + ); + } + if ( + openDocumentIntent.resolveActivity( + mSingleton.getPackageManager() + ) != + null + ) { + mSingleton.startActivityForResult( + Intent.createChooser(openDocumentIntent, "Open a file..."), + PICK_FILE + ); + } else { + Log.d("Looper", "Unable to resolve Intent.ACTION_OPEN_DOCUMENT {}"); + } + } + + @Override + public void onActivityResult( + int requestCode, + int resultCode, + Intent resultData + ) { + if (requestCode == PICK_FILE && resultCode == RESULT_OK) { + Uri uri = null; + if (resultData != null) { + uri = resultData.getData(); + InputStream input = null; + loading = true; + try { + input = getApplication() + .getContentResolver() + .openInputStream(uri); + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + PickedFile = null; + + loading = false; + return; + } + File file = new File(getCacheDir(), uri.getLastPathSegment()); + try { + file.getParentFile().mkdirs(); + file.createNewFile(); + FileOutputStream os = null; + os = new FileOutputStream(file); + int len = 0; + int pos = 0; + byte[] buf = new byte[1024 * 4]; + + while ((len = input.read(buf)) >= 0) { + os.write(buf, 0, len); + pos += len; + } + } catch (IOException e) { + e.printStackTrace(); + PickedFile = null; + loading = false; + return; + } + loading = false; + PickedFile = file.getAbsolutePath(); + } else { + PickedFile = null; + } + } + } + + private static boolean loading; + + public static boolean IsLoading() { + return loading; + } + + private static String PickedFile = null; + + public static String GetPickedFile() { + if (openDocumentIntent == null) { + return ""; + } else if (PickedFile == null) { + return ""; + } else { + return PickedFile; + } + } + + public static void ClearSelected() { + PickedFile = null; + } } diff --git a/sdl-android-project/app/src/main/java/com/complecwaft/looper/PlaybackService.java b/sdl-android-project/app/src/main/java/com/complecwaft/looper/PlaybackService.java new file mode 100644 index 0000000..5dee927 --- /dev/null +++ b/sdl-android-project/app/src/main/java/com/complecwaft/looper/PlaybackService.java @@ -0,0 +1,57 @@ +package com.complecwaft.looper; + +import android.app.ForegroundServiceStartNotAllowedException; +import android.app.Notification; +import android.app.Service; +import android.content.Intent; +import android.content.pm.ServiceInfo; +import android.os.Build; +import android.os.Binder; +import android.os.IBinder; +import androidx.core.app.NotificationCompat; +import androidx.core.app.ServiceCompat; + +public class PlaybackService extends Service { + + private void startForeground() { + try { + Notification notification = new NotificationCompat.Builder( + this, + "com.complecwaft.looper.MediaPlayback" + ).build(); + int type = 0; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + type = ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK; + } + ServiceCompat.startForeground( + this, + 100, // Cannot be 0 + notification, + type + ); + } catch (Exception e) { + if ( + Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && + e instanceof ForegroundServiceStartNotAllowedException + ) { + // App not in a valid state to start foreground service + // (e.g started from bg) + } + } + } + + @Override + public void onCreate() { + startForeground(); + } + + @Override + public void onDestroy() { + ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE); + } + + @Override + public IBinder onBind(Intent arg0) { + return new Binder(); + } +} diff --git a/sdl-android-project/gradle.properties b/sdl-android-project/gradle.properties index 3390091..a8b3067 100644 --- a/sdl-android-project/gradle.properties +++ b/sdl-android-project/gradle.properties @@ -16,3 +16,4 @@ ndk_version=27.2.12479018 # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true +android.useAndroidX=true \ No newline at end of file