Created
July 5, 2016 12:38
-
-
Save homanp/b50a3ac559d3ffa768c1c325dc0ff36a to your computer and use it in GitHub Desktop.
This file contains hidden or 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 com.bitcallproject.RNPlivo; | |
import com.bitcallproject.MainActivity; | |
import com.bitcallproject.RNPlivo.ServiceCallbacks; | |
import java.lang.Exception; | |
import java.lang.Error; | |
import java.util.Timer; | |
import java.util.TimerTask; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.HashMap; | |
import android.os.SystemClock; | |
import android.app.Service; | |
import android.os.IBinder; | |
import android.os.Binder; | |
import android.content.Intent; | |
import android.content.IntentFilter; | |
import android.content.ServiceConnection; | |
import android.content.ComponentName; | |
import android.content.BroadcastReceiver; | |
import android.content.Context; | |
import android.util.Log; | |
import android.view.Window; | |
import android.view.WindowManager; | |
import android.app.ActivityManager; | |
import android.app.ActivityManager.*; | |
import android.telephony.TelephonyManager; | |
import android.app.KeyguardManager; | |
import android.app.KeyguardManager.KeyguardLock; | |
import android.app.PendingIntent; | |
import android.app.AlarmManager; | |
import com.plivo.endpoint.Endpoint; | |
import com.plivo.endpoint.EventListener; | |
import com.plivo.endpoint.Incoming; | |
import com.plivo.endpoint.Outgoing; | |
import java.lang.*; | |
public class PlivoService extends Service implements EventListener{ | |
KeyguardLock keyguardLock; | |
private BroadcastReceiver receiver; | |
private boolean isAppBinded; | |
private Endpoint endpoint; | |
private Outgoing outCall; | |
private Incoming inCall; | |
public final static String PLIVO_PASSWORD = "sip_user"; | |
private ServiceCallbacks serviceCallbacks; | |
private String username; | |
private static final String ACTION_WAKEUP = "com.bitcallproject.WAKEUP"; | |
private static final String STATUS = "com.bitcallproject.STATUS"; | |
private static final String SLEEP = "com.bitcallproject.SLEEP"; | |
private static final String READY = "com.bitcallproject.READY"; | |
private static final String RELEASE_LOCK = "com.bitcallproject.RELEASE_LOCK"; | |
private static final String KEEP_ALIVE = "com.bitcallproject.KEEP_ALIVE"; | |
private static final String ACTION_LOGIN = "com.bitcallproject.ACTION_LOGIN"; | |
private static final String ACTION_INCOMING_CALL = "com.bitcallproject.ACTION_INCOMING_CALL"; | |
private static final String ACTION_BIND_APP = "com.bitcallproject.ACTION_BIND_APP"; | |
private static final String EVENT_SERVICE_STARTED = "com.bitcallproject.EVENT_SERVICE_STARTED"; | |
private static final String EVENT_END_CALL = "com.bitcallproject.EVENT_END_CALL"; | |
private static final String ACTION_REJECT_CALL = "com.bitcallproject.ACTION_REJECT_CALL"; | |
private static final String EVENT_REJECT_CALL = "com.bitcallproject.EVENT_REJECT_CALL"; | |
private static final String EVENT_HANG_UP = "com.bitcallproject.EVENT_HANG_UP"; | |
private static final String ACTION_HANG_UP = "com.bitcallproject.ACTION_HANG_UP"; | |
private Intent currIntent; | |
@Override | |
public int onStartCommand(Intent intent, int flags, int startId) { | |
currIntent = intent; | |
initService(); | |
username = intent.getStringExtra("username"); | |
Log.v("ReactNativeJS", "Starting service with username = " + username); | |
if (endpoint != null){ | |
Log.v("ReactNativeJS", "Resettimng endpoint"); | |
endpoint.resetEndpoint(); | |
endpoint = null; | |
endpoint = Endpoint.newInstance(true, this); | |
} | |
login(username); | |
return START_NOT_STICKY; | |
//return START_REDELIVER_INTENT; | |
} | |
@Override | |
public IBinder onBind(Intent intent) { | |
return null; | |
} | |
public void call(final String number, final String user, final String fromNumber){ | |
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); | |
String countryCode = tm.getNetworkCountryIso().toUpperCase(); | |
String formatedNumber = formatOutboundNumber(number, getCountryCode(countryCode)); | |
Log.v("ReactNativeJS", "Country code: " + getCountryCode(countryCode)); | |
Log.v("ReactNativeJS", "Formated number: " + formatedNumber); | |
Map extraArgs = new HashMap(); | |
extraArgs.put("X-PH-User", user); | |
extraArgs.put("X-PH-Number", fromNumber); | |
extraArgs.put("X-PH-RawNumber", number.replace("+", "")); | |
if (endpoint == null){ | |
Log.v("ReactNativeJS", "Endpoint is null"); | |
return; | |
} | |
outCall = new Outgoing(endpoint); | |
outCall = endpoint.createOutgoingCall(); | |
if (outCall == null){ | |
Log.v("ReactNativeJS", "Outgoing call is null"); | |
return; | |
} | |
outCall.callH(formatedNumber, extraArgs); | |
} | |
private void handleIncomingCall() { | |
Log.v("ReactNativeJS", "Handling incoming call!!!"); | |
broadcastEvent(KEEP_ALIVE); | |
int sipLen = "sip:".length(); | |
Intent payload = new Intent(); | |
payload.setAction(ACTION_INCOMING_CALL); | |
String fromContact = inCall.getFromSip(); | |
Map<String, String> header = inCall.getHeaderDict(); | |
HashMap<String, String> hashHeader = new HashMap<String, String>(header); | |
payload.putExtra("header", hashHeader); | |
payload.putExtra("fromContact", fromContact.substring(sipLen, fromContact.length())); | |
sendBroadcast(payload); | |
} | |
/*@Override | |
public void onCreate()*/public void initService(){ | |
//super.onCreate(); | |
IntentFilter filter = new IntentFilter(); | |
filter.addAction(READY); | |
filter.addAction(SLEEP); | |
filter.addAction(ACTION_LOGIN); | |
filter.addAction(ACTION_BIND_APP); | |
filter.addAction(ACTION_REJECT_CALL); | |
filter.addAction(ACTION_HANG_UP); | |
receiver = new BroadcastReceiver() { | |
@Override | |
public void onReceive(Context context, Intent intent) { | |
//set true to avoid start app, just wake up | |
Log.v("ReactNativeJS", "Service intent received: " + intent.getAction() + " incCall = " + Boolean.toString(inCall != null)); | |
if (intent.getAction().equals(ACTION_BIND_APP)) { | |
isAppBinded = true; | |
} else if (intent.getAction().equals(READY) && inCall != null) { | |
handleIncomingCall(); | |
} else if (intent.getAction().equals(SLEEP)) { | |
broadcastEvent(ACTION_WAKEUP); | |
//don't login if username from broadcast equals to username from startservice | |
} /*else if (intent.getAction().equals(ACTION_LOGIN)) { | |
String currUsername = intent.getStringExtra("username"); | |
if (username != currUsername) { | |
username = currUsername; | |
login(username); | |
} | |
} */else if (intent.getAction().equals(ACTION_REJECT_CALL)) { | |
reject(); | |
} else if (intent.getAction().equals(ACTION_HANG_UP)) { | |
hangup(); | |
} | |
} | |
}; | |
registerReceiver(receiver, filter); | |
broadcastEvent(EVENT_SERVICE_STARTED); | |
} | |
@Override | |
public void onDestroy(){ | |
if (receiver != null) { | |
unregisterReceiver(receiver); | |
receiver = null; | |
} | |
super.onDestroy(); | |
} | |
private void launchActivity() { | |
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE); | |
keyguardLock = keyguardManager.newKeyguardLock("TAG"); | |
keyguardLock.disableKeyguard(); | |
Intent intent = new Intent(this, MainActivity.class); | |
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
this.startActivity(intent); | |
} | |
public void login(final String username) { | |
if (endpoint == null) { | |
Log.v("ReactNativeJS", "Creating endpoint instance!!!"); | |
try { | |
endpoint = Endpoint.newInstance(true, this); | |
} | |
catch (Exception e) { | |
e.printStackTrace(); | |
Log.v("ReactNativeJS", "exception" + e.getMessage()); | |
} | |
} | |
Log.v("ReactNativeJS", "After reset before login"); | |
try { | |
endpoint.login(username, PLIVO_PASSWORD); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
Log.v("ReactNativeJS", "exception" + e.getMessage()); | |
} | |
} | |
public void reject(){ | |
inCall.reject(); | |
broadcastEvent(EVENT_REJECT_CALL); | |
} | |
public void hangup(){ | |
outCall.hangup(); | |
broadcastEvent(EVENT_HANG_UP); | |
} | |
public void onLogin(){ | |
Log.v("ReactNativeJS", "Logged in"); | |
broadcastEvent(RELEASE_LOCK); | |
} | |
public void onLogout() { | |
} | |
public void onLoginFailed() { | |
Log.v("ReactNativeJS", "Failed to login"); | |
} | |
@Override | |
public void onTaskRemoved(Intent rootIntent) { | |
super.onTaskRemoved(rootIntent); | |
endpoint.resetEndpoint(); | |
Log.v("ReactNativeJS", "Application has gone, and never return with rootusername = " + currIntent.getStringExtra("username")); | |
PendingIntent pintent = PendingIntent.getService(PlivoService.this, 0, currIntent, 0); | |
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE); | |
alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 6000, pintent); | |
} | |
public void onIncomingCall(Incoming incoming) { | |
Log.v("ReactNativeJS", "Incoming call has come. isAppBinded = " + Boolean.toString(isAppBinded)); | |
inCall = incoming; | |
if (isAppBinded == true){ | |
broadcastEvent(STATUS); | |
} else { | |
Log.v("ReactNativeJS", "Launching new activity"); | |
launchActivity(); | |
} | |
} | |
private void broadcastEvent(final String eventName){ | |
Intent i = new Intent(); | |
i.setAction(eventName); | |
sendBroadcast(i); | |
Log.v("ReactNativeJS", "Service intent sent: " + i.getAction()); | |
} | |
public void onIncomingCallHangup(Incoming incoming) { | |
broadcastEvent(EVENT_HANG_UP); | |
} | |
public void onIncomingCallRejected(Incoming incoming) { | |
broadcastEvent(EVENT_REJECT_CALL); | |
} | |
public void onOutgoingCall(Outgoing outgoing) { | |
broadcastEvent(KEEP_ALIVE); | |
} | |
public void onOutgoingCallAnswered(Outgoing outgoing) { | |
} | |
public void onOutgoingCallHangup(Outgoing outgoing) { | |
Log.v("ReactNativeJS", "Trigger onOutgoingCallHangup"); | |
broadcastEvent(RELEASE_LOCK); | |
} | |
public void onOutgoingCallRejected(Outgoing outgoing) { | |
Log.v("ReactNativeJS", "Trigger onOutgoingCallRejected"); | |
broadcastEvent(RELEASE_LOCK); | |
} | |
public void onOutgoingCallInvalid(Outgoing outgoing) { | |
Log.v("ReactNativeJS", "Trigger onOutgoingCallInvalid"); | |
broadcastEvent(RELEASE_LOCK); | |
} | |
private String getCountryCode(String countryCode){ | |
Map<String, String> countryCodes = new HashMap<String, String>() {{ | |
put("IL", "972"); put("AF", "93"); put("AL", "355"); put("DZ", "213"); put("AS", "1"); | |
put("AD", "376"); put("AO", "244"); put("AI", "1"); put("AG", "1"); put("AR", "54"); | |
put("AM", "374"); put("AW", "297"); put("AU", "61"); put("AT", "43"); put("AZ", "994"); | |
put("BS", "1"); put("BH", "973"); put("BD", "880"); put("BB", "1"); put("BY", "375"); | |
put("BE", "32"); put("BZ", "501"); put("BJ", "229"); put("BM", "1"); put("BT", "975"); | |
put("BA", "387"); put("BW", "267"); put("BR", "55"); put("IO", "246"); put("BG", "359"); | |
put("BF", "226"); put("BI", "257"); put("KH", "855"); put("CM", "237"); put("CA", "1"); | |
put("CV", "238"); put("KY", "345"); put("CF", "236"); put("TD", "235"); put("CL", "56"); | |
put("CN", "86"); put("CX", "61"); put("CO", "57"); put("KM", "269"); put("CG", "242"); | |
put("CK", "682"); put("CR", "506"); put("HR", "385"); put("CU", "53"); put("CY", "537"); | |
put("CZ", "420"); put("DK", "45"); put("DJ", "253"); put("DM", "1"); put("DO", "1"); | |
put("EC", "593"); put("EG", "20"); put("SV", "503"); put("GQ", "240"); put("ER", "291"); | |
put("EE", "372"); put("ET", "251"); put("FO", "298"); put("FJ", "679"); put("FI", "358"); | |
put("FR", "33"); put("GF", "594"); put("PF", "689"); put("GA", "241"); put("GM", "220"); | |
put("GE", "995"); put("DE", "49"); put("GH", "233"); put("GI", "350"); put("GR", "30"); | |
put("GL", "299"); put("GD", "1"); put("GP", "590"); put("GU", "1"); put("GT", "502"); | |
put("GN", "224"); put("GW", "245"); put("GY", "595"); put("HT", "509"); put("HN", "504"); | |
put("HU", "36"); put("IS", "354"); put("IN", "91"); put("ID", "62"); put("IQ", "964"); | |
put("IE", "353"); put("IL", "972"); put("IT", "39"); put("JM", "1"); put("JP", "81"); | |
put("JO", "962"); put("KZ", "77"); put("KE", "254"); put("KI", "686"); put("KW", "965"); | |
put("KG", "996"); put("LV", "371"); put("LB", "961"); put("LS", "266"); put("LR", "231"); | |
put("LI", "423"); put("LT", "370"); put("LU", "352"); put("MG", "261"); put("MW", "265"); | |
put("MY", "60"); put("MV", "960"); put("ML", "223"); put("MT", "356"); put("MH", "692"); | |
put("MQ", "596"); put("MR", "222"); put("MU", "230"); put("YT", "262"); put("MX", "52"); | |
put("MC", "377"); put("MN", "976"); put("ME", "382"); put("MS", "1"); put("MA", "212"); | |
put("MM", "95"); put("NA", "264"); put("NR", "674"); put("NP", "977"); put("NL", "31"); | |
put("AN", "599"); put("NC", "687"); put("NZ", "64"); put("NI", "505"); put("NE", "227"); | |
put("NG", "234"); put("NU", "683"); put("NF", "672"); put("MP", "1"); put("NO", "47"); | |
put("OM", "968"); put("PK", "92"); put("PW", "680"); put("PA", "507"); put("PG", "675"); | |
put("PY", "595"); put("PE", "51"); put("PH", "63"); put("PL", "48"); put("PT", "351"); | |
put("PR", "1"); put("QA", "974"); put("RO", "40"); put("RW", "250"); put("WS", "685"); | |
put("SM", "378"); put("SA", "966"); put("SN", "221"); put("RS", "381"); put("SC", "248"); | |
put("SL", "232"); put("SG", "65"); put("SK", "421"); put("SI", "386"); put("SB", "677"); | |
put("ZA", "27"); put("GS", "500"); put("ES", "34"); put("LK", "94"); put("SD", "249"); | |
put("SR", "597"); put("SZ", "268"); put("SE", "46"); put("CH", "41"); put("TJ", "992"); | |
put("TH", "66"); put("TG", "228"); put("TK", "690"); put("TO", "676"); put("TT", "1"); | |
put("TN", "216"); put("TR", "90"); put("TM", "993"); put("TC", "1"); put("TV", "688"); | |
put("UG", "256"); put("UA", "380"); put("AE", "971"); put("GB", "44"); put("US", "1"); | |
put("UY", "598"); put("UZ", "998"); put("VU", "678"); put("WF", "681"); put("YE", "967"); | |
put("ZM", "260"); put("ZW", "263"); put("BO", "591"); put("BN", "673"); put("CC", "61"); | |
put("CD", "243"); put("CI", "225"); put("FK", "500"); put("GG", "44"); put("VA", "379"); | |
put("HK", "852"); put("IR", "98"); put("IM", "44"); put("JE", "44"); put("KP", "850"); | |
put("KR", "82"); put("LA", "856"); put("LY", "218"); put("MO", "853"); put("MK", "389"); | |
put("FM", "691"); put("MD", "373"); put("MZ", "258"); put("PS", "970"); put("PN", "872"); | |
put("RE", "262"); put("RU", "7"); put("BL", "590"); put("SH", "290"); put("KN", "1"); | |
put("LC", "1"); put("MF", "590"); put("PM", "508"); put("VC", "1"); put("ST", "239"); | |
put("SO", "252"); put("SJ", "47"); put("SY", "963"); put("TW", "886"); put("TZ", "255"); | |
put("TL", "670"); put("VE", "58"); put("VN", "84"); put("VG", "1"); put("VI", "1"); | |
}}; | |
return countryCodes.get(countryCode); | |
} | |
private String formatOutboundNumber(String number, String countryCode){ | |
String cleanNumber = number.replaceAll("[^A-Za-z0-9]", ""); | |
int len = cleanNumber.length(); | |
if (cleanNumber.startsWith("00")){ | |
return "+" + countryCode + cleanNumber.substring(2, len); | |
} | |
if (cleanNumber.startsWith("0")){ | |
return "+" + countryCode + cleanNumber.substring(1, len); | |
} | |
return "+" + cleanNumber; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment