Loading app/build.gradle +2 −2 Original line number Diff line number Diff line apply plugin: 'com.android.application' android { compileSdkVersion 29 compileSdkVersion 30 defaultConfig { applicationId "org.lineageos.recorder" minSdkVersion 29 targetSdkVersion 29 targetSdkVersion 30 versionCode 1 versionName "1.1" } Loading app/src/main/java/org/lineageos/recorder/ListActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public class ListActivity extends AppCompatActivity implements RecordingItemCall } }); Utils.setFullScreen(coordinatorLayout); Utils.setFullScreen(getWindow(), coordinatorLayout); Utils.setVerticalInsets(listView); } Loading app/src/main/java/org/lineageos/recorder/RecorderActivity.java +3 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.telephony.TelephonyManager; import android.view.View; import android.widget.ImageView; Loading Loading @@ -108,7 +109,7 @@ public class RecorderActivity extends AppCompatActivity implements mSoundList.setOnClickListener(v -> openList()); mSettings.setOnClickListener(v -> openSettings()); Utils.setFullScreen(mainView); Utils.setFullScreen(getWindow(), mainView); Utils.setVerticalInsets(mainView); mPrefs = getSharedPreferences(Utils.PREFS, 0); Loading Loading @@ -204,7 +205,7 @@ public class RecorderActivity extends AppCompatActivity implements private void toggleAfterPermissionRequest(int requestCode) { if (requestCode == REQUEST_SOUND_REC_PERMS) { bindSoundRecService(); new Handler().postDelayed(this::toggleSoundRecorder, 500); new Handler(Looper.getMainLooper()).postDelayed(this::toggleSoundRecorder, 500); } } Loading app/src/main/java/org/lineageos/recorder/utils/MediaProviderHelper.java +58 −55 Original line number Diff line number Diff line Loading @@ -20,7 +20,8 @@ import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; import android.os.Looper; import android.os.ParcelFileDescriptor; import android.provider.MediaStore; import android.util.Log; Loading @@ -39,6 +40,14 @@ import java.nio.file.Files; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; public final class MediaProviderHelper { private static final String TAG = "MediaProviderHelper"; Loading @@ -46,6 +55,8 @@ public final class MediaProviderHelper { private static final String MY_RECORDS_SORT = MediaStore.Audio.Media.DATE_ADDED + " DESC"; private static final ExecutorService executor = Executors.newFixedThreadPool(1); private MediaProviderHelper() { } Loading Loading @@ -75,12 +86,13 @@ public final class MediaProviderHelper { return; } new WriterTask(file, uri, cr, listener).execute(); runTask(new WriterTask(cr, uri, file), listener); } public static void requestMyRecordings(@NonNull ContentResolver cr, @NonNull OnContentLoaded listener) { new LoaderTask(cr, listener).execute(); runTask(new LoaderTask(cr), listener); } public static void remove(@NonNull ContentResolver cr, @NonNull Uri uri) { Loading @@ -91,32 +103,47 @@ public final class MediaProviderHelper { @NonNull Uri uri, @NonNull String newName, @NonNull OnContentRenamed listener) { new RenameTask(cr, listener, uri).execute(newName); runTask(new RenameTask(cr, uri, newName), listener); } private static <T> void runTask(Callable<T> callable, Consumer<T> consumer) { Handler handler = new Handler(Looper.getMainLooper()); FutureTask<T> future = new FutureTask<T>(callable) { @Override protected void done() { try { T result = get(1, TimeUnit.MINUTES); handler.post(() -> consumer.accept(result)); } catch (InterruptedException e) { Log.w(TAG, e); } catch (ExecutionException | TimeoutException e) { throw new RuntimeException("An error occurred while executing task", e.getCause()); } } }; executor.execute(future); } @RequiresApi(29) static class WriterTask extends AsyncTask<Void, Void, String> { static class WriterTask implements Callable<String> { @NonNull private final File file; private final ContentResolver cr; @NonNull private final Uri uri; @NonNull private final ContentResolver cr; @NonNull private final OnContentWritten listener; private final File file; /* synthetic */ WriterTask(@NonNull File file, WriterTask(@NonNull ContentResolver cr, @NonNull Uri uri, @NonNull ContentResolver cr, @NonNull OnContentWritten listener) { this.file = file; this.uri = uri; @NonNull File file) { this.cr = cr; this.listener = listener; this.uri = uri; this.file = file; } @Override protected String doInBackground(Void... voids) { public String call() { try { final ParcelFileDescriptor pfd = cr.openFileDescriptor(uri, "w", null); if (pfd == null) { Loading @@ -142,29 +169,19 @@ public final class MediaProviderHelper { return null; } } @Override protected void onPostExecute(String s) { listener.onContentWritten(s); } } @RequiresApi(29) static class LoaderTask extends AsyncTask<Void, Void, List<RecordingData>> { static class LoaderTask implements Callable<List<RecordingData>> { @NonNull private final ContentResolver cr; @NonNull private final OnContentLoaded listener; /* synthetic */ LoaderTask(@NonNull ContentResolver cr, @NonNull OnContentLoaded listener) { LoaderTask(@NonNull ContentResolver cr) { this.cr = cr; this.listener = listener; } @Override protected List<RecordingData> doInBackground(Void... voids) { public List<RecordingData> call() { final List<RecordingData> list = new ArrayList<>(); final String[] projection = new String[] { Loading Loading @@ -197,55 +214,41 @@ public final class MediaProviderHelper { return list; } @Override protected void onPostExecute(List<RecordingData> list) { listener.onContentLoaded(list); } } @RequiresApi(29) static class RenameTask extends AsyncTask<String, Void, Boolean> { static class RenameTask implements Callable<Boolean> { @NonNull private final ContentResolver cr; @NonNull private final OnContentRenamed listener; @NonNull private final Uri uri; @NonNull private final String newName; /* synthetic */ RenameTask(@NonNull ContentResolver cr, @NonNull OnContentRenamed listener, @NonNull Uri uri) { RenameTask(@NonNull ContentResolver cr, @NonNull Uri uri, @NonNull String newName) { this.cr = cr; this.listener = listener; this.uri = uri; this.newName = newName; } @Override protected Boolean doInBackground(String... strings) { String newName = strings[0]; public Boolean call() { ContentValues cv = new ContentValues(); cv.put(MediaStore.Audio.Media.DISPLAY_NAME, newName); cv.put(MediaStore.Audio.Media.TITLE, newName); int updated = cr.update(uri, cv, null, null); return updated == 1; } @Override protected void onPostExecute(Boolean result) { listener.onContentRenamed(result); } } public interface OnContentWritten { void onContentWritten(@Nullable String uri); public interface OnContentWritten extends Consumer<String> { } public interface OnContentLoaded { void onContentLoaded(@NonNull List<RecordingData> list); public interface OnContentLoaded extends Consumer<List<RecordingData>>{ } public interface OnContentRenamed { void onContentRenamed(boolean success); public interface OnContentRenamed extends Consumer<Boolean> { } } app/src/main/java/org/lineageos/recorder/utils/OnBoardingHelper.java +7 −3 Original line number Diff line number Diff line Loading @@ -18,11 +18,13 @@ package org.lineageos.recorder.utils; import android.content.Context; import android.content.SharedPreferences; import android.os.Handler; import androidx.annotation.NonNull; import android.os.Looper; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import androidx.annotation.NonNull; import org.lineageos.recorder.R; public class OnBoardingHelper { Loading @@ -46,7 +48,8 @@ public class OnBoardingHelper { if (appOpenTimes == RIPPLE_OPEN_APP_WAIT) { // Animate using ripple effect for (int i = 1; i <= RIPPLE_REPEAT; i++) { new Handler().postDelayed(pressRipple(view), i * RIPPLE_DELAY); new Handler(Looper.getMainLooper()) .postDelayed(pressRipple(view), i * RIPPLE_DELAY); } } } Loading @@ -61,7 +64,8 @@ public class OnBoardingHelper { } if (appOpenTimes == ROTATION_OPEN_APP_WAIT) { new Handler().postDelayed(rotationAnimation(context, view), ROTATION_DELAY); new Handler(Looper.getMainLooper()) .postDelayed(rotationAnimation(context, view), ROTATION_DELAY); } } Loading Loading
app/build.gradle +2 −2 Original line number Diff line number Diff line apply plugin: 'com.android.application' android { compileSdkVersion 29 compileSdkVersion 30 defaultConfig { applicationId "org.lineageos.recorder" minSdkVersion 29 targetSdkVersion 29 targetSdkVersion 30 versionCode 1 versionName "1.1" } Loading
app/src/main/java/org/lineageos/recorder/ListActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public class ListActivity extends AppCompatActivity implements RecordingItemCall } }); Utils.setFullScreen(coordinatorLayout); Utils.setFullScreen(getWindow(), coordinatorLayout); Utils.setVerticalInsets(listView); } Loading
app/src/main/java/org/lineageos/recorder/RecorderActivity.java +3 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.telephony.TelephonyManager; import android.view.View; import android.widget.ImageView; Loading Loading @@ -108,7 +109,7 @@ public class RecorderActivity extends AppCompatActivity implements mSoundList.setOnClickListener(v -> openList()); mSettings.setOnClickListener(v -> openSettings()); Utils.setFullScreen(mainView); Utils.setFullScreen(getWindow(), mainView); Utils.setVerticalInsets(mainView); mPrefs = getSharedPreferences(Utils.PREFS, 0); Loading Loading @@ -204,7 +205,7 @@ public class RecorderActivity extends AppCompatActivity implements private void toggleAfterPermissionRequest(int requestCode) { if (requestCode == REQUEST_SOUND_REC_PERMS) { bindSoundRecService(); new Handler().postDelayed(this::toggleSoundRecorder, 500); new Handler(Looper.getMainLooper()).postDelayed(this::toggleSoundRecorder, 500); } } Loading
app/src/main/java/org/lineageos/recorder/utils/MediaProviderHelper.java +58 −55 Original line number Diff line number Diff line Loading @@ -20,7 +20,8 @@ import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; import android.os.Looper; import android.os.ParcelFileDescriptor; import android.provider.MediaStore; import android.util.Log; Loading @@ -39,6 +40,14 @@ import java.nio.file.Files; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; public final class MediaProviderHelper { private static final String TAG = "MediaProviderHelper"; Loading @@ -46,6 +55,8 @@ public final class MediaProviderHelper { private static final String MY_RECORDS_SORT = MediaStore.Audio.Media.DATE_ADDED + " DESC"; private static final ExecutorService executor = Executors.newFixedThreadPool(1); private MediaProviderHelper() { } Loading Loading @@ -75,12 +86,13 @@ public final class MediaProviderHelper { return; } new WriterTask(file, uri, cr, listener).execute(); runTask(new WriterTask(cr, uri, file), listener); } public static void requestMyRecordings(@NonNull ContentResolver cr, @NonNull OnContentLoaded listener) { new LoaderTask(cr, listener).execute(); runTask(new LoaderTask(cr), listener); } public static void remove(@NonNull ContentResolver cr, @NonNull Uri uri) { Loading @@ -91,32 +103,47 @@ public final class MediaProviderHelper { @NonNull Uri uri, @NonNull String newName, @NonNull OnContentRenamed listener) { new RenameTask(cr, listener, uri).execute(newName); runTask(new RenameTask(cr, uri, newName), listener); } private static <T> void runTask(Callable<T> callable, Consumer<T> consumer) { Handler handler = new Handler(Looper.getMainLooper()); FutureTask<T> future = new FutureTask<T>(callable) { @Override protected void done() { try { T result = get(1, TimeUnit.MINUTES); handler.post(() -> consumer.accept(result)); } catch (InterruptedException e) { Log.w(TAG, e); } catch (ExecutionException | TimeoutException e) { throw new RuntimeException("An error occurred while executing task", e.getCause()); } } }; executor.execute(future); } @RequiresApi(29) static class WriterTask extends AsyncTask<Void, Void, String> { static class WriterTask implements Callable<String> { @NonNull private final File file; private final ContentResolver cr; @NonNull private final Uri uri; @NonNull private final ContentResolver cr; @NonNull private final OnContentWritten listener; private final File file; /* synthetic */ WriterTask(@NonNull File file, WriterTask(@NonNull ContentResolver cr, @NonNull Uri uri, @NonNull ContentResolver cr, @NonNull OnContentWritten listener) { this.file = file; this.uri = uri; @NonNull File file) { this.cr = cr; this.listener = listener; this.uri = uri; this.file = file; } @Override protected String doInBackground(Void... voids) { public String call() { try { final ParcelFileDescriptor pfd = cr.openFileDescriptor(uri, "w", null); if (pfd == null) { Loading @@ -142,29 +169,19 @@ public final class MediaProviderHelper { return null; } } @Override protected void onPostExecute(String s) { listener.onContentWritten(s); } } @RequiresApi(29) static class LoaderTask extends AsyncTask<Void, Void, List<RecordingData>> { static class LoaderTask implements Callable<List<RecordingData>> { @NonNull private final ContentResolver cr; @NonNull private final OnContentLoaded listener; /* synthetic */ LoaderTask(@NonNull ContentResolver cr, @NonNull OnContentLoaded listener) { LoaderTask(@NonNull ContentResolver cr) { this.cr = cr; this.listener = listener; } @Override protected List<RecordingData> doInBackground(Void... voids) { public List<RecordingData> call() { final List<RecordingData> list = new ArrayList<>(); final String[] projection = new String[] { Loading Loading @@ -197,55 +214,41 @@ public final class MediaProviderHelper { return list; } @Override protected void onPostExecute(List<RecordingData> list) { listener.onContentLoaded(list); } } @RequiresApi(29) static class RenameTask extends AsyncTask<String, Void, Boolean> { static class RenameTask implements Callable<Boolean> { @NonNull private final ContentResolver cr; @NonNull private final OnContentRenamed listener; @NonNull private final Uri uri; @NonNull private final String newName; /* synthetic */ RenameTask(@NonNull ContentResolver cr, @NonNull OnContentRenamed listener, @NonNull Uri uri) { RenameTask(@NonNull ContentResolver cr, @NonNull Uri uri, @NonNull String newName) { this.cr = cr; this.listener = listener; this.uri = uri; this.newName = newName; } @Override protected Boolean doInBackground(String... strings) { String newName = strings[0]; public Boolean call() { ContentValues cv = new ContentValues(); cv.put(MediaStore.Audio.Media.DISPLAY_NAME, newName); cv.put(MediaStore.Audio.Media.TITLE, newName); int updated = cr.update(uri, cv, null, null); return updated == 1; } @Override protected void onPostExecute(Boolean result) { listener.onContentRenamed(result); } } public interface OnContentWritten { void onContentWritten(@Nullable String uri); public interface OnContentWritten extends Consumer<String> { } public interface OnContentLoaded { void onContentLoaded(@NonNull List<RecordingData> list); public interface OnContentLoaded extends Consumer<List<RecordingData>>{ } public interface OnContentRenamed { void onContentRenamed(boolean success); public interface OnContentRenamed extends Consumer<Boolean> { } }
app/src/main/java/org/lineageos/recorder/utils/OnBoardingHelper.java +7 −3 Original line number Diff line number Diff line Loading @@ -18,11 +18,13 @@ package org.lineageos.recorder.utils; import android.content.Context; import android.content.SharedPreferences; import android.os.Handler; import androidx.annotation.NonNull; import android.os.Looper; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import androidx.annotation.NonNull; import org.lineageos.recorder.R; public class OnBoardingHelper { Loading @@ -46,7 +48,8 @@ public class OnBoardingHelper { if (appOpenTimes == RIPPLE_OPEN_APP_WAIT) { // Animate using ripple effect for (int i = 1; i <= RIPPLE_REPEAT; i++) { new Handler().postDelayed(pressRipple(view), i * RIPPLE_DELAY); new Handler(Looper.getMainLooper()) .postDelayed(pressRipple(view), i * RIPPLE_DELAY); } } } Loading @@ -61,7 +64,8 @@ public class OnBoardingHelper { } if (appOpenTimes == ROTATION_OPEN_APP_WAIT) { new Handler().postDelayed(rotationAnimation(context, view), ROTATION_DELAY); new Handler(Looper.getMainLooper()) .postDelayed(rotationAnimation(context, view), ROTATION_DELAY); } } Loading