6.1.0 - 变更包名 新增投影媒体权限开关/tasks模块 扩展内置模块方法 重构内置模块及构建脚本

This commit is contained in:
SuperMonster003
2022-05-26 19:18:16 +08:00
parent e0374a835e
commit f68ad1c993
770 changed files with 15821 additions and 14759 deletions

View File

@@ -1,62 +1,37 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
// tasks.withType(JavaCompile) {
// options.compilerArgs << '-Xlint:deprecation'
// }
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_16
}
ext {
namespace = 'com.stardust'
}
android {
compileSdkVersion versions.project.compile
defaultConfig {
minSdkVersion versions.project.mini
targetSdkVersion versions.project.target
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_16
targetCompatibility JavaVersion.VERSION_16
}
apply {
from rootProject.file('config.gradle')
}
dependencies {
testImplementation "junit:junit:${versions.junit}"
// Kotlin
// noinspection DifferentStdlibGradleVersion
api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}"
// @Comment by SuperMonster003 on May 19, 2022.
// ! It is no longer necessary to declare a dependency on the stdlib library in any Kotlin Gradle project.
// ! The dependency is added by default.
// ! See https://kotlinlang.org/docs/gradle.html#dependency-on-the-standard-library
// api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21"
// Android supports
api 'com.google.android.material:material:1.5.0'
api 'com.google.android.material:material:1.6.0'
// Material Dialogs
// noinspection GradleDependency
api "com.afollestad.material-dialogs:core:${versions.materialDialogs}"
// TODO by SuperMonster003 on Feb 5, 2022.
// ! Upgrade to 3.3.0 (more difficult than expected)
api "com.afollestad.material-dialogs:core:0.9.6.0"
api "com.afollestad.material-dialogs:commons:0.9.6.0"
// Glide
api "com.github.bumptech.glide:glide:${versions.glide}"
api "com.github.bumptech.glide:glide:4.13.2"
// RoundedImageView
api 'com.makeramen:roundedimageview:2.3.0'
// CircleImageView
api 'de.hdodenhof:circleimageview:3.1.0'
// EventBus
api 'org.greenrobot:eventbus:3.3.1'
@@ -82,6 +57,8 @@ dependencies {
// AppCompat
api 'androidx.appcompat:appcompat:1.4.1'
// AppCompat for legacy views (such as JsTextViewLegacy)
api project(':libs:androidx.appcompat-1.0.2')
// LocaleHelper
@@ -91,5 +68,5 @@ dependencies {
api project(':libs:org.opencv-4.5.5')
// Rhino
api project(':libs:org.mozilla.rhino-1.7.14')
api project(':libs:org.mozilla.rhino-1.7.15-snapshot')
}

View File

@@ -1 +0,0 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":455,"versionName":"4.1.0 Alpha5","enabled":true,"outputFile":"commonRelease-4.1.0 Alpha5.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.1.0 Alpha5.apk","properties":{}}]

View File

@@ -1,26 +0,0 @@
package com.stardust;
import android.content.Context;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.stardust.test", appContext.getPackageName());
}
}

View File

@@ -5,4 +5,5 @@
android:allowBackup="true"
android:label="common"
android:supportsRtl="true" />
</manifest>

View File

