-
-
Save alexesDev/807b1deb49e3399e78e2b56f2e822075 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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