From 964a1a827495e77ab4bc40ac23fdd2a8baf213ad Mon Sep 17 00:00:00 2001 From: fanhuitong <981964879@qq.com> Date: Tue, 28 Jun 2022 10:41:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=80=E5=8F=91=E8=80=85?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 42 +-- app/src/main/AndroidManifest.xml | 139 ++++++---- .../tt/ttutils/activity/KotlinMainActivity.kt | 5 +- .../ttutils/activity/main/MainActivity.java | 66 ++++- .../ttutils/activity/test/TestActivity.java | 102 ++++++++ .../gson/NullStringToEmptyAdapterFactory.java | 45 ++++ .../interceptor/RepeatRequestInterceptor.java | 75 ++++++ .../com/tt/ttutils/utils/java/ApkUtils.java | 102 +++++++- .../com/tt/ttutils/utils/java/AppUtils.java | 1 + .../tt/ttutils/utils/java/DevicesUtils.java | 1 - .../com/tt/ttutils/utils/java/JGYUtils.java | 127 +++++++++ .../tt/ttutils/utils/java/LauncherUtils.java | 175 +++++++++++++ .../tt/ttutils/utils/java/ProcessUtil.java | 96 +++++++ .../com/tt/ttutils/utils/java/TTUtils.java | 20 +- .../main/res/layout-land/activity_main.xml | 50 ++++ .../main/res/layout-port/activity_main.xml | 62 ++++- app/src/main/res/layout/activity_test.xml | 35 +++ app/src/main/res/values/colors.xml | 241 ++++++++++++++++++ niceimageview/build.gradle | 6 +- viewlibrary/build.gradle | 6 +- 20 files changed, 1316 insertions(+), 80 deletions(-) create mode 100644 app/src/main/java/com/tt/ttutils/activity/test/TestActivity.java create mode 100644 app/src/main/java/com/tt/ttutils/gson/NullStringToEmptyAdapterFactory.java create mode 100644 app/src/main/java/com/tt/ttutils/network/interceptor/RepeatRequestInterceptor.java create mode 100644 app/src/main/java/com/tt/ttutils/utils/java/LauncherUtils.java create mode 100644 app/src/main/java/com/tt/ttutils/utils/java/ProcessUtil.java create mode 100644 app/src/main/res/layout/activity_test.xml diff --git a/app/build.gradle b/app/build.gradle index 2b91d61..15988fc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -101,6 +101,15 @@ android { //签名 signingConfigs { + tuixin { + storeFile file("src/keystore/tuixin.jks") + storePassword "123456" + keyAlias "universal" + keyPassword "123456" + v1SigningEnabled true + v2SigningEnabled true + } + xueshibao { storeFile file("src/keystore/xueshibaoos.jks") storePassword "123456" @@ -128,30 +137,23 @@ android { v2SigningEnabled true } - debug { + own { storeFile file("src/keystore/tt.jks") storePassword "fht19961207" keyAlias "key0" keyPassword "981964879aa" v1SigningEnabled true - v2SigningEnabled false - } - - release { - storeFile file("src/keystore/tt.jks") - storePassword "fht19961207" - keyAlias "key0" - keyPassword "981964879aa" - v1SigningEnabled true - v2SigningEnabled false + v2SigningEnabled true } } buildTypes { - zhanRuiRelease.initWith(release) - zhanRuiRelease { + tuiXinDebug.initWith(debug) + tuiXinDebug { + versionNameSuffix "-debug" buildConfigField "String", "platform", '"ZhanRui"' - signingConfig signingConfigs.zhanRui + debuggable true + signingConfig signingConfigs.tuixin } zhanRuiDebug.initWith(debug) @@ -162,6 +164,12 @@ android { signingConfig signingConfigs.zhanRui } + zhanRuiRelease.initWith(release) + zhanRuiRelease { + buildConfigField "String", "platform", '"ZhanRui"' + signingConfig signingConfigs.zhanRui + } + //userdebug rom使用这个版本 zhanRuiUserdebug.initWith(zhanRuiDebug) zhanRuiUserdebug { @@ -202,7 +210,7 @@ android { //Zipalign优化 zipAlignEnabled true //签名 - signingConfig signingConfigs.release + signingConfig signingConfigs.xueshibao //将release版本的包名重命名,加上版本及日期 applicationVariants.all { variant -> variant.outputs.each { output -> @@ -316,8 +324,8 @@ dependencies { implementation 'com.github.bingoogolapple:BGASwipeBackLayout-Android:2.0.2' //圆角 implementation 'de.hdodenhof:circleimageview:2.2.0' - //圆角ImageView - implementation 'com.github.zane618:NiceImageView:1.0.0' +// 圆角ImageView +// implementation 'com.github.zane618:NiceImageView:1.0.0' // 权限请求框架:https://github.com/getActivity/XXPermissions implementation 'com.github.getActivity:XXPermissions:12.3' //动态权限框架 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a8653cf..3d725a6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,24 +10,31 @@ - + + + - + + - + + - + + + + android:protectionLevel="signature" /> + @@ -36,13 +43,17 @@ - + + + - + + - + + @@ -56,29 +67,33 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/ImmerseTheme"> - - - - + + - - + + - - + + + + + + + + + android:exported="true" /> - + + + + android:required="false" /> + + @@ -140,7 +159,8 @@ - + + @@ -159,11 +179,13 @@ - + + + android:process=":xg_vip_service" /> + @@ -172,17 +194,21 @@ - + + + android:authorities="com.tt.ttutils.XGVIP_PUSH_AUTH" /> + + android:authorities="com.tt.ttutils.TPUSH_PROVIDER" /> + + android:exported="true" /> + @@ -192,7 +218,8 @@ - + + + android:exported="false" /> + + android:value="1500026407" /> + + android:value="AQ6C6W1O19LT" /> + + + + tools:replace="android:exported" /> + - + + - + + + android:process=":pushcore" /> + - + + - + + + android:exported="true" /> + @@ -289,14 +328,18 @@ - + + + android:exported="false" /> + - + android:exported="false" /> + + + @@ -313,7 +356,8 @@ - + + @@ -321,7 +365,8 @@ - + + - + + - + + + + diff --git a/app/src/main/java/com/tt/ttutils/activity/KotlinMainActivity.kt b/app/src/main/java/com/tt/ttutils/activity/KotlinMainActivity.kt index 26c16e0..1213f0f 100644 --- a/app/src/main/java/com/tt/ttutils/activity/KotlinMainActivity.kt +++ b/app/src/main/java/com/tt/ttutils/activity/KotlinMainActivity.kt @@ -63,9 +63,10 @@ class KotlinMainActivity : AppCompatActivity(), CancelAdapt { val test = noteAidlInterface.note Log.e("test", test) } - - } + + + } \ No newline at end of file diff --git a/app/src/main/java/com/tt/ttutils/activity/main/MainActivity.java b/app/src/main/java/com/tt/ttutils/activity/main/MainActivity.java index 3d9959f..fa9fb7d 100644 --- a/app/src/main/java/com/tt/ttutils/activity/main/MainActivity.java +++ b/app/src/main/java/com/tt/ttutils/activity/main/MainActivity.java @@ -10,6 +10,7 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.hardware.usb.UsbManager; import android.net.Uri; +import android.os.Bundle; import android.os.Environment; import android.os.IBinder; import android.os.RemoteException; @@ -30,6 +31,7 @@ import com.tt.ttutils.server.main.MainService; import com.tt.ttutils.R; import com.tt.ttutils.utils.java.CmdUtil; import com.tt.ttutils.utils.java.JGYUtils; +import com.tt.ttutils.utils.java.TTUtils; import com.tt.ttutils.utils.java.ToastUtil; import com.tt.ttutils.utils.jni.NDKTools; @@ -40,6 +42,12 @@ import butterknife.BindView; import butterknife.ButterKnife; public class MainActivity extends ImmerseBaseActivity { + @BindView(R.id.tv_qch_Developeroptions) + TextView tv_qch_Developeroptions; + @BindView(R.id.tv_development_settings_enabled) + TextView tv_development_settings_enabled; + @BindView(R.id.tv_adb_enabled) + TextView tv_adb_enabled; @BindView(R.id.textView) TextView textView; @BindView(R.id.button) @@ -78,6 +86,16 @@ public class MainActivity extends ImmerseBaseActivity { @BindView(R.id.bt_start_jgy) Button bt_start_jgy; + @BindView(R.id.tv_statu) + TextView tv_statu; + @BindView(R.id.bt_camera_close) + Button bt_camera_close; + @BindView(R.id.bt_camera_open) + Button bt_camera_open; + @BindView(R.id.bt_camera_refresh) + Button bt_camera_refresh; + + private ServiceConnection mServiceConnection; private INoteAidlInterface noteAidlInterface; private ServiceConnection mLicenseServiceConnection; @@ -105,10 +123,21 @@ public class MainActivity extends ImmerseBaseActivity { // int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //导航栏 // | View.SYSTEM_UI_FLAG_FULLSCREEN;//全屏 // decorView.setSystemUiVisibility(uiOptions); - + Intent intent = getIntent(); + if (intent != null) { + TTUtils.getExtrax(intent); + } mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); } + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + if (intent != null) { + TTUtils.getExtrax(intent); + } + } + @Override public void setListener() { // mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_NONE, true); @@ -309,6 +338,41 @@ public class MainActivity extends ImmerseBaseActivity { // } } }); + + bt_camera_refresh.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int code = Settings.System.getInt(getContentResolver(), "qch_app_camera", 0); + tv_statu.setText("状态:" + code); + } + }); + bt_camera_close.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Settings.System.putInt(getContentResolver(), "qch_app_camera", 1); + Intent cameraIntent = new Intent("qch_camera_forbid").setPackage("com.android.settings"); + sendBroadcast(cameraIntent); + } + }); + bt_camera_open.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Settings.System.putInt(getContentResolver(), "qch_app_camera", 0); + Intent cameraIntent = new Intent("qch_camera_open").setPackage("com.android.settings"); + sendBroadcast(cameraIntent); + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + Log.e(TAG, "onResume: " + Settings.System.getInt(getContentResolver(), "qch_Developeroptions", 0)); + tv_qch_Developeroptions.setText("qch_Developeroptions: " + Settings.System.getInt(getContentResolver(), "qch_Developeroptions", 0)); + Log.e(TAG, "onResume: " + Settings.Global.getInt(getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0)); + tv_development_settings_enabled.setText("development_settings_enabled: " + Settings.Global.getInt(getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0)); + Log.e(TAG, "onResume: " + Settings.Global.getInt(getContentResolver(), Settings.Global.ADB_ENABLED, 0)); + tv_adb_enabled.setText("development_settings_enabled: " + Settings.Global.getInt(getContentResolver(), Settings.Global.ADB_ENABLED, 0)); } private HideAppReceiver hideAppReceiver; diff --git a/app/src/main/java/com/tt/ttutils/activity/test/TestActivity.java b/app/src/main/java/com/tt/ttutils/activity/test/TestActivity.java new file mode 100644 index 0000000..96c5ddb --- /dev/null +++ b/app/src/main/java/com/tt/ttutils/activity/test/TestActivity.java @@ -0,0 +1,102 @@ +package com.tt.ttutils.activity.test; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; + +import com.tt.ttutils.R; +import com.tt.ttutils.utils.java.TTUtils; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class TestActivity extends AppCompatActivity { + private String TAG = TestActivity.class.getSimpleName(); + + @BindView(R.id.bt1) + Button bt1; + @BindView(R.id.bt2) + Button bt2; + @BindView(R.id.bt3) + Button bt3; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_test); + ButterKnife.bind(this); + Intent intent = getIntent(); + if (intent != null) { + TTUtils.getExtrax(intent); + } + bt1.setOnClickListener(view -> setDefault("com.aoleyunos.dop1")); + bt2.setOnClickListener(view -> setDefault("com.aoleyunos.dop2")); + bt3.setOnClickListener(view -> setDefault("com.aoleyun.os")); + } + + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + if (intent != null) { + TTUtils.getExtrax(intent); + } + } + + private void setDefault(String pkg) { + String className = getStartClassName(pkg); + Intent intent = new Intent("setDefaultLauncher"); + intent.putExtra("package", pkg); + intent.putExtra("className", className); + //爱华定制 + intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.AoleReceiver")); + intent.setPackage("com.android.settings"); + sendBroadcast(intent); + } + + public String getStartClassName(String pkg) { + PackageInfo packageInfo = null; + try { + packageInfo = getPackageManager().getPackageInfo(pkg, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageInfo == null) { + return ""; + } else { + // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent + Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); + resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); + resolveIntent.setPackage(packageInfo.packageName); + + // 通过getPackageManager()的queryIntentActivities方法遍历 + List resolveinfoList = getPackageManager() + .queryIntentActivities(resolveIntent, 0); + if (resolveinfoList == null || resolveinfoList.size() == 0) { + return ""; + } + + ResolveInfo resolveinfo = resolveinfoList.iterator().next(); + if (resolveinfo != null) { + // packagename = 参数packname + String packageName = resolveinfo.activityInfo.packageName; + // 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packagename.mainActivityname] + String className = resolveinfo.activityInfo.name; + return className; + } else { + return ""; + } + } + } + +} diff --git a/app/src/main/java/com/tt/ttutils/gson/NullStringToEmptyAdapterFactory.java b/app/src/main/java/com/tt/ttutils/gson/NullStringToEmptyAdapterFactory.java new file mode 100644 index 0000000..6f3174f --- /dev/null +++ b/app/src/main/java/com/tt/ttutils/gson/NullStringToEmptyAdapterFactory.java @@ -0,0 +1,45 @@ +package com.tt.ttutils.gson; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; + +public class NullStringToEmptyAdapterFactory implements TypeAdapterFactory { + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + + Class rawType = (Class) type.getRawType(); + if (rawType != String.class) { + return null; + } + return (TypeAdapter) new StringAdapter(); + } + + public static class StringAdapter extends TypeAdapter { + @Override + public String read(JsonReader reader) throws IOException { + if (reader.peek() == JsonToken.NULL) { + reader.nextNull(); + return ""; + } + return reader.nextString(); + } + + @Override + public void write(JsonWriter writer, String value) throws IOException { + if (value == null) { + writer.nullValue(); + return; + } + writer.value(value); + } + } + +} + diff --git a/app/src/main/java/com/tt/ttutils/network/interceptor/RepeatRequestInterceptor.java b/app/src/main/java/com/tt/ttutils/network/interceptor/RepeatRequestInterceptor.java new file mode 100644 index 0000000..cee780d --- /dev/null +++ b/app/src/main/java/com/tt/ttutils/network/interceptor/RepeatRequestInterceptor.java @@ -0,0 +1,75 @@ +package com.tt.ttutils.network.interceptor; + +import android.util.Log; + +import com.tt.ttutils.utils.java.MD5Util; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; + +import okhttp3.Interceptor; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okio.Buffer; + +public class RepeatRequestInterceptor implements Interceptor { + private static final String TAG = RepeatRequestInterceptor.class.getSimpleName(); + + private final ConcurrentHashMap requestIdsMap = new ConcurrentHashMap<>(); + public static final String REPEAT_REQUEST_PROTOCOL = "OKHTTP_REPEAT_REQUEST_PROTOCOL"; + + @NotNull + @Override + public Response intercept(@NotNull Chain chain) throws IOException { + Request request = chain.request(); + + Response response = chain.proceed(chain.request()); + String content = response.body().string(); +// Log.e(TAG, "请求体返回:| Response:" + content); + //相同的请求 + String requestKey = MD5Util.getUpperMD5Str(request.method() + request.url().toString() + request.body()); + long time = System.currentTimeMillis();//请求时间 + try { + if (requestIdsMap.size() > 0 && requestIdsMap.containsKey(requestKey)) { +// Log.e("REPEAT-REQUEST", "重复请求:" + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url() + "\t" + bodyToString(request)); + Log.e("REPEAT-REQUEST", "重复请求:" + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url()); + //下面这行写了不会抛出onerror +// chain.call().cancel(); + return new Response.Builder() + .protocol(Protocol.get(REPEAT_REQUEST_PROTOCOL)) + .request(request) //multi thread + .build(); + } + requestIdsMap.put(requestKey, time); +// Log.e("REPEAT-REQUEST", "注册请求:" + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url() + "\t" + bodyToString(request)); + Log.e("REPEAT-REQUEST", "注册请求:" + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url()); +// RepeatRequestInterceptor.Builder builder = request.newBuilder(); +// builder.addHeader("header", jsonObject.toString()); + return chain.proceed(request); + } catch (IOException e) { + Log.e(TAG, "intercept: " + e.getMessage()); + throw e; + } finally { + if (requestIdsMap.containsKey(requestKey) && requestIdsMap.containsValue(time)) {//请求任务完成删除map中的数据 + requestIdsMap.remove(requestKey); + Log.e("REPEAT-REQUEST", "移除请求:" + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url() + "\t" + bodyToString(request)); +// Log.e("REPEAT-REQUEST", "移除请求:" + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url()); + } + } + } + + private static String bodyToString(final Request request) { + try { + final Request copy = request.newBuilder().build(); + final Buffer buffer = new Buffer(); + copy.body().writeTo(buffer); + return buffer.readUtf8(); + } catch (Exception e) { + return "-"; + } + } + +} diff --git a/app/src/main/java/com/tt/ttutils/utils/java/ApkUtils.java b/app/src/main/java/com/tt/ttutils/utils/java/ApkUtils.java index 3b6ded7..ac3ead6 100644 --- a/app/src/main/java/com/tt/ttutils/utils/java/ApkUtils.java +++ b/app/src/main/java/com/tt/ttutils/utils/java/ApkUtils.java @@ -1,15 +1,107 @@ package com.tt.ttutils.utils.java; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; +import android.content.pm.IPackageDataObserver; +import android.content.pm.IPackageStatsObserver; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.text.TextUtils; +import android.content.pm.PackageStats; +import android.os.RemoteException; +import android.util.Log; -import java.util.List; +import java.io.File; +import java.lang.reflect.Method; public class ApkUtils { + private static final String TAG = ApkUtils.class.getSimpleName(); + private final long MAX_WAIT_TIME = 60 * 1000; + private final long WAIT_TIME_INCR = 10 * 1000; + /** + * 通过包名获取大小 + * + * @param context + * @param packageName + * @return + */ + public static long getPackageSize(Context context, String packageName) { + + PackageManager packageManager = context.getPackageManager(); + PackageInfo packageInfo = null; + try { + packageInfo = packageManager.getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageInfo == null) { + return 0L; + } else { + return new File(packageInfo.applicationInfo.publicSourceDir).length(); + } + } + + public long getApplicationCache(Context context, String packageName) throws Exception { + try { + PackageStatsObserver observer = new PackageStatsObserver(); + // wait on observer + synchronized (observer) { + Method method = PackageManager.class.getMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class); + method.invoke(context.getPackageManager(), packageName, observer); +// getPm().getPackageSizeInfo(packageName, UserHandle.myUserId(), observer); + long waitTime = 0; + while ((!observer.isDone()) || (waitTime > MAX_WAIT_TIME)) { + observer.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if (!observer.isDone()) { + throw new Exception("Timed out waiting for PackageStatsObserver.onGetStatsCompleted"); + } + } + Log.d(TAG, "toString " + observer.stats.toString()); + return observer.stats.dataSize + observer.stats.cacheSize; + } catch (RemoteException e) { + Log.w(TAG, "Failed to get handle for PackageManger Exception: " + e); + return -1; + } catch (InterruptedException e) { + Log.w(TAG, "InterruptedException :" + e); + return -1; + } + } + + static class PackageDataObserver extends IPackageDataObserver.Stub { + public boolean retValue = false; + private boolean doneFlag = false; + + public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { + synchronized (this) { + retValue = succeeded; + doneFlag = true; + notifyAll(); + } + } + + public boolean isDone() { + return doneFlag; + } + } + + static class PackageStatsObserver extends IPackageStatsObserver.Stub { + boolean retValue = false; + PackageStats stats; + private boolean doneFlag = false; + + public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException { + synchronized (this) { + retValue = succeeded; + stats = pStats; + doneFlag = true; + notifyAll(); + } + } + + public boolean isDone() { + return doneFlag; + } + } } diff --git a/app/src/main/java/com/tt/ttutils/utils/java/AppUtils.java b/app/src/main/java/com/tt/ttutils/utils/java/AppUtils.java index e22403f..b03cccd 100644 --- a/app/src/main/java/com/tt/ttutils/utils/java/AppUtils.java +++ b/app/src/main/java/com/tt/ttutils/utils/java/AppUtils.java @@ -23,6 +23,7 @@ public class AppUtils { } //https://www.jianshu.com/p/9dac8c2aeb4d + //https://www.jianshu.com/p/33695ee91d18 public static boolean openPackage(Context context, String packageName) { Context pkgContext = getPackageContext(context, packageName); diff --git a/app/src/main/java/com/tt/ttutils/utils/java/DevicesUtils.java b/app/src/main/java/com/tt/ttutils/utils/java/DevicesUtils.java index aaab161..7cc635f 100644 --- a/app/src/main/java/com/tt/ttutils/utils/java/DevicesUtils.java +++ b/app/src/main/java/com/tt/ttutils/utils/java/DevicesUtils.java @@ -131,5 +131,4 @@ public class DevicesUtils { } return jsonObject.toString(); } - } diff --git a/app/src/main/java/com/tt/ttutils/utils/java/JGYUtils.java b/app/src/main/java/com/tt/ttutils/utils/java/JGYUtils.java index cd989dd..ac90f06 100644 --- a/app/src/main/java/com/tt/ttutils/utils/java/JGYUtils.java +++ b/app/src/main/java/com/tt/ttutils/utils/java/JGYUtils.java @@ -5,8 +5,11 @@ import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.util.Log; +import com.tt.ttutils.BuildConfig; import com.tt.ttutils.disklrucache.CacheHelper; import com.tt.ttutils.receiver.BootReceiver; @@ -20,6 +23,19 @@ public class JGYUtils { private CacheHelper cacheHelper; + public static int UnknowPlatform = 0; + public static int MTKPlatform = 1; + // TODO: 2022/4/23 标签替换未完成 + public static int CubePlatform = 2; + public static int ZhanruiPlatform = 3; + + + public static String Other = "其他"; + public static String MTKTag = "MTK"; + // TODO: 2022/4/23 标签替换未完成 + public static String CubeTag = "展锐cube"; + public static String ZhanruiTag = "展锐"; + private JGYUtils(Context context) { if (context == null) { throw new RuntimeException("Context is NULL"); @@ -43,6 +59,117 @@ public class JGYUtils { return sInstance; } + public int checkSNPlatform(String sn) { + String secondChars = sn.substring(1, 2); + if ("N".equalsIgnoreCase(secondChars)) {//MTK平台 + return MTKPlatform; + } else if ("R".equalsIgnoreCase(secondChars)) {//展锐平台 + return ZhanruiPlatform; + } else { + Log.e(TAG, "checkSNPlatform: " + "sn: " + sn + "没有对应平台"); + return UnknowPlatform; + } + } + + public int checkAppPlatform() { + String platform = BuildConfig.platform; + if ("MTK".equalsIgnoreCase(platform)) { + Log.i(TAG, "checkAppPlatform: " + "MTK平台"); + return MTKPlatform; + } else if ("ZhanRui".equalsIgnoreCase(platform)) { + Log.i(TAG, "checkAppPlatform: " + "展锐平台"); + return ZhanruiPlatform; + } else if ("ZhanRuiCube".equalsIgnoreCase(platform)) { + Log.i(TAG, "checkAppPlatform: " + "酷比平台"); + return CubePlatform; + } else { + Log.i(TAG, "checkAppPlatform: " + "没有数据"); + return UnknowPlatform; + } + } + + public boolean isSamePlatform(String platform) { + String AppPlatform = BuildConfig.platform; + if ("ZhanRui".equals(AppPlatform)) { + return ZhanruiTag.equals(platform); + } else { + return AppPlatform.equals(platform); + } + } + + public interface GetAppPlatformCallback { + void AppPlatform(int platform); + } + + public void getAppPlatform(GetAppPlatformCallback getAppPlatformCallback) { + String platform = BuildConfig.platform; + if ("MTK".equalsIgnoreCase(platform)) { + getAppPlatformCallback.AppPlatform(MTKPlatform); + } else if ("ZhanRui".equalsIgnoreCase(platform)) { + getAppPlatformCallback.AppPlatform(ZhanruiPlatform); + } else if ("ZhanRuiCube".equalsIgnoreCase(platform)) { + getAppPlatformCallback.AppPlatform(CubePlatform); + } else { + getAppPlatformCallback.AppPlatform(UnknowPlatform); + } + } + + public String getAppPlatform() { + String platform = BuildConfig.platform; + if ("MTK".equalsIgnoreCase(platform)) { + return MTKTag; + } else if ("ZhanRui".equalsIgnoreCase(platform)) { + return ZhanruiTag; + } else if ("ZhanRuiCube".equalsIgnoreCase(platform)) { + return CubeTag; + } else { + return Other; + } + } + + /** + * 从Manifest中获取meta-data值 + * https://blog.csdn.net/yue_233/article/details/91453451 + * + * @return + */ + public String getStringMetaData() { + ApplicationInfo appInfo = null; + try { + appInfo = mContext.getPackageManager().getApplicationInfo(mContext.getPackageName(), PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + String value = appInfo.metaData.getString("CHANNEL_VALUE"); + return value; + } + + public static boolean isOfficialVersion() { + String channelValue = JGYUtils.getInstance().getStringMetaData(); + return "official".equals(channelValue); + } + + public static boolean isOfficialVersion(Context context) { + Log.e(TAG, "isOfficialVersion: " + ProcessUtil.getCurrentProcessName(context)); + String channelValue = JGYUtils.getInstance().getStringMetaData(); + return "official".equals(channelValue); + } + + public static boolean isNewlyVersion() { + String channelValue = JGYUtils.getInstance().getStringMetaData(); + return "beta".equals(channelValue); + } + + public static boolean isBetaVersion() { + String channelValue = JGYUtils.getInstance().getStringMetaData(); + return "beta".equals(channelValue); + } + + public static String getCHANNEL_VALUE() { + return JGYUtils.getInstance().getStringMetaData(); + } + + public static final String PACKAGE_DEVICEINFO = "com.aoleyun.sn"; public static final String CLASS_DEVICEINFO = "com.aoleyun.sn.receiver.BootReceiver"; diff --git a/app/src/main/java/com/tt/ttutils/utils/java/LauncherUtils.java b/app/src/main/java/com/tt/ttutils/utils/java/LauncherUtils.java new file mode 100644 index 0000000..79fa4c2 --- /dev/null +++ b/app/src/main/java/com/tt/ttutils/utils/java/LauncherUtils.java @@ -0,0 +1,175 @@ +package com.tt.ttutils.utils.java; + +import android.app.Activity; +import android.app.WallpaperManager; +import android.app.role.RoleManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Process; +import android.os.UserHandle; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.RenderScript; +import android.renderscript.ScriptIntrinsicBlur; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.WindowManager; + +import com.tt.ttutils.R; + +import java.io.IOException; +import java.util.concurrent.Executor; +import java.util.function.Consumer; + +public class LauncherUtils { + public static void setRoleHolderAsUser(Context context, String packageName) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + String roleName = "android.app.role.HOME"; + boolean add = true; + int flags = 0; + UserHandle user = Process.myUserHandle(); + Log.i("settingssssssstemf", (add ? "Adding" : "Removing") + " package as role holder, role: " + + roleName + ", package: " + packageName); + if (JGYUtils.getInstance().checkAppPlatform() != JGYUtils.MTKPlatform) { + RoleManager roleManager = context.getSystemService(RoleManager.class); + Executor executor = context.getMainExecutor(); + Consumer callback = successful -> { + if (successful) { + Log.d("settingssssssstemf", "Package " + (add ? "added" : "removed") + + " as role holder, role: " + roleName + ", package: " + packageName); + } else { + Log.d("settingssssssstemf", "Failed to " + (add ? "add" : "remove") + + " package as role holder, role: " + roleName + ", package: " + + packageName); + } + }; + roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback); + Log.i("settingssssssstemf", "addRoleHolderAsUser done"); + } + } else { + + } + } + + // private void setDefault() { +// String mRoleName ="android.app.role.HOME"; +// final Intent intent = new Intent(Intent.ACTION_MANAGE_DEFAULT_APP) +// .putExtra(Intent.EXTRA_ROLE_NAME, mRoleName); +// startActivity(intent); +// } + + public static boolean isDefaultHome(Context context) { + Intent intent = new Intent(Intent.ACTION_MAIN);//Intent.ACTION_VIEW + intent.addCategory("android.intent.category.HOME"); + intent.addCategory("android.intent.category.DEFAULT"); + PackageManager pm = context.getPackageManager(); + ResolveInfo info = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); + boolean isDefault = context.getPackageName().equals(info.activityInfo.packageName); + return isDefault; + } + + private String getHomeLauncher(Context context) { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_HOME); + ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0); + String currentHomePackage = resolveInfo.activityInfo.packageName; + return currentHomePackage; + } + + private void setDefaultL(Context context) { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory("android.intent.category.HOME"); + try { + intent.setComponent(new ComponentName("android", "com.android.internal.app.ResolverActivity")); + context.startActivity(intent); + } catch (Exception e) { + try { + intent.setComponent(new ComponentName("com.huawei.android.internal.app", "com.huawei.android.internal.app.HwResolverActivity"));//这个类有些华为手机找不到 + context.startActivity(intent); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + } + + public Bitmap blur(Context context, Bitmap image) { + int width = Math.round(image.getWidth() * 0.4f); + int height = Math.round(image.getHeight() * 0.4f); + Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false); + Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); + RenderScript rs = RenderScript.create(context); + ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); + Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap); + Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); + blurScript.setRadius(25f); + blurScript.setInput(tmpIn); + blurScript.forEach(tmpOut); + tmpOut.copyTo(outputBitmap); + return outputBitmap; + } + + public Bitmap getWallpaperBg(Context context) { + WallpaperManager wallpaperManager = WallpaperManager.getInstance(context); + Drawable wallpaperDrawable = wallpaperManager.getDrawable(); + Bitmap bm = ((BitmapDrawable) wallpaperDrawable).getBitmap(); + Bitmap bitmap = cropImage(context, bm); + return bitmap; + } + + private void SetWallPaper(Activity activity) { + //利用WallpaparManager,添加权限set_wallpaper + WallpaperManager wallpaperManager = WallpaperManager.getInstance(activity); + try { + wallpaperManager.setBitmap(BitmapFactory.decodeResource(activity.getResources(), R.drawable.wallpapers)); + } catch (IOException e) { + e.printStackTrace(); + Log.e("TT", e.getMessage()); + } + SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putInt("SetWallPaper", 1); + editor.apply(); + //getSystemService(WALLPAPER_SERVICE)获取wallpaperManager会出问题 + /* @SuppressLint("ServiceCast") + WallpaperManager manager =(WallpaperManager)getSystemService(WALLPAPER_SERVICE); + try { + manager.setBitmap(BitmapFactory.decodeResource(getResources(),R.drawable.pic1)); + } catch (IOException e) { + e.printStackTrace(); + }*/ + } + + private Bitmap cropImage(Context context, Bitmap oldBitmap) { + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + DisplayMetrics dm = new DisplayMetrics(); + wm.getDefaultDisplay().getRealMetrics(dm); + int width = dm.widthPixels; // 屏幕宽度(像素)1200 + int height = dm.heightPixels; // 屏幕高度(像素)1920 + int picWidth = oldBitmap.getWidth(); + int picHeight = oldBitmap.getHeight(); + float wScala = (float) height / width; + float bScala = (float) picHeight / picWidth; + int newPicWidth; + int newpicHeight; + Bitmap bitmap = null; + if (wScala > bScala) { + newPicWidth = (int) (picWidth / wScala); + newpicHeight = picHeight; + bitmap = Bitmap.createBitmap(oldBitmap, (newPicWidth - width) / 2, 0, newPicWidth, newpicHeight); + } else { + newPicWidth = picWidth; + newpicHeight = (int) (picHeight * wScala); + bitmap = Bitmap.createBitmap(oldBitmap, 0, (picHeight - newpicHeight) / 2, newPicWidth, newpicHeight); + } + return bitmap; + } +} diff --git a/app/src/main/java/com/tt/ttutils/utils/java/ProcessUtil.java b/app/src/main/java/com/tt/ttutils/utils/java/ProcessUtil.java new file mode 100644 index 0000000..d17a6dc --- /dev/null +++ b/app/src/main/java/com/tt/ttutils/utils/java/ProcessUtil.java @@ -0,0 +1,96 @@ +package com.tt.ttutils.utils.java; + +import android.app.ActivityManager; +import android.app.Application; +import android.content.Context; +import android.os.Build; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.lang.reflect.Method; +import java.util.List; + +public class ProcessUtil { + private static String currentProcessName; + + /** + * @return 当前进程名 + */ + @Nullable + public static String getCurrentProcessName(@NonNull Context context) { + if (!TextUtils.isEmpty(currentProcessName)) { + return currentProcessName; + } + + //1)通过Application的API获取当前进程名 + currentProcessName = getCurrentProcessNameByApplication(); + if (!TextUtils.isEmpty(currentProcessName)) { + return currentProcessName; + } + + //2)通过反射ActivityThread获取当前进程名 + currentProcessName = getCurrentProcessNameByActivityThread(); + if (!TextUtils.isEmpty(currentProcessName)) { + return currentProcessName; + } + + //3)通过ActivityManager获取当前进程名 + currentProcessName = getCurrentProcessNameByActivityManager(context); + + return currentProcessName; + } + + + /** + * 通过Application新的API获取进程名,无需反射,无需IPC,效率最高。 + */ + public static String getCurrentProcessNameByApplication() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + return Application.getProcessName(); + } + return null; + } + + /** + * 通过反射ActivityThread获取进程名,避免了ipc + */ + public static String getCurrentProcessNameByActivityThread() { + String processName = null; + try { + final Method declaredMethod = Class.forName("android.app.ActivityThread", false, Application.class.getClassLoader()) + .getDeclaredMethod("currentProcessName", (Class[]) new Class[0]); + declaredMethod.setAccessible(true); + final Object invoke = declaredMethod.invoke(null, new Object[0]); + if (invoke instanceof String) { + processName = (String) invoke; + } + } catch (Throwable e) { + e.printStackTrace(); + } + return processName; + } + + /** + * 通过ActivityManager 获取进程名,需要IPC通信 + */ + public static String getCurrentProcessNameByActivityManager(@NonNull Context context) { + if (context == null) { + return null; + } + int pid = android.os.Process.myPid(); + ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + if (am != null) { + List runningAppList = am.getRunningAppProcesses(); + if (runningAppList != null) { + for (ActivityManager.RunningAppProcessInfo processInfo : runningAppList) { + if (processInfo.pid == pid) { + return processInfo.processName; + } + } + } + } + return null; + } +} diff --git a/app/src/main/java/com/tt/ttutils/utils/java/TTUtils.java b/app/src/main/java/com/tt/ttutils/utils/java/TTUtils.java index 9206523..257c0ea 100644 --- a/app/src/main/java/com/tt/ttutils/utils/java/TTUtils.java +++ b/app/src/main/java/com/tt/ttutils/utils/java/TTUtils.java @@ -3,12 +3,17 @@ package com.tt.ttutils.utils.java; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.os.Bundle; import android.util.Log; import com.tt.ttutils.disklrucache.CacheHelper; +import java.util.Iterator; +import java.util.Set; + public class TTUtils { private static final String TAG = TTUtils.class.getSimpleName(); @@ -60,5 +65,18 @@ public class TTUtils { return false; } - + public static void getExtrax(Intent intent) { + if (intent == null) return; + String action = intent.getAction(); + Log.e(TAG, "getExtrax: " + action); + Bundle bundle = intent.getExtras(); + if (bundle == null) return; + Set ks = bundle.keySet(); + Iterator iterator = ks.iterator(); + while (iterator.hasNext()) { + String key = iterator.next(); + Log.e("KEY", key); + Log.e("value", intent.getStringExtra(key)); + } + } } diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml index 8a29a72..5b9e6bd 100644 --- a/app/src/main/res/layout-land/activity_main.xml +++ b/app/src/main/res/layout-land/activity_main.xml @@ -17,6 +17,56 @@ android:gravity="center" android:orientation="vertical"> + + + + +