357 lines
14 KiB
Java
357 lines
14 KiB
Java
package com.example.shell;
|
|
|
|
import android.app.Activity;
|
|
import android.app.AlertDialog;
|
|
import android.app.Application;
|
|
import android.app.Dialog;
|
|
import android.graphics.Color;
|
|
import android.os.Handler;
|
|
import android.os.Looper;
|
|
import android.view.Gravity;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.Button;
|
|
import android.widget.FrameLayout;
|
|
import android.widget.LinearLayout;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
import java.lang.ref.WeakReference;
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Method;
|
|
import java.util.Map;
|
|
|
|
public class HookApplication extends Application {
|
|
|
|
public static boolean showDialog = true;
|
|
public static boolean showFullscreen = true; // ✅ 全屏弹窗开关
|
|
|
|
private AlertDialog dialog = null;
|
|
private Dialog fullscreenDialog = null; // ✅ 全屏弹窗引用
|
|
|
|
public static boolean showImageFullscreen = true; // ✅ 控制图片弹窗
|
|
private Dialog imageDialog = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private WeakReference<Activity> currentActivityRef = null;
|
|
@Override
|
|
public void onCreate() {
|
|
super.onCreate();
|
|
|
|
Toast.makeText(getApplicationContext(), "HookApplication 已启动", Toast.LENGTH_SHORT).show();
|
|
|
|
//Hook弹窗
|
|
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
|
showPopupLoop();
|
|
}, 3000);
|
|
|
|
//全屏欢迎弹窗
|
|
new Handler(Looper.getMainLooper()).postDelayed(() -> { // ✅ 全屏弹窗监听
|
|
showFullscreenLoop();
|
|
}, 3000);
|
|
|
|
//全屏广告弹窗
|
|
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
|
showImageFullscreenLoop(
|
|
"https://i11.hoopchina.com.cn/editor/3037dc8d3081ab92b16a80b36ef1b332_w_1242_h_1242_.png",
|
|
() -> Toast.makeText(getApplicationContext(), "你点击了图片", Toast.LENGTH_SHORT).show(),
|
|
5
|
|
);
|
|
}, 3000);
|
|
}
|
|
|
|
private void showPopupLoop() {
|
|
Handler handler = new Handler(Looper.getMainLooper());
|
|
|
|
Runnable popupTask = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (!showDialog) {
|
|
if (dialog != null && dialog.isShowing()) {
|
|
dialog.dismiss();
|
|
}
|
|
return;
|
|
}
|
|
|
|
Activity activity = getCurrentActivity();
|
|
|
|
if (activity == null) {
|
|
handler.postDelayed(this, 1000);
|
|
return;
|
|
}
|
|
|
|
boolean needShow = (dialog == null || !dialog.isShowing());
|
|
boolean activityChanged = currentActivityRef == null || currentActivityRef.get() != activity;
|
|
|
|
if (needShow || activityChanged) {
|
|
currentActivityRef = new WeakReference<>(activity);
|
|
dialog = new AlertDialog.Builder(activity)
|
|
.setTitle("Hook 弹窗")
|
|
.setMessage("当前 Activity: " + activity.getClass().getSimpleName())
|
|
.setCancelable(false)
|
|
.setPositiveButton("关闭弹窗", (d, w) -> {
|
|
if (dialog != null) {
|
|
showDialog = false;
|
|
dialog.dismiss();
|
|
}
|
|
})
|
|
.show();
|
|
}
|
|
|
|
handler.postDelayed(this, 1000);
|
|
}
|
|
};
|
|
|
|
handler.post(popupTask);
|
|
}
|
|
|
|
// ✅ 全屏弹窗监听器
|
|
private void showFullscreenLoop() {
|
|
Handler handler = new Handler(Looper.getMainLooper());
|
|
|
|
Runnable fullscreenTask = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (!showFullscreen) {
|
|
if (fullscreenDialog != null && fullscreenDialog.isShowing()) {
|
|
fullscreenDialog.dismiss();
|
|
}
|
|
return;
|
|
}
|
|
|
|
Activity activity = getCurrentActivity();
|
|
|
|
if (activity == null) {
|
|
handler.postDelayed(this, 1000);
|
|
return;
|
|
}
|
|
|
|
boolean needShow = (fullscreenDialog == null || !fullscreenDialog.isShowing());
|
|
boolean activityChanged = currentActivityRef == null || currentActivityRef.get() != activity;
|
|
|
|
if (needShow || activityChanged) {
|
|
currentActivityRef = new WeakReference<>(activity);
|
|
|
|
fullscreenDialog = new Dialog(activity, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
|
|
|
|
LinearLayout layout = new LinearLayout(activity);
|
|
layout.setOrientation(LinearLayout.VERTICAL);
|
|
layout.setBackgroundColor(Color.WHITE);
|
|
layout.setGravity(Gravity.CENTER);
|
|
layout.setLayoutParams(new LinearLayout.LayoutParams(
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
ViewGroup.LayoutParams.MATCH_PARENT
|
|
));
|
|
|
|
TextView title = new TextView(activity);
|
|
title.setText("欢迎使用菜鸟安卓弹窗注入器");
|
|
title.setTextSize(24);
|
|
title.setTextColor(Color.BLACK);
|
|
title.setGravity(Gravity.CENTER);
|
|
title.setPadding(0, 0, 0, 50);
|
|
layout.addView(title);
|
|
|
|
Button close = new Button(activity);
|
|
close.setText("进入");
|
|
layout.addView(close);
|
|
|
|
close.setOnClickListener(v -> {
|
|
showFullscreen = false;
|
|
if (fullscreenDialog != null) {
|
|
fullscreenDialog.dismiss();
|
|
}
|
|
});
|
|
|
|
fullscreenDialog.setContentView(layout);
|
|
fullscreenDialog.setCancelable(false);
|
|
fullscreenDialog.show();
|
|
}
|
|
|
|
handler.postDelayed(this, 1000);
|
|
}
|
|
};
|
|
|
|
handler.post(fullscreenTask);
|
|
}
|
|
private void showImageFullscreenLoop(String imageUrl, Runnable onImageClick, int countdownSeconds) {
|
|
Handler handler = new Handler(Looper.getMainLooper());
|
|
|
|
Runnable imageTask = new Runnable() {
|
|
int remaining = countdownSeconds;
|
|
|
|
@Override
|
|
public void run() {
|
|
if (!showImageFullscreen) {
|
|
if (imageDialog != null && imageDialog.isShowing()) {
|
|
imageDialog.dismiss();
|
|
}
|
|
return;
|
|
}
|
|
|
|
Activity activity = getCurrentActivity();
|
|
|
|
if (activity == null) {
|
|
handler.postDelayed(this, 1000);
|
|
return;
|
|
}
|
|
|
|
boolean needShow = (imageDialog == null || !imageDialog.isShowing());
|
|
boolean activityChanged = currentActivityRef == null || currentActivityRef.get() != activity;
|
|
|
|
if (needShow || activityChanged) {
|
|
currentActivityRef = new WeakReference<>(activity);
|
|
imageDialog = new Dialog(activity, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
|
|
|
|
// 主容器
|
|
FrameLayout rootLayout = new FrameLayout(activity);
|
|
rootLayout.setLayoutParams(new FrameLayout.LayoutParams(
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
ViewGroup.LayoutParams.MATCH_PARENT
|
|
));
|
|
|
|
// 图片控件
|
|
android.widget.ImageView imageView = new android.widget.ImageView(activity);
|
|
imageView.setScaleType(android.widget.ImageView.ScaleType.FIT_XY);
|
|
imageView.setLayoutParams(new FrameLayout.LayoutParams(
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
ViewGroup.LayoutParams.MATCH_PARENT
|
|
));
|
|
|
|
// 标签按钮
|
|
// 标签按钮(带圆角背景)
|
|
Button closeBtn = new Button(activity);
|
|
closeBtn.setText("倒计时 " + remaining + " 秒");
|
|
closeBtn.setTextColor(Color.WHITE);
|
|
closeBtn.setTextSize(14f);
|
|
closeBtn.setPadding(30, 10, 30, 10);
|
|
closeBtn.setEnabled(false);
|
|
|
|
// 创建圆角背景
|
|
android.graphics.drawable.GradientDrawable bg = new android.graphics.drawable.GradientDrawable();
|
|
bg.setColor(Color.parseColor("#AA000000")); // 半透明黑
|
|
bg.setCornerRadius(50); // 圆角
|
|
closeBtn.setBackground(bg);
|
|
|
|
|
|
// 圆角布局参数
|
|
FrameLayout.LayoutParams btnParams = new FrameLayout.LayoutParams(
|
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
);
|
|
btnParams.gravity = Gravity.TOP | Gravity.END;
|
|
btnParams.setMargins(30, 60, 30, 0);
|
|
closeBtn.setLayoutParams(btnParams);
|
|
closeBtn.setEnabled(false); // 初始不可点击
|
|
|
|
rootLayout.addView(imageView);
|
|
rootLayout.addView(closeBtn);
|
|
|
|
// 设置点击事件
|
|
imageView.setOnClickListener(v -> {
|
|
if (onImageClick != null) onImageClick.run();
|
|
});
|
|
|
|
closeBtn.setOnClickListener(v -> {
|
|
if (remaining <= 0) {
|
|
showImageFullscreen = false;
|
|
imageDialog.dismiss();
|
|
}
|
|
});
|
|
|
|
imageDialog.setContentView(rootLayout);
|
|
imageDialog.setCancelable(false);
|
|
imageDialog.show();
|
|
if (imageDialog.getWindow() != null) {
|
|
imageDialog.getWindow().setLayout(
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
ViewGroup.LayoutParams.MATCH_PARENT
|
|
);
|
|
imageDialog.getWindow().getDecorView().setSystemUiVisibility(
|
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
|
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
|
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
|
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
|
);
|
|
}
|
|
|
|
|
|
// 倒计时逻辑
|
|
Handler countdownHandler = new Handler(Looper.getMainLooper());
|
|
Runnable countdown = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (!showImageFullscreen || imageDialog == null || !imageDialog.isShowing()) {
|
|
return;
|
|
}
|
|
|
|
if (remaining > 0) {
|
|
closeBtn.setText("倒计时 " + remaining + " 秒");
|
|
remaining--;
|
|
countdownHandler.postDelayed(this, 1000);
|
|
} else {
|
|
closeBtn.setText("关闭");
|
|
closeBtn.setEnabled(true);
|
|
}
|
|
}
|
|
};
|
|
countdownHandler.post(countdown);
|
|
|
|
// 加载网络图片
|
|
new Thread(() -> {
|
|
try {
|
|
java.net.URL url = new java.net.URL(imageUrl);
|
|
java.io.InputStream input = url.openStream();
|
|
android.graphics.Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(input);
|
|
input.close();
|
|
|
|
new Handler(Looper.getMainLooper()).post(() -> {
|
|
imageView.setImageBitmap(bitmap);
|
|
});
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}).start();
|
|
}
|
|
|
|
handler.postDelayed(this, 1000);
|
|
}
|
|
};
|
|
|
|
handler.post(imageTask);
|
|
}
|
|
|
|
|
|
private Activity getCurrentActivity() {
|
|
try {
|
|
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
|
|
Method currentActivityThreadMethod = activityThreadClass.getMethod("currentActivityThread");
|
|
Object activityThread = currentActivityThreadMethod.invoke(null);
|
|
|
|
Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
|
|
activitiesField.setAccessible(true);
|
|
Map<?, ?> activities = (Map<?, ?>) activitiesField.get(activityThread);
|
|
|
|
for (Object record : activities.values()) {
|
|
Class<?> recordClass = record.getClass();
|
|
Field pausedField = recordClass.getDeclaredField("paused");
|
|
pausedField.setAccessible(true);
|
|
boolean paused = pausedField.getBoolean(record);
|
|
if (!paused) {
|
|
Field activityField = recordClass.getDeclaredField("activity");
|
|
activityField.setAccessible(true);
|
|
return (Activity) activityField.get(record);
|
|
}
|
|
}
|
|
} catch (Throwable e) {
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
}
|