Update Android project
Some checks failed
Build / build-appimage (push) Blocked by required conditions
Build / build-android (push) Blocked by required conditions
Build / build-windows (push) Blocked by required conditions
Build / download-system-deps (push) Successful in 47s
Build / build-gentoo (push) Successful in 1m8s
Build / get-source-code (push) Has been cancelled
Some checks failed
Build / build-appimage (push) Blocked by required conditions
Build / build-android (push) Blocked by required conditions
Build / build-windows (push) Blocked by required conditions
Build / download-system-deps (push) Successful in 47s
Build / build-gentoo (push) Successful in 1m8s
Build / get-source-code (push) Has been cancelled
This commit is contained in:
parent
fda208e643
commit
1f8c7e46bb
13 changed files with 294 additions and 197 deletions
Binary file not shown.
|
@ -9,7 +9,7 @@ jobs:
|
||||||
- name: Download and cache system dependencies
|
- name: Download and cache system dependencies
|
||||||
uses: https://complecwaft.com/catmeow/cache-apt-pkgs-action@latest
|
uses: https://complecwaft.com/catmeow/cache-apt-pkgs-action@latest
|
||||||
with:
|
with:
|
||||||
packages: zstd cmake build-essential python3 python3-pip python3-venv wget gcc-mingw-w64 g++-mingw-w64 ninja-build binutils-mingw-w64-x86_64
|
packages: zstd cmake build-essential python3 python3-pip python3-venv wget gcc-mingw-w64 g++-mingw-w64 ninja-build binutils-mingw-w64-x86-64
|
||||||
version: 1.0
|
version: 1.0
|
||||||
get-source-code:
|
get-source-code:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -137,7 +137,7 @@ jobs:
|
||||||
- name: Download and cache system dependencies
|
- name: Download and cache system dependencies
|
||||||
uses: https://complecwaft.com/catmeow/cache-apt-pkgs-action@latest
|
uses: https://complecwaft.com/catmeow/cache-apt-pkgs-action@latest
|
||||||
with:
|
with:
|
||||||
packages: zstd cmake build-essential gcc-mingw-w64 g++-mingw-w64 ninja-build binutils-mingw-w64-x86_64
|
packages: zstd cmake build-essential gcc-mingw-w64 g++-mingw-w64 ninja-build binutils-mingw-w64-x86-64
|
||||||
version: 1.0
|
version: 1.0
|
||||||
- name: Download repository code
|
- name: Download repository code
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
|
@ -154,7 +154,7 @@ jobs:
|
||||||
- name: Build protoc
|
- name: Build protoc
|
||||||
run: ./build-protoc.sh
|
run: ./build-protoc.sh
|
||||||
- name: Build with CMake
|
- name: Build with CMake
|
||||||
run: mkdir -p build-windows && cd build-windows && cmake .. -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-gcc -G Ninja -DDISABLE_GTK_UI=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_LIBFMT=ON -DUSE_PORTALS=OFF -DENABLE_DBUS=OFF -DBUILD_STATIC=ON -DDOWNLOAD_AUDIO_CODECS_DEPENDENCY=ON -DSDL_MIXER_X_SHARED=OFF -DSDL_MIXER_X_STATIC=ON -DUSE_OGG_VORBIS_STB=ON -DUSE_OPUS=OFF -DUSE_MODPLUG=OFF -DUSE_GME=OFF -DUSE_WAVPACK=OFF -DUSE_XMP=OFF -DUSE_MIDI_EDMIDI=OFF -DUSE_SYSTEM_SDL2=ON -DBUILD_PROTOC=OFF -DBUILD_SDL=ON -DBUILD_SDL_IMAGE=ON -DBUILD_JSONCPP=ON -DBUILD_SOUNDTOUCH=ON -DBUILD_PROTOBUF=ON -DDISABLE_IMGUI_UI=OFF -D BUILD_FMT=ON && env PATH="/usr/x86_64-w64-mingw32/bin:$PATH" ninja && cd ..
|
run: mkdir -p build-windows && cd build-windows && cmake .. -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-gcc -G Ninja -DDISABLE_GTK_UI=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_LIBFMT=ON -DUSE_PORTALS=OFF -DENABLE_DBUS=OFF -DBUILD_STATIC=ON -DDOWNLOAD_AUDIO_CODECS_DEPENDENCY=ON -DSDL_MIXER_X_SHARED=OFF -DSDL_MIXER_X_STATIC=ON -DUSE_OGG_VORBIS_STB=ON -DUSE_OPUS=OFF -DUSE_MODPLUG=OFF -DUSE_GME=OFF -DUSE_WAVPACK=OFF -DUSE_XMP=OFF -DUSE_MIDI_EDMIDI=OFF -DUSE_SYSTEM_SDL2=ON -DBUILD_PROTOC=OFF -DBUILD_SDL=ON -DBUILD_SDL_IMAGE=ON -DBUILD_JSONCPP=ON -DBUILD_SOUNDTOUCH=ON -DBUILD_PROTOBUF=ON -DDISABLE_IMGUI_UI=OFF -D BUILD_FMT=ON && ninja && cd ..
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
|
|
28
sdl-android-project/.gitmodules
vendored
Normal file
28
sdl-android-project/.gitmodules
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
[submodule "../backends/ui/imgui/imgui"]
|
||||||
|
commit = 99109c0b3b052cffa154a9295440f68868a39f74
|
||||||
|
[submodule "../subprojects/SDL"]
|
||||||
|
commit = 79ec168f3c1e2fe27335cb8886439f7ef676fb49
|
||||||
|
[submodule "../subprojects/SDL-Mixer-X"]
|
||||||
|
commit = 22aed1f6bcfa6912a34d3241edf3bd90498a6bc2
|
||||||
|
[submodule "../subprojects/SDL_image"]
|
||||||
|
commit = abcf63aa71b4e3ac32120fa9870a6500ddcdcc89
|
||||||
|
[submodule "../subprojects/fmt"]
|
||||||
|
commit = 0379bf3a5d52d8542aec1874677c9df5ff9ba5f9
|
||||||
|
[submodule "../subprojects/googletest"]
|
||||||
|
commit = 6dae7eb4a5c3a169f3e298392bff4680224aa94a
|
||||||
|
[submodule "../subprojects/grpc"]
|
||||||
|
commit = e821cdc231bda9ee93139a6daab6311dd8953832
|
||||||
|
[submodule "../subprojects/jsoncpp"]
|
||||||
|
commit = 8214f717e7c7d361f002b6c3d1b1086ddd096315
|
||||||
|
[submodule "../subprojects/libintl-lite"]
|
||||||
|
commit = 44035a0c3fe20ef28f071b35b9f5a653fbfe5e6d
|
||||||
|
[submodule "../subprojects/oboe"]
|
||||||
|
commit = 86165b8249bc22b9ef70b69e20323244b6f08d88
|
||||||
|
[submodule "../subprojects/protobuf"]
|
||||||
|
commit = 63def39e881afa496502d9c410f4ea948e59490d
|
||||||
|
[submodule "../subprojects/protobuf-c"]
|
||||||
|
commit = 8c201f6e47a53feaab773922a743091eb6c8972a
|
||||||
|
[submodule "../subprojects/soundtouch"]
|
||||||
|
commit = e83424d5928ab8513d2d082779c275765dee31b9
|
||||||
|
[submodule "../subprojects/vgmstream"]
|
||||||
|
commit = 1d836a3693541811d4a5089cf8c68d6acd4b1eeb
|
|
@ -1,28 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>sdl-android-project</name>
|
|
||||||
<comment>Project sdl-android-project created by Buildship.</comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
|
||||||
</natures>
|
|
||||||
<filteredResources>
|
|
||||||
<filter>
|
|
||||||
<id>1729361463965</id>
|
|
||||||
<name></name>
|
|
||||||
<type>30</type>
|
|
||||||
<matcher>
|
|
||||||
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
|
||||||
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
|
||||||
</matcher>
|
|
||||||
</filter>
|
|
||||||
</filteredResources>
|
|
||||||
</projectDescription>
|
|
|
@ -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
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<classpath>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21/"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
|
||||||
<classpathentry kind="output" path="bin/default"/>
|
|
||||||
</classpath>
|
|
|
@ -1,34 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>app</name>
|
|
||||||
<comment>Project app created by Buildship.</comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
||||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
|
||||||
</natures>
|
|
||||||
<filteredResources>
|
|
||||||
<filter>
|
|
||||||
<id>1729361463958</id>
|
|
||||||
<name></name>
|
|
||||||
<type>30</type>
|
|
||||||
<matcher>
|
|
||||||
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
|
||||||
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
|
||||||
</matcher>
|
|
||||||
</filter>
|
|
||||||
</filteredResources>
|
|
||||||
</projectDescription>
|
|
|
@ -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
|
|
@ -6,7 +6,6 @@ if (buildAsApplication) {
|
||||||
else {
|
else {
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
prefab true
|
prefab true
|
||||||
|
@ -19,8 +18,26 @@ android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 30
|
minSdkVersion 30
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionCode 1
|
def revListStdout = new ByteArrayOutputStream();
|
||||||
versionName "1.0"
|
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 {
|
externalNativeBuild {
|
||||||
cmake {
|
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"
|
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 {
|
dependencies {
|
||||||
|
implementation "androidx.core:core:1.13.1"
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation group: 'com.getkeepsafe.relinker', name: 'relinker', version: '1.4.5'
|
implementation group: 'com.getkeepsafe.relinker', name: 'relinker', version: '1.4.5'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Replace com.test.game with the identifier of your game below, e.g.
|
|
||||||
com.gamemaker.game
|
|
||||||
-->
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto"
|
||||||
package="com.complecwaft.looper">
|
>
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
<action android:name="android.intent.action.OPEN_DOCUMENT" />
|
<action android:name="android.intent.action.OPEN_DOCUMENT" />
|
||||||
|
@ -53,7 +50,9 @@
|
||||||
|
|
||||||
<!-- Allow access to the vibrator -->
|
<!-- Allow access to the vibrator -->
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||||
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||||
<!-- if you want to capture audio, uncomment this. -->
|
<!-- if you want to capture audio, uncomment this. -->
|
||||||
<!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
|
<!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
|
||||||
|
|
||||||
|
@ -70,6 +69,7 @@
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
android:hardwareAccelerated="true" >
|
android:hardwareAccelerated="true" >
|
||||||
|
<service android:name="com.complecwaft.looper.PlaybackService" android:foregroundServiceType="mediaPlayback" android:exported="false" />
|
||||||
|
|
||||||
<!-- Example of setting SDL hints from AndroidManifest.xml:
|
<!-- Example of setting SDL hints from AndroidManifest.xml:
|
||||||
<meta-data android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK" android:value="0"/>
|
<meta-data android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK" android:value="0"/>
|
||||||
|
|
|
@ -1,114 +1,184 @@
|
||||||
package com.complecwaft.looper;
|
package com.complecwaft.looper;
|
||||||
|
|
||||||
import android.content.ContentUris;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.provider.DocumentsContract;
|
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.libsdl.app.SDLActivity;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.Objects;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
public class MainActivity extends SDLActivity
|
|
||||||
{
|
|
||||||
public static MainActivity mSingleton;
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
mSingleton = this;
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
}
|
|
||||||
private static Intent openDocumentIntent = null;
|
|
||||||
public static String GetUserDir() {
|
|
||||||
return System.getProperty("user.home");
|
|
||||||
}
|
|
||||||
private static final int PICK_FILE = 0x33;
|
|
||||||
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 {}");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
import org.libsdl.app.SDLActivity;
|
||||||
@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;
|
import android.Manifest;
|
||||||
return;
|
import android.app.NotificationChannel;
|
||||||
}
|
import android.app.NotificationManager;
|
||||||
File file = new File(getCacheDir(), uri.getLastPathSegment());
|
import android.content.Context;
|
||||||
try {
|
import android.content.Intent;
|
||||||
file.getParentFile().mkdirs();
|
import android.content.pm.PackageManager;
|
||||||
file.createNewFile();
|
import android.net.Uri;
|
||||||
FileOutputStream os = null;
|
import android.os.Build;
|
||||||
os = new FileOutputStream(file);
|
import android.os.Bundle;
|
||||||
int len = 0;
|
import android.provider.DocumentsContract;
|
||||||
int pos = 0;
|
import android.util.Log;
|
||||||
byte[] buf = new byte[1024*4];
|
import androidx.core.app.NotificationCompat.Builder;
|
||||||
|
import androidx.core.app.ServiceCompat;
|
||||||
|
|
||||||
while ((len = input.read(buf)) >= 0) {
|
public class MainActivity extends SDLActivity {
|
||||||
os.write(buf, 0, len);
|
|
||||||
pos += len;
|
public static MainActivity mSingleton;
|
||||||
}
|
private static Intent mediaPlaybackService;
|
||||||
} catch (IOException e) {
|
private static Intent requestPermissionLauncher;
|
||||||
e.printStackTrace();
|
@Override
|
||||||
PickedFile = null;
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
loading = false;
|
if (
|
||||||
return;
|
this.getBaseContext().checkSelfPermission(
|
||||||
}
|
Manifest.permission.POST_NOTIFICATIONS
|
||||||
loading = false;
|
) ==
|
||||||
PickedFile = file.getAbsolutePath();
|
PackageManager.PERMISSION_GRANTED
|
||||||
} else {
|
) {
|
||||||
PickedFile = null;
|
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.
|
||||||
private static boolean loading;
|
this.requestPermissions(
|
||||||
public static boolean IsLoading() {
|
new String[] {Manifest.permission.POST_NOTIFICATIONS},
|
||||||
return loading;
|
PERMISSION_REQUEST
|
||||||
}
|
);
|
||||||
private static String PickedFile = null;
|
}
|
||||||
public static String GetPickedFile() {
|
mSingleton = this;
|
||||||
if (openDocumentIntent == null) {
|
super.onCreate(savedInstanceState);
|
||||||
return "";
|
}
|
||||||
} else if (PickedFile == null) {
|
@Override
|
||||||
return "";
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
} else {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
return PickedFile;
|
int importance = NotificationManager.IMPORTANCE_DEFAULT;
|
||||||
}
|
NotificationChannel channel = new NotificationChannel(
|
||||||
}
|
"com.complecwaft.looper.MediaPlayback",
|
||||||
public static void ClearSelected() {
|
"Media Playback",
|
||||||
PickedFile = null;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,3 +16,4 @@ ndk_version=27.2.12479018
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# 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
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
# org.gradle.parallel=true
|
# org.gradle.parallel=true
|
||||||
|
android.useAndroidX=true
|
Loading…
Reference in a new issue