@@ -5,19 +5,27 @@ import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.Build
import androidx.annotation.RequiresApi
@RequiresApi(Build.VERSION_CODES.KITKAT)
fun Context.isOpPermissionGranted(permission: String): Boolean {
return try {
val packageManager: PackageManager = this.packageManager
val applicationInfo: ApplicationInfo = packageManager.getApplicationInfo(this.packageName, 0)
val appOpsManager: AppOpsManager = this.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
val mode = if (Build.VERSION.SDK_INT >= 29 /* Build.VERSION_CODES.Q */) {
appOpsManager.unsafeCheckOpNoThrow(permission, applicationInfo.uid, applicationInfo.packageName)
val uid = applicationInfo.uid
val packageName = applicationInfo.packageName
val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
appOpsManager.unsafeCheckOpNoThrow(permission, uid, packageName)
} else {
@Suppress("DEPRECATION")
appOpsManager.checkOpNoThrow(permission, applicationInfo.uid, applicationInfo.packageName)
if (permission.matches(Regex("^\\d+$"))) {
// @Reflect by SuperMonster003 on May 1, 2022.
// ! checkOpNoThrow(int op, int uid, String packageName): int
appOpsManager.javaClass
.getMethod("checkOpNoThrow", Int::class.javaPrimitiveType, Int::class.javaPrimitiveType, String::class.java)
.invoke(appOpsManager, permission.toInt(), uid, packageName)
} else {
@Suppress("DEPRECATION")
appOpsManager.checkOpNoThrow(permission, uid, packageName)
}
}
mode == AppOpsManager.MODE_ALLOWED
} catch (e: PackageManager.NameNotFoundException) {
@@ -26,5 +34,26 @@ fun Context.isOpPermissionGranted(permission: String): Boolean {
}
fun Context.isUsageStatsPermissionGranted(): Boolean {
return this.isOpPermissionGranted(AppOpsManager.OPSTR_GET_USAGE_STATS)
return isOpPermissionGranted(AppOpsManager.OPSTR_GET_USAGE_STATS)
}
// FIXME by SuperMonster003 as of May 1, 2022.
// ! A better long-term maintainability is required to replace hardcoded strings.
fun Context.isProjectMediaAccessGranted(): Boolean {
val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
/*
FIXME by SuperMonster003 as of May 1, 2022.
! AppOpsManager.OPSTR_PROJECT_MEDIA is hide and is a system api.
! String value may change or be invalid some day.
*/
"android:project_media" /* AppOpsManager.OPSTR_PROJECT_MEDIA */
} else {
/*
FIXME by SuperMonster003 as of May 1, 2022.
! AppOpsManager.OP_PROJECT_MEDIA is annotated with "UnsupportedAppUsage".
! As is known to all, hardcoded string usage is always the worst plan.
*/
"46" /* String of AppOpsManager.OP_PROJECT_MEDIA */
}
return isOpPermissionGranted(permission)
}

View File

@@ -1,6 +1,5 @@
package com.stardust.app;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
@@ -13,7 +12,6 @@ import android.view.WindowManager;
/**
* Created by Stardust on 2017/8/4.
*/
public class DialogUtils {
public static <T extends Dialog> T showDialog(final T dialog) {

View File

@@ -12,7 +12,6 @@ import com.stardust.util.ViewUtil;
/**
* Created by Stardust on 2017/1/30.
*/
public abstract class Fragment extends androidx.fragment.app.Fragment {
private View mView;
@@ -36,7 +35,7 @@ public abstract class Fragment extends androidx.fragment.app.Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mView = createView(inflater, container, savedInstanceState);
return mView;
}

View File

@@ -14,7 +14,6 @@ import java.util.List;
/**
* Created by Stardust on 2017/3/24.
*/
public class FragmentPagerAdapterBuilder {
public interface OnFragmentInstantiateListener {
@@ -41,6 +40,7 @@ public class FragmentPagerAdapterBuilder {
public StoredFragmentPagerAdapter build() {
return new StoredFragmentPagerAdapter(mActivity.getSupportFragmentManager()) {
@NonNull
@Override
public Fragment getItem(int position) {
return mFragments.get(position);

View File

@@ -3,16 +3,13 @@ package com.stardust.app;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.RequiresApi;
import android.widget.Toast;
/**
* Created by Stardust on 2018/3/22.
*/
public class GlobalAppContext {
@SuppressLint("StaticFieldLeak")
@@ -34,7 +31,6 @@ public class GlobalAppContext {
return get().getString(resId);
}
@RequiresApi(api = Build.VERSION_CODES.M)
public static int getColor(int id) {
return get().getColor(id);
}

View File

@@ -10,7 +10,6 @@ import java.util.List;
/**
* Created by Stardust on 2017/3/5.
*/
public interface OnActivityResultDelegate {
void onActivityResult(int requestCode, int resultCode, Intent data);
@@ -22,8 +21,8 @@ public interface OnActivityResultDelegate {
class Mediator implements OnActivityResultDelegate {
private SparseArray<OnActivityResultDelegate> mSpecialDelegate = new SparseArray<>();
private List<OnActivityResultDelegate> mDelegates = new ArrayList<>();
private final SparseArray<OnActivityResultDelegate> mSpecialDelegate = new SparseArray<>();
private final List<OnActivityResultDelegate> mDelegates = new ArrayList<>();
public void onActivityResult(int requestCode, int resultCode, Intent data) {
OnActivityResultDelegate delegate = mSpecialDelegate.get(requestCode);

View File

@@ -7,7 +7,6 @@ import android.os.Bundle;
/**
* Created by Stardust on 2017/4/2.
*/
public class SimpleActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
@Override

View File

@@ -6,7 +6,6 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by Stardust on 2017/12/30.
*/
public class ConcurrentArrayList<T> {
private final Class<T> mTClass;

View File

@@ -3,7 +3,6 @@ package com.stardust.concurrent;
/**
* Created by Stardust on 2017/12/27.
*/
public class Value<T> {
private T mValue;

View File

@@ -1,12 +1,9 @@
package com.stardust.concurrent;
import java.lang.reflect.Constructor;
/**
* Created by Stardust on 2017/5/8.
*/
public class VolatileBox<T> {
private volatile T mValue;
@@ -60,9 +57,7 @@ public class VolatileBox<T> {
} catch (InterruptedException e) {
try {
throw exception.newInstance();
} catch (InstantiationException e1) {
throw new RuntimeException(e1);
} catch (IllegalAccessException e1) {
} catch (InstantiationException | IllegalAccessException e1) {
throw new RuntimeException(e1);
}
}

View File

@@ -3,7 +3,6 @@ package com.stardust.concurrent;
/**
* Created by Stardust on 2017/10/28.
*/
public class VolatileDispose<T> {
private volatile T mValue;
@@ -32,9 +31,7 @@ public class VolatileDispose<T> {
} catch (InterruptedException e) {
try {
throw exception.newInstance();
} catch (InstantiationException e1) {
throw new RuntimeException(e1);
} catch (IllegalAccessException e1) {
} catch (InstantiationException | IllegalAccessException e1) {
throw new RuntimeException(e1);
}
}
@@ -52,9 +49,7 @@ public class VolatileDispose<T> {
} catch (InterruptedException e) {
try {
throw exception.newInstance();
} catch (InstantiationException e1) {
throw new RuntimeException(e1);
} catch (IllegalAccessException e1) {
} catch (InstantiationException | IllegalAccessException e1) {
throw new RuntimeException(e1);
}
}

View File

@@ -5,14 +5,13 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* Created by Stardust on 2017/8/6.
*/
public class EventDispatcher<Listener> {
public interface Event<Listener> {
void notify(Listener l);
}
private CopyOnWriteArrayList<Listener> mListeners = new CopyOnWriteArrayList<>();
private final CopyOnWriteArrayList<Listener> mListeners = new CopyOnWriteArrayList<>();
public void addListener(Listener l) {
mListeners.add(l);

View File

@@ -3,6 +3,7 @@ package com.stardust.io
import java.io.IOException
import java.io.InputStream
import java.nio.ByteBuffer
import kotlin.math.min
class ByteBufferBackedInputStream(private var buf: ByteBuffer) : InputStream() {
@@ -18,7 +19,7 @@ class ByteBufferBackedInputStream(private var buf: ByteBuffer) : InputStream() {
if (!buf.hasRemaining()) {
return -1
}
val read = Math.min(len, available())
val read = min(len, available())
buf.get(bytes, off, read)
buf.position(buf.position() - read)
return read

View File

@@ -20,7 +20,6 @@ package com.stardust.io;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
/**
* A reader which reads sequentially from multiple sources.
@@ -44,7 +43,7 @@ public class ConcatReader extends Reader {
*
* @since ostermillerutils 1.04.01
*/
private ArrayList<Reader> readerQueue = new ArrayList<>();
private final ArrayList<Reader> readerQueue = new ArrayList<>();
/**
* A cache of the current reader from the readerQueue

View File

@@ -8,7 +8,6 @@ import java.net.URI;
/**
* Created by Stardust on 2017/8/19.
*/
public class EFile extends File {
public EFile(@NonNull String pathname) {

View File

@@ -1,6 +1,5 @@
package com.stardust.io;
import com.stardust.pio.PFile;
import com.stardust.pio.PFiles;
import java.io.File;

View File

@@ -1,19 +1,16 @@
package com.stardust.lang;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Set;
import java.util.WeakHashMap;
/**
* Created by Stardust on 2017/4/30.
*/
public class ThreadCompat extends Thread {
// FIXME: 2017/12/29 是否需要用synchronizedMap?这里虽然线程不安全,但竞争很小
private static final Set<Thread> interruptedThreads = Collections.newSetFromMap(new WeakHashMap<Thread, Boolean>());
private static final Set<Thread> interruptedThreads = Collections.newSetFromMap(new WeakHashMap<>());
public ThreadCompat() {
}

View File

@@ -6,16 +6,14 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by Stardust on 2017/4/10.
*/
public class AutoHttpURLConnection extends HttpURLConnection implements AutoCloseable {
private HttpURLConnection mHttpURLConnection;
private final HttpURLConnection mHttpURLConnection;
private InputStream mInputStream;
private OutputStream mOutputStream;

View File

@@ -1,7 +1,6 @@
package com.stardust.pio;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.File;
import java.io.FileFilter;
@@ -12,7 +11,6 @@ import java.util.ArrayList;
/**
* Created by Stardust on 2017/10/19.
*/
public class PFile extends File {
private String mSimplifyPath;
@@ -85,47 +83,66 @@ public class PFile extends File {
@Override
public PFile getParentFile() {
String p = this.getParent();
if (p == null)
if (p == null) {
return null;
}
return new PFile(p);
}
@Override
public PFile[] listFiles() {
String ss[] = list();
if (ss == null) return null;
ArrayList<PFile> files = new ArrayList<>();
for (int i = 0; i < ss.length; i++) {
if (!ss[i].startsWith(".")) {
files.add(new PFile(this, ss[i]));
}
}
return files.toArray(new PFile[files.size()]);
return listFiles((FilenameFilter) null, true);
}
@Override
public PFile[] listFiles(FilenameFilter filter) {
String ss[] = list();
if (ss == null) return null;
ArrayList<PFile> files = new ArrayList<>();
for (String s : ss)
if (!s.startsWith(".") && (filter == null || filter.accept(this, s)))
files.add(new PFile(this, s));
return files.toArray(new PFile[files.size()]);
return listFiles(filter, true);
}
@Override
public PFile[] listFiles(FileFilter filter) {
String ss[] = list();
if (ss == null) return null;
return listFiles(filter, true);
}
public PFile[] listFiles(boolean isShowHidden) {
return listFiles((FilenameFilter) null, isShowHidden);
}
public PFile[] listFiles(FilenameFilter filter, boolean isShowHidden) {
String[] ss = list();
if (ss == null) {
return null;
}
ArrayList<PFile> files = new ArrayList<>();
for (String s : ss) {
if (canAddHidden(s, isShowHidden) && (filter == null || filter.accept(this, s))) {
files.add(new PFile(this, s));
}
}
return files.toArray(new PFile[0]);
}
public PFile[] listFiles(FileFilter filter, boolean isShowHidden) {
String[] ss = list();
if (ss == null) {
return null;
}
ArrayList<PFile> files = new ArrayList<>();
for (String s : ss) {
PFile f = new PFile(this, s);
if (!f.isHidden() && (filter == null || filter.accept(f)))
if (canAddHidden(f, isShowHidden) && (filter == null || filter.accept(f))) {
files.add(f);
}
}
return files.toArray(new PFile[files.size()]);
return files.toArray(new PFile[0]);
}
private boolean canAddHidden(PFile file, boolean override) {
return override || !file.isHidden();
}
private boolean canAddHidden(String fileName, boolean override) {
return override || !fileName.startsWith(".");
}
public String getSimplifiedName() {

View File

@@ -3,7 +3,6 @@ package com.stardust.pio;
/**
* Created by Stardust on 2017/12/5.
*/
public interface PFileInterface {
String getPath();
}

View File

@@ -22,7 +22,6 @@ import java.util.Objects;
/**
* Created by Stardust on 2017/4/1.
*/
@SuppressWarnings("ResultOfMethodCallIgnored")
public class PFiles {

View File

@@ -1,17 +1,13 @@
package com.stardust.pio;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/4/29.
*/
public class PRandomAccessBinaryFile extends RandomAccessFile {

View File

@@ -6,7 +6,6 @@ import java.io.IOException;
/**
* Created by Stardust on 2017/4/6.
*/
public class PReadableBinaryFile implements Closeable {

View File

@@ -7,14 +7,13 @@ import java.util.List;
/**
* Created by Stardust on 2017/4/1.
*/
public class PReadableTextFile implements Closeable, PFileInterface {
private BufferedReader mBufferedReader;
private FileInputStream mFileInputStream;
private int mBufferingSize;
private String mEncoding;
private String mPath;
private final FileInputStream mFileInputStream;
private final int mBufferingSize;
private final String mEncoding;
private final String mPath;
public PReadableTextFile(String path) {
this(path, PFiles.DEFAULT_ENCODING);
@@ -87,7 +86,7 @@ public class PReadableTextFile implements Closeable, PFileInterface {
while (mBufferedReader.ready()) {
lines.add(mBufferedReader.readLine());
}
return lines.toArray(new String[lines.size()]);
return lines.toArray(new String[0]);
} catch (IOException e) {
throw new UncheckedIOException(e);
}

View File

@@ -15,7 +15,6 @@ import static com.stardust.pio.PFiles.DEFAULT_BUFFER_SIZE;
/**
* Created by Stardust on 2017/4/1.
*/
public class PWritableTextFile implements Closeable, PFileInterface {
public static PWritableTextFile open(String path, String encoding, int bufferSize) {
@@ -34,8 +33,8 @@ public class PWritableTextFile implements Closeable, PFileInterface {
return new PWritableTextFile(path);
}
private BufferedWriter mBufferedWriter;
private String mPath;
private final BufferedWriter mBufferedWriter;
private final String mPath;
public PWritableTextFile(String path, String encoding, int bufferingSize, boolean append) {
mPath = path;

View File

@@ -5,7 +5,6 @@ import java.io.IOException;
/**
* Created by Stardust on 2017/4/1.
*/
public class UncheckedIOException extends RuntimeException {
public UncheckedIOException(IOException cause) {

View File

@@ -6,7 +6,6 @@ import java.util.List;
/**
* Created by Stardust on 2017/5/8.
*/
public class ArrayUtils {

View File

@@ -8,20 +8,14 @@ import com.stardust.pio.PFiles;
/**
* Created by Stardust on 2017/3/14.
*/
public class AssetsCache {
private static final long PERSIST_TIME = 5 * 60 * 1000;
private static SimpleCache<String> cache = new SimpleCache<>(PERSIST_TIME, 5, 30 * 1000);
private static final SimpleCache<String> cache = new SimpleCache<>(PERSIST_TIME, 5, 30 * 1000);
public static String get(final AssetManager assetManager, final String path) {
return cache.get(path, new SimpleCache.Supplier<String>() {
@Override
public String get(String key) {
return PFiles.readAsset(assetManager, path);
}
});
return cache.get(path, key -> PFiles.readAsset(assetManager, path));
}
public static String get(final Activity activity, final String path) {

View File

@@ -1,7 +1,6 @@
package com.stardust.util;
import android.app.Activity;
import android.os.Handler;
import android.widget.Toast;
@@ -22,7 +21,7 @@ public interface BackPressedHandler {
class Observer implements BackPressedHandler {
private CopyOnWriteArrayList<BackPressedHandler> mBackPressedHandlers = new CopyOnWriteArrayList<>();
private final CopyOnWriteArrayList<BackPressedHandler> mBackPressedHandlers = new CopyOnWriteArrayList<>();
@Override
public boolean onBackPressed(Activity activity) {
@@ -53,7 +52,7 @@ public interface BackPressedHandler {
private final Activity mActivity;
private long mLastPressedMillis;
private long mDoublePressInterval = 1000;
private String mToast;
private final String mToast;
public DoublePressExit(Activity activity, int noticeResId) {
this(activity, activity.getString(noticeResId));

View File

@@ -1,8 +1,6 @@
package com.stardust.util;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import java.util.Collection;
import java.util.HashMap;
@@ -24,7 +22,7 @@ public class BiMaps {
public static class BiMapBuilder<K, V> {
private final BiMap<K, V> mBiMap = make(new HashMap<K, V>(), new HashMap<V, K>());
private final BiMap<K, V> mBiMap = make(new HashMap<>(), new HashMap<>());
public BiMapBuilder<K, V> put(K key, V value) {
mBiMap.put(key, value);
@@ -149,69 +147,58 @@ public class BiMaps {
return mKVMap.hashCode();
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public V getOrDefault(Object key, V defaultValue) {
return mKVMap.getOrDefault(key, defaultValue);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
public void forEach(@NonNull BiConsumer<? super K, ? super V> action) {
mKVMap.forEach(action);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
public void replaceAll(@NonNull BiFunction<? super K, ? super V, ? extends V> function) {
mKVMap.replaceAll(function);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public V putIfAbsent(K key, V value) {
return mKVMap.putIfAbsent(key, value);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public boolean remove(Object key, Object value) {
return mKVMap.remove(key, value);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public boolean replace(K key, V oldValue, V newValue) {
return mKVMap.replace(key, oldValue, newValue);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public V replace(K key, V value) {
return mKVMap.replace(key, value);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
public V computeIfAbsent(K key, @NonNull Function<? super K, ? extends V> mappingFunction) {
return mKVMap.computeIfAbsent(key, mappingFunction);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
public V computeIfPresent(K key, @NonNull BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
return mKVMap.computeIfPresent(key, remappingFunction);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
public V compute(K key, @NonNull BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
return mKVMap.compute(key, remappingFunction);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
public V merge(K key, @NonNull V value, @NonNull BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
return mKVMap.merge(key, value, remappingFunction);
}
}

View File

@@ -3,7 +3,6 @@ package com.stardust.util;
/**
* Created by Stardust on 2017/4/18.
*/
public interface Callback<T> {
void call(T t);

View File

@@ -10,7 +10,6 @@ import androidx.annotation.NonNull;
/**
* Created by Stardust on 2017/3/10.
*/
public class ClipboardUtil {

View File

@@ -9,9 +9,11 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
import androidx.annotation.Nullable;
import android.util.Base64;
import android.util.Log;
import androidx.annotation.Nullable;
import com.stardust.app.GlobalAppContext;
import java.io.IOException;
import java.lang.ref.WeakReference;
@@ -25,16 +27,14 @@ import kotlin.text.Regex;
/**
* Created by Stardust on 2017/4/5.
*/
public class DeveloperUtils {
private static final String PACKAGE_NAME = "org.autojs.autojs";
private static final Regex SIGNATURE_REX = new Regex(".*(CbKua77m59vis|N7YkpKxKjsPWe).*");
private static final ExecutorService sExecutor = UnderuseExecutors.getExecutor();
private static final String SALT = "let\nlife\nbe\nbeautiful\nlike\nsummer\nflowers\nand\ndeath\nlike\nautumn\nleaves\n.";
public static boolean isSelfPackage(@Nullable String runningPackage) {
return PACKAGE_NAME.equals(runningPackage);
return selfPackage().equals(runningPackage);
}
@Nullable
@@ -85,12 +85,10 @@ public class DeveloperUtils {
return SIGNATURE_REX.matches(sha);
}
public static String selfPackage() {
return PACKAGE_NAME;
return GlobalAppContext.get().getPackageName();
}
public static boolean isActivityRegistered(Context context, Class<? extends Activity> c) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
@@ -154,15 +152,10 @@ public class DeveloperUtils {
public static void verifyApk(Activity activity) {
final WeakReference<Activity> activityWeakReference = new WeakReference<>(activity);
sExecutor.execute(new Runnable() {
@Override
public void run() {
Activity a = activityWeakReference.get();
if (a == null)
return;
if (!checkSignature(a)) {
a.finish();
}
sExecutor.execute(() -> {
Activity a = activityWeakReference.get();
if (a != null && !checkSignature(a)) {
a.finish();
}
});
}

View File

@@ -6,11 +6,10 @@ import androidx.drawerlayout.widget.DrawerLayout;
/**
* Created by Stardust on 2017/6/19.
*/
public class DrawerAutoClose implements BackPressedHandler {
private DrawerLayout mDrawerLayout;
private int mGravity;
private final DrawerLayout mDrawerLayout;
private final int mGravity;
public DrawerAutoClose(DrawerLayout drawerLayout, int gravity){
mDrawerLayout = drawerLayout;

View File

@@ -5,17 +5,15 @@ import com.stardust.pio.PFiles;
import java.io.File;
import java.text.Collator;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Created by Stardust on 2017/3/31.
*/
public class FileSorter {
public static final Comparator<File> NAME = new Comparator<File>() {
public static final Comparator<File> NAME = new Comparator<>() {
final Collator collator = Collator.getInstance();
@Override
@@ -26,39 +24,17 @@ public class FileSorter {
}
};
public static final Comparator<File> DATE = new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return o1.lastModified() == o2.lastModified() ? 0 :
o1.lastModified() > o2.lastModified() ? 1 : -1;
}
};
public static final Comparator<File> DATE = Comparator.comparingLong(File::lastModified);
public static final Comparator<File> TYPE = new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return -PFiles.getExtension(o1.getName()).compareTo(PFiles.getExtension(o2.getName()));
}
};
public static final Comparator<File> TYPE = (o1, o2) -> -PFiles.getExtension(o1.getName()).compareTo(PFiles.getExtension(o2.getName()));
public static final Comparator<File> SIZE = new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return o1.length() == o2.length() ? 0 :
o1.length() < o2.length() ? 1 : -1;
}
};
public static final Comparator<File> SIZE = (o1, o2) -> Long.compare(o2.length(), o1.length());
public static void sort(File[] files, final Comparator<File> comparator, boolean ascending) {
if (ascending) {
Arrays.sort(files, comparator);
} else {
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return comparator.compare(o2, o1);
}
});
Arrays.sort(files, (o1, o2) -> comparator.compare(o2, o1));
}
}
@@ -68,14 +44,9 @@ public class FileSorter {
public static void sort(List<? extends File> files, final Comparator<File> comparator, boolean ascending) {
if (ascending) {
Collections.sort(files, comparator);
files.sort(comparator);
} else {
Collections.sort(files, new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return comparator.compare(o2, o1);
}
});
files.sort((Comparator<File>) (o1, o2) -> comparator.compare(o2, o1));
}
}

View File

@@ -3,7 +3,6 @@ package com.stardust.util;
/**
* Created by Stardust on 2017/7/7.
*/
public interface Func1<T, R> {
R call(T t);

View File

@@ -8,7 +8,6 @@ import java.security.NoSuchAlgorithmException;
/**
* Created by Stardust on 2017/9/26.
*/
public class HashUtils {
public static String md5(String text) {

View File

@@ -11,15 +11,14 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by Stardust on 2017/7/11.
*/
public class IntentExtras implements Serializable {
public static final String EXTRA_ID = "com.stardust.util.IntentExtras.id";
private static AtomicInteger mMaxId = new AtomicInteger(-1);
private static SparseArray<Map<String, Object>> extraStore = new SparseArray<>();
private static final AtomicInteger mMaxId = new AtomicInteger(-1);
private static final SparseArray<Map<String, Object>> extraStore = new SparseArray<>();
private Map<String, Object> mMap;
private final Map<String, Object> mMap;
private int mId;
private IntentExtras() {

View File

@@ -4,14 +4,12 @@ import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.content.FileProvider;
import android.os.Build;
import android.widget.Toast;
import com.stardust.R;
import java.io.File;
@@ -21,6 +19,7 @@ public class IntentUtil {
public static boolean chatWithQQ(Context context, String qq) {
try {
@SuppressWarnings("SpellCheckingInspection")
String url = "mqqwpa://im/chat?chat_type=wpa&uin=" + qq;
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
return true;
@@ -31,8 +30,10 @@ public class IntentUtil {
}
public static boolean joinQQGroup(Context context, String key) {
@SuppressWarnings("SpellCheckingInspection")
String url = "mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key;
Intent intent = new Intent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key));
intent.setData(Uri.parse(url));
try {
context.startActivity(intent);
return true;
@@ -89,7 +90,7 @@ public class IntentUtil {
public static boolean goToAppDetailSettings(Context context, String packageName) {
try {
Intent i = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Intent i = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setData(Uri.parse("package:" + packageName));
@@ -187,12 +188,10 @@ public class IntentUtil {
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static void requestAppUsagePermission(Context context) {
Intent intent = new Intent(android.provider.Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
context.startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}

View File

@@ -0,0 +1,31 @@
package com.stardust.util;
import androidx.annotation.NonNull;
/**
* Created by SuperMonster003 on May 4, 2022.
* Mainly for JavaScript modules.
*/
public class JavaUtils {
@NonNull
public static Class<?> getClass(@NonNull Class<?> Clazz) {
return Clazz;
}
@NonNull
public static Class<?> getClass(@NonNull Object o) {
return o.getClass();
}
@NonNull
public static String getClassName(@NonNull Class<?> Clazz) {
return Clazz.getName();
}
@NonNull
public static String getClassName(@NonNull Object o) {
return o.getClass().getName();
}
}

View File

@@ -5,10 +5,9 @@ import java.util.LinkedHashMap;
/**
* Created by Stardust on 2017/3/31.
*/
public class LimitedHashMap<K, V> extends LinkedHashMap<K, V> {
private int mMaxSize;
private final int mMaxSize;
public LimitedHashMap(int maxSize) {
super(4, 0.75f, true);

View File

@@ -1,7 +1,6 @@
package com.stardust.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5 {

View File

@@ -6,13 +6,12 @@ import java.util.Map;
/**
* Created by Stardust on 2017/1/26.
*/
public class MapBuilder<K, V> {
private Map<K, V> mMap;
private final Map<K, V> mMap;
public MapBuilder() {
this(new HashMap<K, V>());
this(new HashMap<>());
}
public MapBuilder(Map<K, V> map) {

View File

@@ -3,7 +3,6 @@ package com.stardust.util;
/**
* Created by Stardust on 2017/3/12.
*/
public class MessageEvent {
public String message;

View File

@@ -9,7 +9,6 @@ import java.util.HashMap;
/**
* Created by Stardust on 2017/6/27.
*/
public class MessageIntent extends Intent {
private HashMap<String, Object> mObjectExtras;

View File

@@ -9,7 +9,6 @@ import static com.stardust.pio.PFiles.getExtension;
/**
* Created by Stardust on 2018/2/12.
*/
public class MimeTypes {
@Nullable

View File

@@ -3,13 +3,12 @@ package com.stardust.util;
/**
* Created by Stardust on 2017/11/26.
*/
public class Nath {
public static int min(int... ints) {
int min = ints[0];
for (int i = 1; i < ints.length; i++) {
min = ints[i] < min ? ints[i] : min;
min = Math.min(ints[i], min);
}
return min;
}

View File

@@ -7,7 +7,6 @@ import android.net.NetworkInfo;
/**
* Created by Stardust on 2017/4/9.
*/
public class NetworkUtils {
public static boolean isWifiAvailable(Context context) {

View File

@@ -3,7 +3,6 @@ package com.stardust.util;
/**
* Created by Stardust on 2017/12/31.
*/
public class Objects {
/**
@@ -22,7 +21,7 @@ public class Objects {
* @see Object#equals(Object)
*/
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
return java.util.Objects.equals(a, b);
}
/**

View File

@@ -10,7 +10,6 @@ import com.stardust.BuildConfig;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
public final class ResourceMonitor {
private static final String LOG_TAG = "ResourceMonitor";
@@ -133,10 +132,8 @@ public final class ResourceMonitor {
public UnclosedResourceException(Resource resource) {
super("id = " + resource.getResourceId() + ", resource = " + resource);
}
}
public static final class UnclosedResourceDetectedException extends RuntimeException {
public UnclosedResourceDetectedException(Throwable cause) {
super(cause);
@@ -152,7 +149,6 @@ public final class ResourceMonitor {
}
public interface UnclosedResourceDetectedHandler {
void onUnclosedResourceDetected(UnclosedResourceDetectedException detectedException);
}
}

View File

@@ -2,17 +2,12 @@ package com.stardust.util;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Point;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Surface;
import static java.lang.System.out;
/**
* Created by Stardust on 2017/4/26.
*/
public class ScreenMetrics {
private static int deviceScreenHeight;

View File

@@ -3,21 +3,46 @@ package com.stardust.util;
/**
* Created by Stardust on 2017/4/3.
*/
public class SdkVersionUtil {
private static final String[] SDK_VERSIONS = {
"1.0", "1.1", "1.5", "1.6", "2.0", "2.0.1", "2.1.x", "2.2.x",
"2.3", "2.3.3", "3.0.x", "3.1.x", "3.2", "4.0", "4.0.3", "4.1",
"4.2", "4.3", "4.4.2", "4.4W", "5.0", "5.1", "6.0", "7.0", "7.1",
"8.0", "8.1", "9", "10", "11", "12"
/* placeholder */ null,
/* api: 1 */ "1.0",
/* api: 2 */ "1.1",
/* api: 3 */ "1.5",
/* api: 4 */ "1.6",
/* api: 5 */ "2.0",
/* api: 6 */ "2.0.1",
/* api: 7 */ "2.1.x",
/* api: 8 */ "2.2.x",
/* api: 9 */ "2.3",
/* api: 10 */ "2.3.3",
/* api: 11 */ "3.0.x",
/* api: 12 */ "3.1.x",
/* api: 13 */ "3.2",
/* api: 14 */ "4.0",
/* api: 15 */ "4.0.3",
/* api: 16 */ "4.1",
/* api: 17 */ "4.2",
/* api: 18 */ "4.3",
/* api: 19 */ "4.4.2",
/* api: 20 */ "4.4W",
/* api: 21 */ "5.0",
/* api: 22 */ "5.1",
/* api: 23 */ "6.0",
/* api: 24 */ "7.0",
/* api: 25 */ "7.1",
/* api: 26 */ "8.0",
/* api: 27 */ "8.1",
/* api: 28 */ "9",
/* api: 29 */ "10",
/* api: 30 */ "11",
/* api: 31 */ "12",
/* api: 32 */ "13"
};
public static String sdkIntToString(int i) {
if (i > 31) {
return "Unknown";
}
return SDK_VERSIONS[i - 1];
return i > SDK_VERSIONS.length || i < 1 ? "Unknown" : SDK_VERSIONS[i];
}
}

View File

@@ -8,22 +8,21 @@ import java.util.TimerTask;
/**
* Created by Stardust on 2017/4/5.
*/
public class SimpleCache<T> {
public interface Supplier<T> {
T get(String key);
}
private long mPersistTime;
private LimitedHashMap<String, Item<T>> mCache;
private Timer mCacheCheckTimer;
private Supplier<T> mSupplier;
private final long mPersistTime;
private final LimitedHashMap<String, Item<T>> mCache;
private final Timer mCacheCheckTimer;
private final Supplier<T> mSupplier;
public SimpleCache(long persistTime, int cacheSize, long checkInterval, Supplier<T> supplier) {
mPersistTime = persistTime;
mCache = new LimitedHashMap<>(cacheSize);
mSupplier = supplier == null ? new NullSupplier<T>() : supplier;
mSupplier = supplier == null ? new NullSupplier<>() : supplier;
mCacheCheckTimer = new Timer();
startCacheCheck(checkInterval);
}
@@ -81,18 +80,13 @@ public class SimpleCache<T> {
private synchronized void checkCache() {
Iterator<Map.Entry<String, Item<T>>> iterator = mCache.entrySet().iterator();
while (iterator.hasNext()) {
if (!iterator.next().getValue().isValid()) {
iterator.remove();
}
}
mCache.entrySet().removeIf(stringItemEntry -> !stringItemEntry.getValue().isValid());
}
private class Item<T> {
T value;
private long mSaveMillis;
private final long mSaveMillis;
Item(T value) {

View File

@@ -6,7 +6,6 @@ import android.util.SparseArray;
/**
* Created by Stardust on 2017/1/26.
*/
public class SparseArrayEntries<E> {
private final SparseArray<E> mSparseArray = new SparseArray<>();

View File

@@ -2,7 +2,6 @@ package com.stardust.util;
import android.content.SharedPreferences;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -11,7 +10,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* Created by Stardust on 2017/2/3.
*/
public class StateObserver {
public interface OnStateChangedListener {
@@ -32,7 +30,7 @@ public class StateObserver {
private final Map<String, List<OnStateChangedListener>> mKeyStateListenersMap = new HashMap<>();
private SharedPreferences mSharedPreferences;
private final SharedPreferences mSharedPreferences;
public StateObserver(SharedPreferences sharedPreferences) {
mSharedPreferences = sharedPreferences;

View File

@@ -3,7 +3,6 @@ package com.stardust.util;
/**
* Created by Stardust on 2017/5/1.
*/
public interface Supplier<T> {
T get();
}

View File

@@ -5,7 +5,6 @@ import androidx.annotation.NonNull;
/**
* Created by Stardust on 2017/5/3.
*/
public class TextUtils {
public static String join(CharSequence delimiter, Object... tokens) {

View File

@@ -8,11 +8,10 @@ import android.widget.Toast;
/**
* Created by Stardust on 2017/5/2.
*/
public class UiHandler extends Handler {
private Context mContext;
private final Context mContext;
public UiHandler(Context context) {
super(Looper.getMainLooper());
@@ -24,20 +23,10 @@ public class UiHandler extends Handler {
}
public void toast(final String message) {
post(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
});
post(() -> Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show());
}
public void toast(final int resId) {
post(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, resId, Toast.LENGTH_SHORT).show();
}
});
post(() -> Toast.makeText(mContext, resId, Toast.LENGTH_SHORT).show());
}
}

View File

@@ -1,16 +1,14 @@
package com.stardust.util;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by Stardust on 2017/5/2.
*/
public class UnderuseExecutors {
private static ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private static final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
public static void execute(Runnable runnable) {
mExecutor.execute(runnable);

View File

@@ -16,12 +16,11 @@ import android.view.Window;
/**
* Created by Stardust on 2017/1/24.
*/
public class ViewUtil {
@SuppressWarnings("unchecked")
public static <V extends View> V $(View view, @IdRes int resId) {
return (V) view.findViewById(resId);
return view.findViewById(resId);
}
// FIXME: 2018/1/23 not working in some devices (https://github.com/hyb1996/Auto.js/issues/268)

View File

@@ -1,21 +1,18 @@
package com.stardust.util;
import android.content.Context;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewParent;
/**
* Created by Stardust on 2017/7/2.
*/
public class ViewUtils {
public static View findParentById(View view, int id) {
ViewParent parent = view.getParent();
if (parent == null || !(parent instanceof View))
if (!(parent instanceof View viewParent))
return null;
View viewParent = (View) parent;
if (viewParent.getId() == id) {
return viewParent;
}

View File

@@ -39,7 +39,7 @@
<string name="text_error">Error</string>
<string name="text_execution_finished" formatted="false">[%s] finished in %s seconds.\n</string>
<string name="text_no_accessibility_permission">Accessibility service is disabled and the script has stopped</string>
<string name="text_no_floating_window_permission">No \"display over other apps\" permission</string>
<string name="text_no_draw_overlays_permission">No \"display over other apps\" permission</string>
<string name="text_others">Others</string>
<string name="text_please_choose">Please choose</string>
<string name="text_script_running">Script running</string>

View File

@@ -40,7 +40,7 @@
<string name="text_error">错误</string>
<string name="text_execution_finished" formatted="false">[%s] 运行结束 (用时 %s 秒)\n</string>
<string name="text_no_accessibility_permission">无障碍服务未启用</string>
<string name="text_no_floating_window_permission">缺少 \"显示在其他应用上层\" 权限</string>
<string name="text_no_draw_overlays_permission">缺少 \"显示在其他应用上层\" 权限</string>
<string name="text_others">其他</string>
<string name="text_please_choose">请选择</string>
<string name="text_script_running">脚本运行</string>

View File

@@ -45,7 +45,7 @@
<string name="text_error">Error</string>
<string name="text_execution_finished" formatted="false">[%s] finished in %s seconds.\n</string>
<string name="text_no_accessibility_permission">Accessibility service is disabled and the script has stopped</string>
<string name="text_no_floating_window_permission">No \"display over other apps\" permission</string>
<string name="text_no_draw_overlays_permission">No \"display over other apps\" permission</string>
<string name="text_others">Others</string>
<string name="text_please_choose">Please choose</string>
<string name="text_script_running">Script running</string>

View File

@@ -2,10 +2,6 @@ package com.stardust;
import org.junit.Test;
import java.net.Socket;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*