借助RX实现全局Toast工具类
RX主要用于切换到主线程,也用换成其他方式处理
需要在Application中先执行ToastUtils.init(getApplicationContext());
import android.content.Context;
import android.text.TextUtils;
import android.widget.Toast;
public class ToastUtils {
private static Toast toast;
private static Context context;
public static void init(Context context) {
ToastUtils.context = context.getApplicationContext();
}
public static synchronized void debugShow(String content) {
if (BuildConfig.DEBUG) {
showToast(content);
}
}
public static synchronized void showToast(int id) {
showToast(context.getString(id));
}
public static synchronized void showToast(String content) {
if (TextUtils.isEmpty(content)) {
return;
}
RxHelper.excuteMainThread((p) -> {
cancel();
toast = Toast.makeText(context, content, Toast.LENGTH_SHORT);
toast.show();
}, content);
}
public static synchronized void cancel() {
if (toast != null) {
toast.cancel();
toast = null;
}
}
}
/**
* 使用Rx的线程切换功能,主线程执行
*
* @param runnable 执行体
* @param param 参数
* @param <T> 参数类型
*/
@SuppressLint("CheckResult")
public static <T> void excuteMainThread(Runnable<T> runnable, T param) {
Observable.just(SystemClock.uptimeMillis())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> runnable.run(param));
}
SharedPreferences存取数据
用于通过SharedPreferences保存跟获取数据,通过调用save跟get方法就可以
import android.content.Context;
import android.content.SharedPreferences;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
public class PersistUtil {
private static final WeakHashMap<Operator, String> maps = new WeakHashMap<>();
/**
* 获取写入字符串操作符
*
* @param dbName 文件(或表)名称,分类名称
* @return {@link IStringReader}
*/
public static IStringWriter getStringWriter(Context context, String dbName) {
return getOperator(context, dbName);
}
/**
* 获取读取字符串操作符
*
* @param dbName 文件(或表)名称,分类名称
* @return {@link IStringWriter}
*/
public static IStringReader getStringReader(Context context, String dbName) {
return getOperator(context, dbName);
}
/**
* 保存字符串内容。简单的封装
*
* @param dbName 文件名
* @param key 键值
* @param value 内容
*/
public static void save(Context context, String dbName, String key, String value) {
getOperator(context, dbName).save(key, value);
}
/**
* 读取字符串内容。简单的封装
*
* @param dbName 文件名
* @param key 键值
* @param defValue 默认内容
* @return 读取到的字符串。如果该键值无内容,则返回defValue
*/
public static String get(Context context, String dbName, String key, String defValue) {
return getOperator(context, dbName).read(key, defValue);
}
private static Operator getOperator(Context context, String dbName) {
synchronized (maps) {
Set<Map.Entry<Operator, String>> entrySet = maps.entrySet();
for (Map.Entry<Operator, String> entry : entrySet) {
if (entry.getValue().equals(dbName)) {
return entry.getKey();
}
}
Operator operator = new Operator(context, dbName);
maps.put(operator, dbName);
return operator;
}
}
private static class Operator implements IStringWriter, IStringReader {
final String dbName;
final SharedPreferences sp;
Operator(Context context, String dbName) {
this.dbName = dbName;
this.sp = context.getSharedPreferences(dbName, Context.MODE_PRIVATE);
}
@Override
public String read(String key, String defValue) {
return sp.getString(key, defValue);
}
@Override
public boolean save(String key, String value) {
sp.edit().putString(key, value).apply();
return true;
}
}
interface IStringWriter {
/**
* 保存字符串
*
* @param key key
* @param value 需要保存的内容
* @return 是否保存成功
*/
boolean save(String key, String value);
}
interface IStringReader {
/**
* 读取内容
*
* @param key Key
* @return 获取到的内容。如果不存在则返回null
*/
default String read(String key) {
return read(key, null);
}
/**
* 读取内容
*
* @param key Key
* @param defValue 不存在时的默认值
* @return 获取到的内容。如果不存在则返回defValue
*/
String read(String key, String defValue);
}
}
Logcat工具类
可定位到具体代码位置
package com.example.tool.util;
import android.util.Log;
import com.example.tool.BuildConfig;
/**
* logcat工具类,能够定位到具体位置
*/
public class LogUtils {
private static String getSimpleClassName(String name) {
int lastIndex = name.lastIndexOf(".");
return name.substring(lastIndex + 1);
}
public static void i(String tag, String msg) {
if (BuildConfig.DEBUG) {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
int methodCount = 1;
int stackOffset = getStackOffset(trace);
if (methodCount + stackOffset > trace.length) {
methodCount = trace.length - stackOffset - 1;
}
for (int i = methodCount; i > 0; i--) {
int stackIndex = i + stackOffset;
if (stackIndex >= trace.length) {
continue;
}
StackTraceElement element = trace[stackIndex];
StringBuilder builder = new StringBuilder();
builder.append(getSimpleClassName(element.getClassName()))
.append(".")
.append(element.getMethodName())
.append(" ")
.append(" (")
.append(element.getFileName())
.append(":")
.append(element.getLineNumber())
.append(")")
.append(tag + ":----->")
.append(msg);
Log.i(tag, builder.toString());
}
}
}
public static void v(String tag, String msg) {
if (BuildConfig.DEBUG) {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
int methodCount = 1;
int stackOffset = getStackOffset(trace);
if (methodCount + stackOffset > trace.length) {
methodCount = trace.length - stackOffset - 1;
}
for (int i = methodCount; i > 0; i--) {
int stackIndex = i + stackOffset;
if (stackIndex >= trace.length) {
continue;
}
StackTraceElement element = trace[stackIndex];
StringBuilder builder = new StringBuilder();
builder.append(getSimpleClassName(element.getClassName()))
.append(".")
.append(element.getMethodName())
.append(" ")
.append(" (")
.append(element.getFileName())
.append(":")
.append(element.getLineNumber())
.append(")")
.append(tag + ":----->")
.append(msg);
Log.v(tag, builder.toString());
}
}
}
public static void w(String tag, String msg) {
if (BuildConfig.DEBUG) {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
int methodCount = 1;
int stackOffset = getStackOffset(trace);
if (methodCount + stackOffset > trace.length) {
methodCount = trace.length - stackOffset - 1;
}
for (int i = methodCount; i > 0; i--) {
int stackIndex = i + stackOffset;
if (stackIndex >= trace.length) {
continue;
}
StackTraceElement element = trace[stackIndex];
StringBuilder builder = new StringBuilder();
builder.append(getSimpleClassName(element.getClassName()))
.append(".")
.append(element.getMethodName())
.append(" ")
.append(" (")
.append(element.getFileName())
.append(":")
.append(element.getLineNumber())
.append(")")
.append(tag + ":----->")
.append(msg);
Log.w(tag, builder.toString());
}
}
}
public static void e(String tag, String msg) {
if (BuildConfig.DEBUG) {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
int methodCount = 1;
int stackOffset = getStackOffset(trace);
if (methodCount + stackOffset > trace.length) {
methodCount = trace.length - stackOffset - 1;
}
for (int i = methodCount; i > 0; i--) {
int stackIndex = i + stackOffset;
if (stackIndex >= trace.length) {
continue;
}
StackTraceElement element = trace[stackIndex];
StringBuilder builder = new StringBuilder();
builder.append(getSimpleClassName(element.getClassName()))
.append(".")
.append(element.getMethodName())
.append(" ")
.append(" (")
.append(element.getFileName())
.append(":")
.append(element.getLineNumber())
.append(")")
.append(tag + ":----->")
.append(msg);
Log.e(tag, builder.toString());
}
}
}
public static void d(String tag, String msg) {
if (BuildConfig.DEBUG) {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
int methodCount = 1;
int stackOffset = getStackOffset(trace);
if (methodCount + stackOffset > trace.length) {
methodCount = trace.length - stackOffset - 1;
}
for (int i = methodCount; i > 0; i--) {
int stackIndex = i + stackOffset;
if (stackIndex >= trace.length) {
continue;
}
StackTraceElement element = trace[stackIndex];
StringBuilder builder = new StringBuilder();
builder.append(getSimpleClassName(element.getClassName()))
.append(".")
.append(element.getMethodName())
.append(" ")
.append(" (")
.append(element.getFileName())
.append(":")
.append(element.getLineNumber())
.append(")")
.append(tag + ":----->")
.append(msg);
Log.d(tag, builder.toString());
}
}
}
private static int getStackOffset(StackTraceElement[] trace) {
for (int i = 2; i < trace.length; i++) {
StackTraceElement e = trace[i];
String name = e.getClassName();
if (!name.equals(LogUtils.class.getName())) {
return --i;
}
}
return -1;
}
}
权限申请工具类
package com.panzq.exovideodemo.utils;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import androidx.core.app.ActivityCompat;
public class PermissionUtils {
public static final int REQUEST_PERMISSION_CODE = 100;
public static void grantePermission(Context context, String[] permissions) {
boolean isGranted = false;
if (android.os.Build.VERSION.SDK_INT >= 23) {
if (permissions != null) {
for (int i = 0; i < permissions.length; i++) {
if (!checkPermission(context, permissions[i])) {
isGranted = false;
break;
}
}
}
if (!isGranted) {
//acitivty中申请权限
ActivityCompat.requestPermissions(((Activity) context), permissions, REQUEST_PERMISSION_CODE);
}
}
}
public static boolean checkPermission(Context context, String permission) {
if (context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) {
return true;
}
return false;
}
}
获取所有U盘路径
package com.panzq.exovideodemo.utils;
import android.content.Context;
import android.os.storage.StorageManager;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class UsbUtils {
public static String[] getVolumePaths(Context context) {
String paths[] = null;
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
try {
Class<?>[] paramClasses = {};
Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", paramClasses);
getVolumePathsMethod.setAccessible(true);
Object[] params = {};
paths = (String[]) getVolumePathsMethod.invoke(storageManager, params);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return paths;
}
}