需要准备的材料:
1.liphone4android-master代码,此代码已经编译过,可直接运行到手机上
需要的伙伴可以自行下载:
https://github.com/treasure-lau/Linphone4Android
2.linphone-3.11.1,此代码为linphone底层源码,在linphone官网下载即可
这里项目代码和C源码并不是用一个版本,项目为3.10.2版本的源码。
配置和服务器,我就不多说了
本公司曾经外包给别人过一套sip消息外加编解码的底层项目给别人,长期的代码维护和沟通上的问题不停出现,公司终于决定,抛弃原始底层,改用linphone的底层来实现网络视频电话。于是,这个光荣而又极其需要头发的任务,就落在了公司本人身上。
第一次运行源码,百度了不少,终于找到了在藏在LinphoneService,java文件下的callState回调,在此回调中,可及时的获取呼叫的状态。
/*
LinphoneService.java
Copyright (C) 2010 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.linphone;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.view.WindowManager;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCallLog.CallStatus;
import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCore.GlobalState;
import org.linphone.core.LinphoneCore.RegistrationState;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreFactoryImpl;
import org.linphone.core.LinphoneCoreListenerBase;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.core.PayloadType;
import org.linphone.mediastream.Log;
import org.linphone.mediastream.Version;
import org.linphone.ui.LinphoneOverlay;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
/**
*
* Linphone service, reacting to Incoming calls, ...<br />
*
* Roles include:<ul>
* <li>Initializing LinphoneManager</li>
* <li>Starting C libLinphone through LinphoneManager</li>
* <li>Reacting to LinphoneManager state changes</li>
* <li>Delegating GUI state change actions to GUI listener</li>
*
*
* @author Guillaume Beraudo
*
*/
public final class LinphoneService extends Service {
/* Listener needs to be implemented in the Service as it calls
* setLatestEventInfo and startActivity() which needs a context.
*/
public static final String START_LINPHONE_LOGS = " ==== Phone information dump ====";
public static final int IC_LEVEL_ORANGE=0;
/*private static final int IC_LEVEL_GREEN=1;
private static final int IC_LEVEL_RED=2;*/
//public static final int IC_LEVEL_OFFLINE=3;
private static LinphoneService instance;
private final static int NOTIF_ID=1;
private final static int INCALL_NOTIF_ID=2;
private final static int MESSAGE_NOTIF_ID=3;
private final static int CUSTOM_NOTIF_ID=4;
private final static int MISSED_NOTIF_ID=5;
/**
* 返回服务是否准备好
* @return
*/
public static boolean isReady() {
return instance != null && instance.mTestDelayElapsed;
}
/**
* 返回linphone服务的对象,若还未创建,则抛出异常
* @throws RuntimeException service not instantiated
*/
public static LinphoneService instance() {
if (isReady()) return instance;
throw new RuntimeException("LinphoneService not instantiated yet");
}
public Handler mHandler = new Handler();
// private boolean mTestDelayElapsed; // add a timer for testing
/**
* 测试延长时间,不设置
*/
private boolean mTestDelayElapsed = true; // no timer
/**
* 通知栏管理器
*/
private NotificationManager mNM;
private Notification mNotif;
private Notification mIncallNotif;
private Notification mMsgNotif;
private Notification mCustomNotif;
private int mMsgNotifCount;
private PendingIntent mNotifContentIntent, mMissedCallsNotifContentIntent;
private String mNotificationTitle;
private boolean mDisableRegistrationStatus;
/**
* linphone 底层回调接口,监听电话呼叫状态的改变
*/
private LinphoneCoreListenerBase mListener;
public static int notifcationsPriority = (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41) ? Notification.PRIORITY_MIN : 0);
private WindowManager mWindowManager;
private LinphoneOverlay mOverlay;
private Application.ActivityLifecycleCallbacks activityCallbacks;
/*Believe me or not, but knowing the application visibility state on Android is a nightmare.
After two days of hard work I ended with the following class, that does the job more or less reliabily.
*/
/**
* linphone码农吐槽部分,监听界面的可见情况
*/
class ActivityMonitor implements Application.ActivityLifecycleCallbacks {
private ArrayList<Activity> activities = new ArrayList<Activity>();
private boolean mActive = false;
private int mRunningActivities = 0;
class InactivityChecker implements Runnable {
private boolean isCanceled;
public void cancel() {
isCanceled = true;
}
@Override
public void run() {
synchronized(LinphoneService.this) {
if (!isCanceled) {
if (ActivityMonitor.this.mRunningActivities == 0 && mActive) {
mActive = false;
LinphoneService.this.onBackgroundMode();
}
}
}
}
};
private InactivityChecker mLastChecker;
@Override
public synchronized void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.i("Activity created:" + activity);
if (!activities.contains(activity))
activities.add(activity);
}
@Override
public void onActivityStarted(Activity activity) {
Log.i("Activity started:" + activity);
}
@Override
public synchronized void onActivityResumed(Activity activity) {
Log.i("Activity resumed:" + activity);
if (activities.contains(activity)) {
mRunningActivities++;
Log.i("runningActivities=" + mRunningActivities);
checkActivity();
}
}
@Override
public synchronized void onActivityPaused(Activity activity) {
Log.i("Activity paused:" + activity);
if (activities.contains(activity)) {
mRunningActivities--;
Log.i("runningActivities=" + mRunningActivities);
checkActivity();
}
}
@Override
public void onActivityStopped(Activity activity) {
Log.i("Activity stopped:" + activity);
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public synchronized void onActivityDestroyed(Activity activity) {
Log.i("Activity destroyed:" + activity);
if (activities.contains(activity)) {
activities.remove(activity);
}
}
void startInactivityChecker() {
if (mLastChecker != null) mLastChecker.cancel();
LinphoneService.this.mHandler.postDelayed(
(mLastChecker = new InactivityChecker()), 2000);
}
void checkActivity() {
if (mRunningActivities == 0) {
if (mActive) startInactivityChecker();
} else if (mRunningActivities > 0) {
if (!mActive) {
mActive = true;
LinphoneService.this.onForegroundMode();
}
if (mLastChecker != null) {
mLastChecker.cancel();
mLastChecker = null;
}
}
}
}
/**
* 进入后台模式
*/
protected void onBackgroundMode(){
Log.i("App has entered background mode");
if (LinphonePreferences.instance() != null && LinphonePreferences.instance().isFriendlistsubscriptionEnabled()) {
if (LinphoneManager.isInstanciated())
LinphoneManager.getInstance().subscribeFriendList(false);
}
}
/**
* 前台模式
*/
protected void onForegroundMode() {
Log.i("App has left background mode");
}
private void setupActivityMonitor(){
if (activityCallbacks != null) return;
getApplication().registerActivityLifecycleCallbacks(activityCallbacks = new ActivityMonitor());
}
public int getMessageNotifCount() {
return mMsgNotifCount;
}
public void resetMessageNotifCount() {
mMsgNotifCount = 0;
}
private boolean displayServiceNotification() {
return LinphonePreferences.instance().getServiceNotificationVisibility();
}
public void showServiceNotification() {
startForegroundCompat(NOTIF_ID, mNotif);
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (lc == null) return;
LinphoneProxyConfig lpc = lc.getDefaultProxyConfig();
if (lpc != null) {
if (lpc.isRegistered()) {
sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
} else {
sendNotification(IC_LEVEL_ORANGE, R.string.notification_register_failure);
}
} else {
sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
}
}
public void hideServiceNotification() {
stopForegroundCompat(NOTIF_ID);
}
@SuppressWarnings("unchecked")
@Override
public void onCreate() {
super.onCreate();
setupActivityMonitor();
// In case restart after a crash. Main in LinphoneActivity
mNotificationTitle = getString(R.string.service_name);
// Needed in order for the two next calls to succeed, libraries must have been loaded first
/*下面两个调用成功,必须先加载库*/
LinphonePreferences.instance().setContext(getBaseContext());
LinphoneCoreFactory.instance().setLogCollectionPath(getFilesDir().getAbsolutePath());
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled);
LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, getString(R.string.app_name));
// Dump some debugging information to the logs
Log.i(START_LINPHONE_LOGS);
dumpDeviceInformation();
dumpInstalledLinphoneInformation();
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
/*解决在崩溃的情况下,图标不会删除的情况*/
mNM.cancel(INCALL_NOTIF_ID); // in case of crash the icon is not removed
Intent notifIntent = new Intent(this, incomingReceivedActivity);
notifIntent.putExtra("Notification", true);
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent missedCallNotifIntent = new Intent(this, incomingReceivedActivity);
missedCallNotifIntent.putExtra("GoToHistory", true);
mMissedCallsNotifContentIntent = PendingIntent.getActivity(this, 0, missedCallNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap bm = null;
try {
bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
} catch (Exception e) {
}
mNotif = Compatibility.createNotification(this, mNotificationTitle, "", R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, mNotifContentIntent, true,notifcationsPriority);
LinphoneManager.createAndStart(LinphoneService.this);
instance = this; // instance is ready once linphone manager has been created
incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived();
try {
incomingReceivedActivity = (Class<? extends Activity>) Class.forName(incomingReceivedActivityName);
} catch (ClassNotFoundException e) {
Log.e(e);
}
LinphoneManager.getLc().addListener(mListener = new LinphoneCoreListenerBase() {
@Override
public void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State state, String message) {
String TAG = "LinphoneService";
android.util.Log.e(TAG,"LinphoneCall.State--state:"+state);
android.util.Log.e(TAG,"message:"+message);
android.util.Log.e(TAG,"MaxCalls:"+lc.getMaxCalls());
android.util.Log.e(TAG,"--------------------------------------------------------------");
for (final PayloadType pt : lc.getAudioCodecs()) {
android.util.Log.e(TAG,"LinphoneCore-"+pt.getMime()+"-Rate-"+pt.getRate()+"-open:"+lc.isPayloadTypeEnabled(pt));
}
android.util.Log.e(TAG,"--------------------------------------------------------------");
android.util.Log.e(TAG,"LinphoneCore--AudioDirection:"+lc.getCurrentCall().getCurrentParamsCopy().getAudioDirection());
android.util.Log.e(TAG,"LinphoneCore--VideoDirection:"+lc.getCurrentCall().getCurrentParamsCopy().getVideoDirection());
android.util.Log.e(TAG,"--------------------------------------------------------------");
android.util.Log.e(TAG,"LinphoneCall--AuthenticationToken:"+call.getAuthenticationToken());
android.util.Log.e(TAG,"LinphoneCall--RemoteContact:"+call.getRemoteContact());
android.util.Log.e(TAG,"LinphoneCall--RemoteUserAgent:"+call.getRemoteUserAgent());
android.util.Log.e(TAG,"LinphoneCall--AudioStats:"+call.getAudioStats());
if (call.getAudioStats()!=null) {
android.util.Log.e(TAG, "LinphoneCall--AudioStats--MediaType:" + call.getAudioStats().getMediaType());
android.util.Log.e(TAG, "LinphoneCall--AudioStats--IceState:" + call.getAudioStats().getIceState());
}
android.util.Log.e(TAG,"LinphoneCall--VideoStats:"+call.getVideoStats());
if (call.getVideoStats()!=null) {
android.util.Log.e(TAG,"LinphoneCall--VideoStats--MediaType:"+call.getVideoStats().getMediaType());
android.util.Log.e(TAG,"LinphoneCall--VideoStats--IceState:"+call.getVideoStats().getIceState());
}
android.util.Log.e(TAG,"LinphoneCall--AverageQuality:"+call.getAverageQuality());
android.util.Log.e(TAG,"--------------------------------------------------------------");
android.util.Log.e(TAG, "LinphoneCall--CallLog:" + call.getCallLog());
if (call.getCallLog()!= null) {
android.util.Log.e(TAG, "LinphoneCall--CallLog--CallId:" + call.getCallLog().getCallId());
android.util.Log.e(TAG, "LinphoneCall--CallLog--StartDate:" + call.getCallLog().getStartDate());
android.util.Log.e(TAG, "LinphoneCall--CallLog--Timestamp:" + call.getCallLog().getTimestamp());
android.util.Log.e(TAG, "LinphoneCall--CallLog--CallDuration():" + call.getCallLog().getCallDuration());
android.util.Log.e(TAG, "LinphoneCall--CallLog--Direction:" + call.getCallLog().getDirection());
android.util.Log.e(TAG, "LinphoneCall--CallLog--From--DisplayName:" + call.getCallLog().getFrom().getDisplayName());
android.util.Log.e(TAG, "LinphoneCall--CallLog--From--Domain:" + call.getCallLog().getFrom().getDomain());
android.util.Log.e(TAG, "LinphoneCall--CallLog--From--UserName:" + call.getCallLog().getFrom().getUserName());
android.util.Log.e(TAG, "LinphoneCall--CallLog--From--Port:" + call.getCallLog().getFrom().getPort());
android.util.Log.e(TAG, "LinphoneCall--CallLog--From--Transport:" + call.getCallLog().getFrom().getTransport());
android.util.Log.e(TAG, "LinphoneCall--CallLog--To--DisplayName:" + call.getCallLog().getTo().getDisplayName());
android.util.Log.e(TAG, "LinphoneCall--CallLog--To--Domain:" + call.getCallLog().getTo().getDomain());
android.util.Log.e(TAG, "LinphoneCall--CallLog--To--UserName:" + call.getCallLog().getTo().getUserName());
android.util.Log.e(TAG, "LinphoneCall--CallLog--To--Port:" + call.getCallLog().getTo().getPort());
android.util.Log.e(TAG, "LinphoneCall--CallLog--To--Transport:" + call.getCallLog().getTo().getTransport());
android.util.Log.e(TAG, "LinphoneCall--CallLog--Status:" + call.getCallLog().getStatus());
android.util.Log.e(TAG, "--------------------------------------------------------------");
}
android.util.Log.e(TAG, "LinphoneCall--ChatRoom:" + call.getChatRoom());
if (call.getChatRoom()!= null) {
android.util.Log.e(TAG, "LinphoneCall--ChatRoom--PeerAddress--DisplayName:" + call.getChatRoom().getPeerAddress()
.getDisplayName());
android.util.Log.e(TAG, "LinphoneCall--ChatRoom--PeerAddress--Domain:" + call.getChatRoom().getPeerAddress().getDomain());
android.util.Log.e(TAG, "LinphoneCall--ChatRoom--PeerAddress--UserName:" + call.getChatRoom().getPeerAddress().getUserName());
android.util.Log.e(TAG, "LinphoneCall--ChatRoom--PeerAddress--Port:" + call.getChatRoom().getPeerAddress().getPort());
android.util.Log.e(TAG, "LinphoneCall--ChatRoom--PeerAddress--Transport:" + call.getChatRoom().getPeerAddress().getTransport());
android.util.Log.e(TAG, "--------------------------------------------------------------");
}
android.util.Log.e(TAG, "LinphoneCall--Conference:" + call.getConference());
if (call.getConference()!= null) {
android.util.Log.e(TAG, "LinphoneCall--Conference--Participants:" + call.getConference().getParticipants().length);
}
android.util.Log.e(TAG,"LinphoneCall--CurrentQuality:"+call.getCurrentQuality());
android.util.Log.e(TAG,"LinphoneCall--Direction:"+call.getDirection());
android.util.Log.e(TAG,"--------------------------------------------------------------");
android.util.Log.e(TAG, "LinphoneCall--DiversionAddress:" + call.getDiversionAddress());
if (call.getDiversionAddress()!= null) {
android.util.Log.e(TAG, "LinphoneCall--DiversionAddress--DisplayName:" + call.getDiversionAddress().getDisplayName());
android.util.Log.e(TAG, "LinphoneCall--DiversionAddress--Domain:" + call.getDiversionAddress().getDomain());
android.util.Log.e(TAG, "LinphoneCall--DiversionAddress--UserName:" + call.getDiversionAddress().getUserName());
android.util.Log.e(TAG, "LinphoneCall--DiversionAddress--Port:" + call.getDiversionAddress().getPort());
android.util.Log.e(TAG, "LinphoneCall--DiversionAddress--Transport:" + call.getDiversionAddress().getTransport());
android.util.Log.e(TAG, "--------------------------------------------------------------");
}
if (call.getErrorInfo()!= null) {
android.util.Log.e(TAG, "LinphoneCall--ErrorInfo--Details:" + call.getErrorInfo().getDetails());
android.util.Log.e(TAG, "LinphoneCall--ErrorInfo--Phrase:" + call.getErrorInfo().getPhrase());
android.util.Log.e(TAG, "LinphoneCall--ErrorInfo--ProtocolCode:" + call.getErrorInfo().getProtocolCode());
android.util.Log.e(TAG, "LinphoneCall--ErrorInfo--Reason:" + call.getErrorInfo().getReason());
android.util.Log.e(TAG, "--------------------------------------------------------------");
}
android.util.Log.e(TAG,"LinphoneCall--Player--State:"+call.getPlayer().getState());
android.util.Log.e(TAG,"LinphoneCall--PlayVolume:"+call.getPlayVolume());
android.util.Log.e(TAG,"LinphoneCall--Reason:"+call.getReason());
android.util.Log.e(TAG,"--------------------------------------------------------------");
android.util.Log.e(TAG,"LinphoneCall--RemoteAddress:"+call.getRemoteAddress());
if (call.getRemoteAddress() != null) {
android.util.Log.e(TAG, "LinphoneCall--RemoteAddress--DisplayName:" + call.getRemoteAddress().getDisplayName());
android.util.Log.e(TAG, "LinphoneCall--RemoteAddress--Domain:" + call.getRemoteAddress().getDomain());
android.util.Log.e(TAG, "LinphoneCall--RemoteAddress--UserName:" + call.getRemoteAddress().getUserName());
android.util.Log.e(TAG, "LinphoneCall--RemoteAddress--Port:" + call.getRemoteAddress().getPort());
android.util.Log.e(TAG, "LinphoneCall--RemoteAddress--Transport:" + call.getRemoteAddress().getTransport());
android.util.Log.e(TAG, "--------------------------------------------------------------");
}
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--AudioDirection:"+call.getCurrentParamsCopy().getAudioDirection());
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--UsedAudioCodec:"+call.getCurrentParamsCopy().getUsedAudioCodec());
if (call.getCurrentParamsCopy().getUsedAudioCodec() != null) {
android.util.Log.e(TAG, "LinphoneCall--CurrentParamsCopy--UsedAudioCodec.Rate:" + call.getCurrentParamsCopy().getUsedAudioCodec
().getRate());
android.util.Log.e(TAG, "LinphoneCall--CurrentParamsCopy--UsedAudioCodec.Mime:" + call.getCurrentParamsCopy().getUsedAudioCodec
().getMime());
android.util.Log.e(TAG, "LinphoneCall--CurrentParamsCopy--UsedAudioCodec.RecvFmtp:" + call.getCurrentParamsCopy().getUsedAudioCodec
().getRecvFmtp());
android.util.Log.e(TAG, "LinphoneCall--CurrentParamsCopy--UsedAudioCodec.SendFmtp:" + call.getCurrentParamsCopy().getUsedAudioCodec
().getSendFmtp());
}
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy:"+call.getCurrentParamsCopy());
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--VideoDirection:"+call.getCurrentParamsCopy().getVideoDirection());
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--VideoEnabled:"+call.getCurrentParamsCopy().getVideoEnabled());
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--UsedVideoCodec:"+call.getCurrentParamsCopy().getUsedVideoCodec());
if (call.getCurrentParamsCopy().getUsedVideoCodec() != null) {
android.util.Log.e(TAG, "LinphoneCall--CurrentParamsCopy--UsedAudioCodec.Rate:" + call.getCurrentParamsCopy().getUsedVideoCodec
().getRate());
android.util.Log.e(TAG, "LinphoneCall--CurrentParamsCopy--UsedAudioCodec.Mime:" + call.getCurrentParamsCopy().getUsedVideoCodec
().getMime());
android.util.Log.e(TAG, "LinphoneCall--CurrentParamsCopy--UsedAudioCodec.RecvFmtp:" + call.getCurrentParamsCopy().getUsedVideoCodec
().getRecvFmtp());
android.util.Log.e(TAG, "LinphoneCall--CurrentParamsCopy--UsedAudioCodec.SendFmtp:" + call.getCurrentParamsCopy().getUsedVideoCodec
().getSendFmtp());
}
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--SessionName:"+call.getCurrentParamsCopy().getSessionName());
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--ReceivedVideoSize:"+call.getCurrentParamsCopy().getReceivedVideoSize());
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--SentVideoSize:"+call.getCurrentParamsCopy().getSentVideoSize());
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--MediaEncryption:"+call.getCurrentParamsCopy().getMediaEncryption());
android.util.Log.e(TAG,"LinphoneCall--CurrentParamsCopy--Privacy:"+call.getCurrentParamsCopy().getPrivacy());
android.util.Log.e(TAG, "--------------------------------------------------------------");
android.util.Log.e(TAG,"LinphoneCall--RemoteParams:"+call.getRemoteParams());
if (call.getRemoteParams() != null) {
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--AudioDirection:"+call.getRemoteParams().getAudioDirection());
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--UsedAudioCodec:"+call.getRemoteParams().getUsedAudioCodec());
if (call.getRemoteParams().getUsedAudioCodec() != null) {
android.util.Log.e(TAG, "LinphoneCall--RemoteParams--UsedAudioCodec.Rate:" + call.getRemoteParams().getUsedAudioCodec
().getRate());
android.util.Log.e(TAG, "LinphoneCall--RemoteParams--UsedAudioCodec.Mime:" + call.getRemoteParams().getUsedAudioCodec
().getMime());
android.util.Log.e(TAG, "LinphoneCall--RemoteParams--UsedAudioCodec.RecvFmtp:" + call.getRemoteParams().getUsedAudioCodec
().getRecvFmtp());
android.util.Log.e(TAG, "LinphoneCall--RemoteParams--UsedAudioCodec.SendFmtp:" + call.getRemoteParams().getUsedAudioCodec
().getSendFmtp());
}
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--VideoDirection:"+call.getRemoteParams().getVideoDirection());
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--VideoEnabled:"+call.getRemoteParams().getVideoEnabled());
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--UsedVideoCodec:"+call.getRemoteParams().getUsedVideoCodec());
if (call.getCurrentParamsCopy().getUsedVideoCodec() != null) {
android.util.Log.e(TAG, "LinphoneCall--RemoteParams--UsedVideoCodec.Rate:" + call.getRemoteParams().getUsedVideoCodec
().getRate());
android.util.Log.e(TAG, "LinphoneCall--RemoteParams--UsedVideoCodec.Mime:" + call.getRemoteParams().getUsedVideoCodec
().getMime());
android.util.Log.e(TAG, "LinphoneCall--RemoteParams--UsedVideoCodec.RecvFmtp:" + call.getRemoteParams().getUsedVideoCodec
().getRecvFmtp());
android.util.Log.e(TAG, "LinphoneCall--RemoteParams--UsedVideoCodec.SendFmtp:" + call.getRemoteParams().getUsedVideoCodec
().getSendFmtp());
}
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--SessionName:"+call.getRemoteParams().getSessionName());
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--ReceivedVideoSize:"+call.getRemoteParams().getReceivedVideoSize());
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--SentVideoSize:"+call.getRemoteParams().getSentVideoSize());
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--MediaEncryption:"+call.getRemoteParams().getMediaEncryption());
android.util.Log.e(TAG,"LinphoneCall--RemoteParams--Privacy:"+call.getRemoteParams().getPrivacy());
}
android.util.Log.e(TAG, "--------------------------------------------------------------");
android.util.Log.e(TAG,"LinphoneCall--ReplacedCall:"+call.getReplacedCall());
android.util.Log.e(TAG,"LinphoneCall--TransfererCall:"+call.getTransfererCall());
android.util.Log.e(TAG,"LinphoneCall--TransferState:"+call.getTransferState());
android.util.Log.e(TAG,"LinphoneCall--TransferTargetCall:"+call.getTransferTargetCall());
android.util.Log.e(TAG,"LinphoneCall--UserData:"+call.getUserData());
android.util.Log.e(TAG,"*********************************************************************");
if (instance == null) {
Log.i("Service not ready, discarding call state change to ",state.toString());
return;
}
if (state == LinphoneCall.State.IncomingReceived) {
onIncomingReceived();
}
if (state == State.CallEnd || state == State.CallReleased || state == State.Error) {
destroyOverlay();
}
if (state == State.CallEnd && call.getCallLog().getStatus() == CallStatus.Missed) {
int missedCallCount = LinphoneManager.getLcIfManagerNotDestroyedOrNull().getMissedCallsCount();
String body;
if (missedCallCount > 1) {
body = getString(R.string.missed_calls_notif_body).replace("%i", String.valueOf(missedCallCount));
} else {
LinphoneAddress address = call.getRemoteAddress();
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
if (c != null) {
body = c.getFullName();
} else {
body = address.getDisplayName();
if (body == null) {
body = address.asStringUriOnly();
}
}
}
Notification notif = Compatibility.createMissedCallNotification(instance, getString(R.string.missed_calls_notif_title), body, mMissedCallsNotifContentIntent);
notifyWrapper(MISSED_NOTIF_ID, notif);
}
if (state == State.StreamsRunning) {
// Workaround bug current call seems to be updated after state changed to streams running
if (getResources().getBoolean(R.bool.enable_call_notification))
refreshIncallIcon(call);
} else {
if (getResources().getBoolean(R.bool.enable_call_notification))
refreshIncallIcon(LinphoneManager.getLc().getCurrentCall());
}
}
@Override
public void globalState(LinphoneCore lc,LinphoneCore.GlobalState state, String message) {
if (state == GlobalState.GlobalOn && displayServiceNotification()) {
sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
}
}
@Override
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState state, String smessage) {
// if (instance == null) {
// Log.i("Service not ready, discarding registration state change to ",state.toString());
// return;
// }
if (!mDisableRegistrationStatus) {
if (displayServiceNotification() && state == RegistrationState.RegistrationOk && LinphoneManager.getLc().getDefaultProxyConfig() != null && LinphoneManager.getLc().getDefaultProxyConfig().isRegistered()) {
sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
}
if (displayServiceNotification() && (state == RegistrationState.RegistrationFailed || state == RegistrationState.RegistrationCleared) && (LinphoneManager.getLc().getDefaultProxyConfig() == null || !LinphoneManager.getLc().getDefaultProxyConfig().isRegistered())) {
sendNotification(IC_LEVEL_ORANGE, R.string.notification_register_failure);
}
if (displayServiceNotification() && state == RegistrationState.RegistrationNone) {
sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
}
}
}
});
// Retrieve methods to publish notification and keep Android
// from killing us and keep the audio quality high.
if (Version.sdkStrictlyBelow(Version.API05_ECLAIR_20)) {
try {
mSetForeground = getClass().getMethod("setForeground", mSetFgSign);
} catch (NoSuchMethodException e) {
Log.e(e, "Couldn't find foreground method");
}
} else {
try {
mStartForeground = getClass().getMethod("startForeground", mStartFgSign);
mStopForeground = getClass().getMethod("stopForeground", mStopFgSign);
} catch (NoSuchMethodException e) {
Log.e(e, "Couldn't find startForeground or stopForeground");
}
}
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, ContactsManager.getInstance());
if (displayServiceNotification()) {
startForegroundCompat(NOTIF_ID, mNotif);
}
if (!mTestDelayElapsed) {
// Only used when testing. Simulates a 5 seconds delay for launching service
mHandler.postDelayed(new Runnable() {
@Override public void run() {
mTestDelayElapsed = true;
}
}, 5000);
}
//make sure the application will at least wakes up every 10 mn
Intent intent = new Intent(this, KeepAliveReceiver.class);
PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE));
Compatibility.scheduleAlarm(alarmManager, AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 600000, keepAlivePendingIntent);
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
}
public void createOverlay() {
if (mOverlay != null) destroyOverlay();
LinphoneCall call = LinphoneManager.getLc().getCurrentCall();
if (call == null || !call.getCurrentParamsCopy().getVideoEnabled()) return;
mOverlay = new LinphoneOverlay(this);
WindowManager.LayoutParams params = mOverlay.getWindowManagerLayoutParams();
params.x = 0;
params.y = 0;
mWindowManager.addView(mOverlay, params);
}
public void destroyOverlay() {
if (mOverlay != null) {
mWindowManager.removeViewImmediate(mOverlay);
mOverlay.destroy();
}
mOverlay = null;
}
private enum IncallIconState {INCALL, PAUSE, VIDEO, IDLE}
private IncallIconState mCurrentIncallIconState = IncallIconStat