Skip to content

Instantly share code, notes, and snippets.

@alexesDev
Created July 15, 2019 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexesDev/807b1deb49e3399e78e2b56f2e822075 to your computer and use it in GitHub Desktop.
Save alexesDev/807b1deb49e3399e78e2b56f2e822075 to your computer and use it in GitHub Desktop.
package myfresh.freshcaller;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.IBinder;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.URISyntaxException;
import java.util.Date;
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
public class AutoCallService extends Service {
private Socket mSocket;
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber;
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
}
else{
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)){
state = TelephonyManager.CALL_STATE_IDLE;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
state = TelephonyManager.CALL_STATE_OFFHOOK;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){
state = TelephonyManager.CALL_STATE_RINGING;
}
onCallStateChanged(context, intent, state, number);
}
}
private void trackEvent(Context ctx, JSONObject data) {
mSocket.emit("phone", data);
}
private void trackEvent(Context ctx, String eventName, String number) {
JSONObject data = new JSONObject();
try {
data.put("number", number);
data.put("name", eventName);
} catch (JSONException e) {
return;
}
trackEvent(ctx, data);
}
public void onCallStateChanged(Context context, Intent intent, int state, String number) {
if (lastState == state) {
//No change, debounce extras
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
trackEvent(context, "onIncomingCallStarted", savedNumber);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//Transition of ringing->offhook are pickups of incoming calls. Nothing done on them
if (lastState != TelephonyManager.CALL_STATE_RINGING) {
isIncoming = false;
callStartTime = new Date();
trackEvent(context, "onOutgoingCallStarted", savedNumber);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
//Went to idle- this is the end of a call. What type depends on previous state(s)
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
//Ring but no pickup- a mis
trackEvent(context, "onMissedCall", number);
} else if (isIncoming) {
JSONObject data = new JSONObject();
try {
data.put("name", "onIncomingCallEnded");
data.put("number", savedNumber);
data.put("duration", ((new Date()).getTime() - callStartTime.getTime()) / 1000);
} catch(JSONException e) {
return;
}
trackEvent(context, data);
} else {
JSONObject data = new JSONObject();
try {
data.put("name", "onIncomingCallEnded");
data.put("number", savedNumber);
data.put("duration", ((new Date()).getTime() - callStartTime.getTime()) / 1000);
} catch (JSONException e) {
return;
}
trackEvent(context, data);
}
break;
}
lastState = state;
}
};
private Emitter.Listener onConnect = new Emitter.Listener() {
@Override
public void call(Object... args) {
SharedPreferences prefs = getSharedPreferences("freshcaller", Context.MODE_PRIVATE);
String token = prefs.getString("token", "");
JSONObject data = new JSONObject();
try {
data.put("token", token);
data.put("device", "phone");
} catch (JSONException e) {
return;
}
mSocket.emit("identify", data);
}
};
private Emitter.Listener onDisconnect = new Emitter.Listener() {
@Override
public void call(Object... args) {
mSocket.connect();
}
};
public AutoCallService() {
IO.Options opts = new IO.Options();
opts.forceNew = true;
opts.reconnection = true;
try {
mSocket = IO.socket("http://freshdev.ru:4050", opts);
} catch (URISyntaxException e) {
return;
}
mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
SharedPreferences prefs = getSharedPreferences("freshcaller", Context.MODE_PRIVATE);
String token = prefs.getString("token", "");
JSONObject data = new JSONObject();
try {
data.put("token", token);
data.put("device", "phone");
} catch (JSONException e) {
return;
}
mSocket.emit("identify", data);
}
}).on("call", new Emitter.Listener() {
@Override
public void call(Object... args) {
JSONObject data = (JSONObject) args[0];
try {
String number = data.getString("number");
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + number));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (JSONException e) {
return;
}
}
}).on("open", new Emitter.Listener() {
@Override
public void call(Object... args) {
JSONObject data = (JSONObject) args[0];
try {
String url = data.getString("url");
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (JSONException e) {
return;
}
}
});
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
if (mSocket.connected()) {
mSocket.disconnect();
}
mSocket.connect();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, filter);
}
@Override
public void onDestroy() {
mSocket.disconnect();
unregisterReceiver(receiver);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onTaskRemoved(Intent rootIntent) {
//create a intent that you want to start again..
Intent intent = new Intent(getApplicationContext(), AutoCallService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 1, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + 5000, pendingIntent);
super.onTaskRemoved(rootIntent);
}
}
package myfresh.freshcaller;
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
public class MainActivity extends Activity {
@Override
protected void onStart() {
super.onStart();
if (getIntent().getExtras() != null) {
Uri data = getIntent().getData();
if (data != null) {
String scheme = data.getScheme();
if (!TextUtils.isEmpty(scheme) && scheme.equals("freshcaller")) {
List<String> params = data.getPathSegments();
String type = data.getHost();
if (type.equals("token") && !params.isEmpty()) {
saveToken(params.get(0));
}
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences prefs = getSharedPreferences("freshcaller", MODE_PRIVATE);
String token = prefs.getString("token", "0");
int currentId = Integer.parseInt(token, 10);
RadioGroup group = new RadioGroup(this);
group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
saveToken(Integer.toString(i));
}
});
RadioButton but1 = new RadioButton(this);
but1.setText("Анна Кондрашина");
but1.setId(29);
RadioButton but2 = new RadioButton(this);
but2.setText("Александра Бабкина");
but2.setId(282);
RadioButton but3 = new RadioButton(this);
but3.setText("Ксения Комлева");
but3.setId(138);
RadioButton but4 = new RadioButton(this);
but4.setText("Анастасия Князьковa");
but4.setId(279);
RadioButton but5 = new RadioButton(this);
but5.setText("Алена Желдак");
but5.setId(201);
RadioButton but6 = new RadioButton(this);
but6.setText("Тестовый");
but6.setId(25);
group.addView(but1);
group.addView(but2);
group.addView(but3);
group.addView(but4);
group.addView(but5);
group.addView(but6);
group.check(currentId);
Button restartBut = new Button(this);
restartBut.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View view) {
restart();
}
});
restartBut.setText("Перезапустить службу");
Button disableMobileDataButton = new Button(this);
disableMobileDataButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View view) {
try {
setMobileDataEnabled(getApplicationContext(), false);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
});
disableMobileDataButton.setText("Отключить мобильный интернет");
LinearLayout linLayout = new LinearLayout(this);
linLayout.setPadding(20, 20, 20, 20);
linLayout.setDividerPadding(20);
linLayout.addView(group);
linLayout.addView(restartBut);
linLayout.addView(disableMobileDataButton);
linLayout.setOrientation(LinearLayout.VERTICAL);
LayoutParams linLayoutParam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
setContentView(linLayout, linLayoutParam);
restart();
}
private void restart() {
stopService(new Intent(this, AutoCallService.class));
startService(new Intent(this, AutoCallService.class));
}
private void saveToken(String token) {
SharedPreferences prefs = getSharedPreferences("freshcaller", MODE_PRIVATE);
Editor ed = prefs.edit();
ed.putString("token", token);
ed.apply();
}
private void setMobileDataEnabled(Context context, boolean enabled) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, NoSuchFieldException {
final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final Class conmanClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
}
}%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment