This commit is contained in:
2020-09-10 22:38:32 +08:00
parent 34b8ae06ab
commit 22fd760d55
136 changed files with 7495 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
package com.tianrun.sipcall;
import android.content.Context;
import android.util.Log;
import androidx.multidex.MultiDexApplication;
public class App extends MultiDexApplication {
public static String TAG = "ApplicationAPP";
private static App sInstance;
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
}
public static App getInstance() {
return sInstance;
}
public static Context getContext() {
return sInstance;
}
public static String getRString(int resid) {
return sInstance.getString(resid);
}
@Override
public void onTerminate() {
super.onTerminate();
Log.e(TAG, "Application终止");
}
}

View File

@@ -0,0 +1,21 @@
package com.tianrun.sipcall;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.tianrun.sipcall.login.LoginActivity;
public class BootBroadcastReceiver extends BroadcastReceiver {
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(ACTION)){
Intent myIntent = new Intent(context, LoginActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
}
}

View File

@@ -0,0 +1,318 @@
package com.tianrun.sipcall;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.tianrun.sipcall.call.CallMediaUtils;
import com.tianrun.sipcall.call.InCallActivity;
import com.tianrun.sipcall.call.InCallMeetingActivity;
import com.tianrun.sipcall.call.utils.InCallUtils;
import com.tianrun.sipcall.net.Net;
import com.tianrun.sipcall.ui.ActivityMgr;
import com.tianrun.sipcall.ui.UIUtl;
import com.tianrun.sipcall.utils.CONS;
import com.tianrun.sipcall.utils.HttpUtl;
import com.tianrun.sipcall.utils.logmy;
import java.util.ArrayList;
import java.util.List;
import blue.all.BluetelEngine;
import blue.bluetelobserver.BluetelInterface;
public class SipEngine implements BluetelInterface {
public static final String TAG = "TestEngine";
private static SipEngine Instance;
public boolean onLine = false;
public boolean isRelogin = false;
private String name = "0";
private String pw = "0";
public String ip = "0";
private int port = 0;
public static List<InCallUtils> callPagesConfig = new ArrayList<InCallUtils>();//所有通话页面的集合
private BluetelEngine myBluetelEngine;
public static SipEngine getInstance() {
if (Instance == null)
Instance = new SipEngine();
return Instance;
}
//删除页面配置
private void removeConfig(int callid) {
//移除页面配置
InCallUtils cursorPagesConfig = null;
for (InCallUtils icu : callPagesConfig) {
if (icu.getCallId() == callid) {
cursorPagesConfig = icu;
}
}
if (cursorPagesConfig != null) {
callPagesConfig.remove(cursorPagesConfig);
}
}
/**
* 根据号码查通话的id
*
* @param callnumber
* @return
*/
public int getCallId(String callnumber) {
int res = 0;
for (InCallUtils icu : callPagesConfig) {
if (icu.getCallNumber().equals(callnumber)) {
res = icu.getCallId();
break;
}
}
return res;
}
/**
* 退出
*/
public void stop() {
myBluetelEngine.deinit();
}
public String getip() {
return ip;
}
public String getName() {return name;};
public boolean isonLine() {
return onLine;
}
public void init() {
if (myBluetelEngine == null) {
myBluetelEngine = new BluetelEngine(App.getContext(), this);
} else {
myBluetelEngine.Stop();
myBluetelEngine = new BluetelEngine(App.getContext(), this);
}
logmy.e("服务启动");
}
/**
* 注册
*
* @param name
* @param pw
* @param ip
* @param port
*/
public void Register(String name, String pw, String ip, int port) {
this.name = name;
this.pw = pw;
this.ip = ip;
this.port = port;
myBluetelEngine.Register(name, pw, ip, port);
}
/**
* 注销
*/
public void Unregister() {
onLine = false;
myBluetelEngine.Stop();
}
/**************************** 接口 *************************************************/
@Override
public void AccountState(String uri, boolean state) {
logmy.e(uri + "-->" + state);
if (state) {
if (!onLine) {
onLine = true;
Net.login(this.name, this.pw, new HttpUtl.CallBack() {
@Override
public void onRequestComplete(int cmd, String result, Object orgs) {
ActivityMgr.sendMsg(CONS.LOGIN, null);
}
@Override
public void onRequestError(int cmd, String result, Object orgs) {
UIUtl.toastI("取得token失败");
ActivityMgr.sendMsg(CONS.LOGINFAILED, null);
}
}, null);
}
} else {
if(!onLine && !isRelogin) {
UIUtl.toastI("Sip登陆失败");
ActivityMgr.sendMsg(CONS.LOGINFAILED, null);
}
}
isRelogin = false;
}
public boolean isMeetingCall(String phoneNo) {
if (phoneNo.length() >= 5) {
return true;
}
return false;
}
@Override
public void FirstIncoming(String incomingNumber, boolean isVideo, int rPort, int lPort, boolean isHolder, int callid) {
logmy.e("FirstIncoming" + incomingNumber + "<>" + isVideo + "<>" + rPort + "<>" + lPort + "<>" + isHolder + "<>" + callid);
int calltype = isVideo == false ? 0 : 1;
String state = isVideo == true ? "视频来电" : "音频来电";
callPagesConfig.add(new InCallUtils(incomingNumber, isHolder, isVideo, rPort, lPort, incomingNumber, state, false, 0, callid));
GoToInCall(App.getContext(), incomingNumber, "来电", calltype, callid);
}
@Override
public void OtherIncoming(String incomingNumber, boolean isVideo, int rPort, int lPort, boolean isHolder, int callid) {
logmy.e("OtherIncoming:" + incomingNumber + "<>" + isVideo + "<>" + rPort + "<>" + lPort + "<>" + isHolder + "<>" + callid);
String state = isVideo == true ? "视频来电" : "音频来电";
callPagesConfig.add(new InCallUtils(incomingNumber, isHolder, isVideo, rPort, lPort, incomingNumber, state, false, 0, callid));
}
@Override
public void StateCallDown(int callid, String number) {
logmy.e(callid + "<>" + number);
removeConfig(callid);
ActivityMgr.sendMsg(CONS.CALLDOWN, callid);
}
@Override
public void CallState(int callid, int callstate, String number) {
String stateValues = "未知状态";
switch (callstate) {
case 1:
stateValues = "呼叫中";//也可以在这里启动主动呼叫界面(此demo主动启动页面做在了button上)
break;
case 2:
stateValues = "未知";
break;
case 3:
stateValues = "振铃中";
break;
case 4:
stateValues = "连接中";
break;
case 5:
stateValues = "通话中";
//一般在这里进行增益调节
break;
case 6:
stateValues = "挂断";
break;
}
logmy.e(callid + "<>" + stateValues + "<>" + number);
ActivityMgr.sendMsg(CONS.CALLSTATE, stateValues);
}
@Override
public void NotifyCallMediaState(int callid, int r, int l, int payload) {
logmy.e("NotifyCallMediaState" + callid + "<>" + r + "<>" + l + "<>" + payload);
ActivityMgr.sendMsg(CONS.MEDIASTATE, new CallMediaUtils(callid, payload, r, l));
}
@Override
public void ErrorMessage(String s) {
logmy.e(s);
}
/************************ 方法 ***************************************************/
/**
* 去通话页面 要在NotifyCallMediaState接口之前页面开好
*
* @param context
* @param callnumber
* @param callstate
* @param calltype
* @param callid
*/
public void GoToInCall(Context context, String callnumber, String callstate, int calltype, int callid) {
Intent intent = null;
if (isMeetingCall(callnumber)) {
intent = new Intent(context, InCallMeetingActivity.class);
} else {
intent = new Intent(context, InCallActivity.class);
}
Bundle bundle = new Bundle();
bundle.putInt("callid", callid);
bundle.putString("callnumber", callnumber);
bundle.putString("callstate", callstate);
bundle.putInt("calltype", calltype);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
/**
* 打电话
*
* @param number 呼叫的号码
* @param isVideo 是否是视频呼叫
* @return
*/
public int CallNumber(String number, boolean isVideo) {
int callid = myBluetelEngine.CallNumber(number, ip, port, isVideo);
int calltype = isVideo ? 0 : 1;
GoToInCall(App.getContext(), number, "呼叫中", calltype, callid);
callPagesConfig.add(new InCallUtils(number, false, isVideo, 0, 0, number, "呼叫中", false, 0, callid));
return callid;
}
/**
* 挂断电话
*
* @param callid
*/
public void hangup(int callid) {
myBluetelEngine.hangup(callid);
removeConfig(callid);//移除页面配置
}
/**
* 接听电话
*
* @param callid
*/
public void answer(int callid) {
myBluetelEngine.answer(callid);
}
/**
* 通话增益调节
*
* @param callId
* @param tx
* @param rx
*/
public void setAdjustAudio(int callId, int tx, int rx) {
myBluetelEngine.setAdjustAudio2(callId, tx, rx);
}
/**
* 通话保持
*
* @param isHolder
* @param callid
* @return
*/
public boolean Holder(boolean isHolder, int callid) {
return myBluetelEngine.Holder(isHolder, callid);
}
}

View File

@@ -0,0 +1,91 @@
package com.tianrun.sipcall.call;
import com.tianrun.sipcall.R;
import com.tianrun.sipcall.SipEngine;
import com.tianrun.sipcall.ui.TrBaseActivity;
import com.tianrun.sipcall.utils.CONS;
import android.app.Activity;
import android.content.Intent;
import android.os.Handler.Callback;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class CallActivity extends TrBaseActivity implements AdapterView.OnItemClickListener {
public static Handler handler_CallActivity;
// private Handler handler = new Handler(this);
private String[] nums = {"1","2","3","4","5","6","7","8","9","*","0","#"};
private EditText et_callnumber;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_callactivity);
handler_CallActivity = handler;
et_callnumber = (EditText) findViewById(R.id.et_callnumber);
initNumKeyboard();
}
public void initNumKeyboard(){
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getBaseContext(), android.R.layout.simple_expandable_list_item_1, nums);
GridView gv = findViewById(R.id.NumKeyBoard);
gv.setAdapter(adapter);
gv.setOnItemClickListener(this);
}
public void audiocall(View view) {
String callnumber = et_callnumber.getText().toString();
if (callnumber.isEmpty()) {
Toast.makeText(CallActivity.this, "号码不能为空", Toast.LENGTH_SHORT).show();
return;
}
SipEngine.getInstance().CallNumber(callnumber, false);
}
public void videocall(View view) {
String callnumber = et_callnumber.getText().toString();
if (callnumber.isEmpty()) {
Toast.makeText(CallActivity.this, "号码不能为空", Toast.LENGTH_SHORT).show();
return;
}
SipEngine.getInstance().CallNumber(callnumber, true);
}
public void createmeeting(View view)
{
startActivity(new Intent(this, CreateMeetingActivity.class));
}
@Override
protected void onDestroy() {
super.onDestroy();
handler_CallActivity = null;
}
@Override
public boolean handleMessage(Message m) {
switch (m.what) {
case CONS.FINISH:
finish();
break;
}
return true;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
et_callnumber.setText(et_callnumber.getText()+nums[position]);
}
}

View File

@@ -0,0 +1,56 @@
package com.tianrun.sipcall.call;
public class CallMediaUtils {
/**
* 通话的id
*/
private int callid;
/**
* payload
*/
private int payload;
/**
* 本地端口
*/
private int l;
/**
* 远程端口
*/
private int r;
public CallMediaUtils(int callid, int payload, int r, int l) {
super();
this.callid = callid;
this.payload = payload;
this.l = l;
this.r = r;
}
public int getCallid() {
return callid;
}
public void setCallid(int callid) {
this.callid = callid;
}
public int getPayload() {
return payload;
}
public void setPayload(int payload) {
this.payload = payload;
}
public int getL() {
return l;
}
public void setL(int l) {
this.l = l;
}
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
}

View File

@@ -0,0 +1,239 @@
package com.tianrun.sipcall.call;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.alibaba.fastjson.JSONObject;
import com.qmuiteam.qmui.skin.QMUISkinManager;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.tianrun.sipcall.R;
import com.tianrun.sipcall.SipEngine;
import com.tianrun.sipcall.db.DBUser;
import com.tianrun.sipcall.net.Net;
import com.tianrun.sipcall.ui.TrAdapter;
import com.tianrun.sipcall.ui.TrBaseActivity;
import com.tianrun.sipcall.ui.UIUtl;
import com.tianrun.sipcall.utils.HttpUtl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class CreateGroupActivity extends TrBaseActivity {
TextView meetingTopic;
GridView gridUsers;
TrAdapter adapterUser;
List<DBUser> users = new ArrayList<>();
HashMap<String, DBUser> mapUsers = new HashMap<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.creatgroup_view);
View rootView = findViewById(R.id.RelativeLayoutNewGroupRoot);
meetingTopic = rootView.findViewById(R.id.group_name);
gridUsers = rootView.findViewById(R.id.GridUser_select);
users.clear();
mapUsers.clear();
DBUser u = new DBUser("", "添加分机号", "");
u.isAddFlag = true;
users.add(u);
setList(null);
}
public class UserSelectViews {
public TextView textViewName;
public TextView textViewNum;
public ImageView imageViewStatus;
public Button buttonDel;
public CheckBox checkBox;
public ImageView getImageViewPhoneIcon;
public ImageView imageViewAddflag;
}
public void setList(List<DBUser> list) {
if (list != null) {
for (DBUser u : list) {
mapUsers.put(u.phone, u);
users.add(users.size() - 1, u);
}
}
if (adapterUser == null) {
adapterUser = UIUtl.setList(this, gridUsers, R.layout.list_item_user_select, users, new TrAdapter.Callback() {
@Override
public void initCallback(Object data, int position, View prefabView, ViewGroup parent) {
UserSelectViews views;
if (prefabView.getTag() == null) {
views = new UserSelectViews();
views.textViewName = prefabView.findViewById(R.id.textViewName);
views.textViewNum = prefabView.findViewById(R.id.textViewNum);
views.imageViewStatus = prefabView.findViewById(R.id.imageViewStatus);
views.buttonDel = prefabView.findViewById(R.id.buttonDel);
views.checkBox = prefabView.findViewById(R.id.checkBox);
views.getImageViewPhoneIcon = prefabView.findViewById(R.id.imageView3PhoneIcon);
views.imageViewAddflag = prefabView.findViewById(R.id.imageViewAddFlag);
prefabView.setTag(views);
} else {
views = (UserSelectViews) (prefabView.getTag());
}
DBUser user = (DBUser) data;
if (user.isAddFlag) {
views.imageViewAddflag.setVisibility(View.VISIBLE);
views.buttonDel.setVisibility(View.INVISIBLE);
views.checkBox.setVisibility(View.INVISIBLE);
views.getImageViewPhoneIcon.setVisibility(View.INVISIBLE);
} else {
views.imageViewAddflag.setVisibility(View.INVISIBLE);
views.buttonDel.setVisibility(View.VISIBLE);
views.checkBox.setVisibility(View.INVISIBLE);
views.getImageViewPhoneIcon.setVisibility(View.VISIBLE);
}
views.textViewName.setText(user.name);
views.textViewNum.setText(user.phone);
if (user.isOffline()) {
views.imageViewStatus.setColorFilter(Color.GRAY);
} else if (user.isOnline()) {
views.imageViewStatus.setColorFilter(Color.GREEN);
} else if (user.isBusy()) {
views.imageViewStatus.setColorFilter(Color.RED);
} else {
views.imageViewStatus.setColorFilter(Color.GRAY);
}
views.checkBox.setChecked(true);
views.checkBox.setClickable(false);
// views.checkBox.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// UserSelect d = (UserSelect) data;
// d.isSelected = !d.isSelected;
// adapterUser.notifyDataSetChanged();
// refreshSelectedUsers();
// }
// });
views.buttonDel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
users.remove(data);
mapUsers.remove(user.phone);
adapterUser.notifyDataSetChanged();
}
});
}
@Override
public void clickCallback(Object data, AdapterView<?> parent, View view, int position, long id) {
DBUser d = (DBUser) data;
if (d.isAddFlag) {
showUsersMultiChoiceDialog();
}
}
});
} else {
adapterUser.notifyDataSetChanged();
}
}
private void showUsersMultiChoiceDialog() {
List<String> list = new ArrayList<>();
List<String> listPhone = new ArrayList<>();
for (DBUser u : DBUser.allUser) {
if (mapUsers.get(u.phone) == null) {
listPhone.add(u.phone);
list.add(u.phone + "|" + u.name);
}
}
if(list.size() == 0) {
UIUtl.toastI("所有分机已经添加");
return;
}
final String[] items = new String[list.size()];
list.toArray(items);
final QMUIDialog.MultiCheckableDialogBuilder builder = new QMUIDialog.MultiCheckableDialogBuilder(this)
.setTitle("选择要加入的分机号")
// .setCheckedItems(new int[]{1, 3})
.setSkinManager(QMUISkinManager.defaultInstance(this))
.addItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.addAction("取消", new QMUIDialogAction.ActionListener() {
@Override
public void onClick(QMUIDialog dialog, int index) {
dialog.dismiss();
}
});
builder.addAction("确定", new QMUIDialogAction.ActionListener() {
@Override
public void onClick(QMUIDialog dialog, int index) {
int[] selectIndexs = builder.getCheckedItemIndexes();
if (selectIndexs.length > 0) {
List<DBUser> list = new ArrayList<>();
for (int i = 0; i < selectIndexs.length; i++) {
String phNum = listPhone.get(selectIndexs[i]);
list.add(DBUser.getUser(phNum));
}
setList(list);
}
dialog.dismiss();
}
});
int mCurrentDialogStyle = com.qmuiteam.qmui.R.style.QMUI_Dialog;
builder.create(mCurrentDialogStyle).show();
}
public String getSelectedUsers() {
String str = "";
for (DBUser us : users) {
if (!us.isAddFlag) {
str = str + us.phone + ",";
}
}
return str;
}
public void createGroup(View view) {
String userStr = getSelectedUsers();
if (userStr == null || userStr == "") {
UIUtl.toastI("请添加要加入会议的分机号");
return;
}
//TODO:
}
public void exit(View view) {
finish();
}
@Override
public boolean handleMessage(@NonNull Message msg) {
return super.handleMessage(msg);
}
}

View File

@@ -0,0 +1,295 @@
package com.tianrun.sipcall.call;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.alibaba.fastjson.JSONObject;
import com.qmuiteam.qmui.skin.QMUISkinManager;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.tianrun.sipcall.R;
import com.tianrun.sipcall.SipEngine;
import com.tianrun.sipcall.db.DBUser;
import com.tianrun.sipcall.net.Net;
import com.tianrun.sipcall.net.NetPkg;
import com.tianrun.sipcall.ui.TrAdapter;
import com.tianrun.sipcall.ui.TrBaseActivity;
import com.tianrun.sipcall.ui.UIUtl;
import com.tianrun.sipcall.utils.HttpUtl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class CreateMeetingActivity extends TrBaseActivity {
TextView meetingTopic;
TextView meetingDesc;
TextView meetingUsers;
GridView gridUsers;
TrAdapter adapterUser;
List<DBUser> users = new ArrayList<>();
HashMap<String, DBUser> mapUsers = new HashMap<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.creatmeeting_view);
meetingTopic = findViewById(R.id.meeting_name);
meetingDesc = findViewById(R.id.meeting_desc);
meetingUsers = findViewById(R.id.textViewMembers);
gridUsers = findViewById(R.id.GridUser_select);
users.clear();
mapUsers.clear();
DBUser u = new DBUser("", "添加分机号", "");
u.isAddFlag = true;
users.add(u);
setList(null);
refreshSelectedUsers();
}
@Override
protected void onResume() {
super.onResume();
refreshSelectedUsers();
}
public class UserSelectViews {
public TextView textViewName;
public TextView textViewNum;
public ImageView imageViewStatus;
public Button buttonDel;
public CheckBox checkBox;
public ImageView getImageViewPhoneIcon;
public ImageView imageViewAddflag;
}
public void setList(List<DBUser> list) {
if (list != null) {
for (DBUser u : list) {
mapUsers.put(u.phone, u);
users.add(users.size() - 1, u);
}
}
if (adapterUser == null) {
adapterUser = UIUtl.setList(this, gridUsers, R.layout.list_item_user_select, users, new TrAdapter.Callback() {
@Override
public void initCallback(Object data, int position, View prefabView, ViewGroup parent) {
UserSelectViews views;
if (prefabView.getTag() == null) {
views = new UserSelectViews();
views.textViewName = prefabView.findViewById(R.id.textViewName);
views.textViewNum = prefabView.findViewById(R.id.textViewNum);
views.imageViewStatus = prefabView.findViewById(R.id.imageViewStatus);
views.buttonDel = prefabView.findViewById(R.id.buttonDel);
views.checkBox = prefabView.findViewById(R.id.checkBox);
views.getImageViewPhoneIcon = prefabView.findViewById(R.id.imageView3PhoneIcon);
views.imageViewAddflag = prefabView.findViewById(R.id.imageViewAddFlag);
prefabView.setTag(views);
} else {
views = (UserSelectViews) (prefabView.getTag());
}
DBUser user = (DBUser) data;
if (user.isAddFlag) {
views.imageViewAddflag.setVisibility(View.VISIBLE);
views.buttonDel.setVisibility(View.INVISIBLE);
views.checkBox.setVisibility(View.INVISIBLE);
views.getImageViewPhoneIcon.setVisibility(View.INVISIBLE);
} else {
views.imageViewAddflag.setVisibility(View.INVISIBLE);
views.buttonDel.setVisibility(View.VISIBLE);
views.checkBox.setVisibility(View.INVISIBLE);
views.getImageViewPhoneIcon.setVisibility(View.VISIBLE);
}
views.textViewName.setText(user.name);
views.textViewNum.setText(user.phone);
if (user.isOffline()) {
views.imageViewStatus.setColorFilter(Color.GRAY);
} else if (user.isOnline()) {
views.imageViewStatus.setColorFilter(Color.GREEN);
} else if (user.isBusy()) {
views.imageViewStatus.setColorFilter(Color.RED);
} else {
views.imageViewStatus.setColorFilter(Color.GRAY);
}
views.checkBox.setChecked(true);
views.checkBox.setClickable(false);
// views.checkBox.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// UserSelect d = (UserSelect) data;
// d.isSelected = !d.isSelected;
// adapterUser.notifyDataSetChanged();
// refreshSelectedUsers();
// }
// });
views.buttonDel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
users.remove(data);
mapUsers.remove(user.phone);
adapterUser.notifyDataSetChanged();
refreshSelectedUsers();
}
});
}
@Override
public void clickCallback(Object data, AdapterView<?> parent, View view, int position, long id) {
DBUser d = (DBUser) data;
if (d.isAddFlag) {
showUsersMultiChoiceDialog();
}
}
});
} else {
adapterUser.notifyDataSetChanged();
refreshSelectedUsers();
}
}
private void showUsersMultiChoiceDialog() {
List<String> list = new ArrayList<>();
List<String> listPhone = new ArrayList<>();
for (DBUser u : DBUser.allUser) {
if (mapUsers.get(u.phone) == null) {
listPhone.add(u.phone);
list.add(u.phone + " | " + u.name);
}
}
if(list.size() == 0) {
UIUtl.toastI("所有分机已经添加");
return;
}
final String[] items = new String[list.size()];
list.toArray(items);
final QMUIDialog.MultiCheckableDialogBuilder builder = new QMUIDialog.MultiCheckableDialogBuilder(this)
.setTitle("选择要加入的分机号")
// .setCheckedItems(new int[]{1, 3})
.setSkinManager(QMUISkinManager.defaultInstance(this))
.addItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.addAction("取消", new QMUIDialogAction.ActionListener() {
@Override
public void onClick(QMUIDialog dialog, int index) {
dialog.dismiss();
}
});
builder.addAction("确定", new QMUIDialogAction.ActionListener() {
@Override
public void onClick(QMUIDialog dialog, int index) {
int[] selectIndexs = builder.getCheckedItemIndexes();
if (selectIndexs.length > 0) {
List<DBUser> list = new ArrayList<>();
for (int i = 0; i < selectIndexs.length; i++) {
String phNum = listPhone.get(selectIndexs[i]);
list.add(DBUser.getUser(phNum));
}
setList(list);
}
dialog.dismiss();
}
});
int mCurrentDialogStyle = com.qmuiteam.qmui.R.style.QMUI_Dialog;
builder.create(mCurrentDialogStyle).show();
}
public void refreshSelectedUsers() {
meetingUsers.setText("已选择:" + getSelectedUsers());
}
public String getSelectedUsers() {
String str = "";
for (DBUser us : users) {
if (!us.isAddFlag) {
str = str + us.phone + ",";
}
}
return str;
}
public void createMeetingVoice(View view) {
createMeeting(false);
}
public void createMeetingVideo(View view) {
createMeeting(true);
}
void createMeeting(boolean isVideo) {
String userStr = getSelectedUsers();
if (userStr == null || userStr == "") {
UIUtl.toastI("请添加要加入会议的分机号");
return;
}
QMUITipDialog dialog = UIUtl.toastLoading("");
Net.createMeeting(meetingTopic.getText().toString(), meetingDesc.getText().toString(), userStr, new HttpUtl.CallBack() {
@Override
public void onRequestComplete(int cmd, String result, Object orgs) {
JSONObject jo = JSONObject.parseObject(result);
if (jo != null) {
String code = "";
if(isVideo) {
code = jo.getString("video_code");
} else {
code = jo.getString("audio_code");
}
SipEngine.getInstance().CallNumber(code, isVideo);
}
dialog.dismiss();
finish();
}
@Override
public void onRequestError(int cmd, String result, Object orgs) {
dialog.dismiss();
}
}, isVideo);
}
public void exit(View view) {
finish();
}
@Override
public boolean handleMessage(@NonNull Message msg) {
switch (msg.what) {
case Net.CMD_createMeeting:
NetPkg pkg =(NetPkg)(msg.obj);
break;
}
return super.handleMessage(msg);
}
}

View File

@@ -0,0 +1,277 @@
package com.tianrun.sipcall.call;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import com.tianrun.sipcall.R;
import com.tianrun.sipcall.SipEngine;
import com.tianrun.sipcall.ui.TrBaseActivity;
import com.tianrun.sipcall.utils.CONS;
import com.tianrun.sipcall.utils.logmy;
import blue.view.EngineServer;
import blue.view.SMPercentFrameLayout;
import blue.view.SMSurfaceViewRenderer;
public class InCallActivity extends TrBaseActivity implements OnClickListener {
public static Handler handler_CallActivity;
public static String TAG = "CallActivity";
private Handler handler = new Handler(this);
private PowerManager powerManager = null;
private WakeLock wakeLock = null;
private SMSurfaceViewRenderer localRender;
private SMSurfaceViewRenderer remoteRender;
private SMPercentFrameLayout localRenderLayout;
private SMPercentFrameLayout remoteRenderLayout;
private ImageButton incall_answer, incall_hangup;
private TextView show;
// private Button meetingbutton;
private EngineServer engineServer;
private int callid = -1;//当前通话的id
private String callnumber = "未知";
private String callstate = "未知";
private int calltype = 0; //0音频1视频
private boolean VIDEOSTATE = false;
public static Intent incallIntent;
@SuppressLint("InvalidWakeLockTag")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// fullScreen();
setContentView(R.layout.incallactivity);
handler_CallActivity = handler;
powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
//获取PowerManager.WakeLock对象后面的参数|表示同时传入两个值最后的是调试用的Tag
wakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
//点亮屏幕
wakeLock.acquire();
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock kl = km.newKeyguardLock("unLock");
kl.disableKeyguard();
initview();
incallIntent = getIntent();
setDate(this.getIntent());
}
private void initview() {
show = (TextView) findViewById(R.id.show);
incall_answer = (ImageButton) findViewById(R.id.incall_answer);
incall_hangup = (ImageButton) findViewById(R.id.incall_hangup);
incall_hangup.setOnClickListener(this);
incall_answer.setOnClickListener(this);
//下面为视频部分
localRender = (SMSurfaceViewRenderer) findViewById(R.id.local_video_view);
remoteRender = (SMSurfaceViewRenderer) findViewById(R.id.remote_video_view);
localRenderLayout = (SMPercentFrameLayout) findViewById(R.id.local_video_layout);
remoteRenderLayout = (SMPercentFrameLayout) findViewById(R.id.remote_video_layout);
engineServer = new EngineServer(localRender, remoteRender, localRenderLayout, remoteRenderLayout, true);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
fullScreen();
incallIntent = getIntent();
setDate(intent);
}
@Override
protected void onResume() {
super.onResume();
if (callstate.equals("来电")) {
incall_answer.setVisibility(View.VISIBLE);
} else {
incall_answer.setVisibility(View.GONE);
}
show.setText(callnumber + callstate);
if (incall_answer.getVisibility() == View.VISIBLE) {
incall_answer.setVisibility(View.GONE);
SipEngine.getInstance().answer(callid);
}
}
@Override
protected void onPause() {
super.onPause();
// onDestroy();
}
@Override
protected void onDestroy() {
stopVideoStream(true);
super.onDestroy();
SipEngine.getInstance().hangup(callid);
handler_CallActivity = null;
if (wakeLock != null) {
wakeLock.release();
wakeLock = null;
}
}
/**
* 变更通话数据
*/
public void setDate(Intent intent) {
Bundle bundle = intent.getExtras();
callid = bundle.getInt("callid");
callnumber = bundle.getString("callnumber");
callstate = bundle.getString("callstate");
calltype = bundle.getInt("calltype");
}
/**
* 停止视频
*
* @param isExit 是否完全退出视频
*/
public synchronized void stopVideoStream(boolean isExit) {
if (VIDEOSTATE && engineServer != null) {
engineServer.stopVideoStream(isExit);
VIDEOSTATE = false;
}
}
@Override
public boolean handleMessage(Message m) {
switch (m.what) {
case CONS.CALLSTATE:
callstate = (String) m.obj;
show.setText(callnumber + callstate);
if (callstate.equals("挂断")) {
stopVideoStream(true);
finish();
}
break;
case CONS.MEDIASTATE:
CallMediaUtils utils = (CallMediaUtils) m.obj;
int r = utils.getR();
int l = utils.getL();
int payload = utils.getPayload();
if (r != 0 || l != 0) {
//开始视频
ShowVideoView(true);
startVideoStream(SipEngine.getInstance().getip(), r, l, payload);
} else {
//开始音频
stopVideoStream(false);
ShowVideoView(false);
}
break;
case CONS.CALLDOWN:
stopVideoStream(true);
finish();
break;
}
return true;
}
private synchronized void startVideoStream(String server, int rport, int lport, final int payload) {
int BitRate = 768;
int FrameRate = 10;
int w = 480;
int h = 270;
String camerafb = "Front";
int c = 1;
switch (camerafb) {
case "Front":
c = 1;
break;
case "Post":
c = 0;
break;
case "Usb":
c = 2;
break;
}
c = 0;
logmy.e(callnumber + "--" + server + "--" + rport + "--" + lport);
if (engineServer != null) {
ShowVideoView(true);
/*
* 开始视频
* @param context
* @param server 服务器地址
* @param rport 远程端口
* @param lport 本地端口
* @param payload payload
* @param BitRate 带宽
* @param FrameRate 帧率
* @param w 宽
* @param h 高
* @param camtype 摄像头前后外置
* @param videoHwAcceleration 是否启用硬编
* @param recordTx 是否录制远程画面
* @param recordRx 是否录制本地画面
* @param saveVideoDir 录制画面存放的文件
*/
engineServer.startVideoStream(this, server, rport, lport, payload, BitRate, FrameRate, w, h, c, true);
VIDEOSTATE = true;
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.incall_hangup:
SipEngine.getInstance().hangup(callid);
if (SipEngine.callPagesConfig.size() == 0) {
finish();
}
break;
case R.id.incall_answer:
incall_answer.setVisibility(View.GONE);
SipEngine.getInstance().answer(callid);
break;
}
}
public void ShowVideoView(boolean show) {
if (show) {
localRenderLayout.setVisibility(View.VISIBLE);
remoteRenderLayout.setVisibility(View.VISIBLE);
} else {
localRenderLayout.setVisibility(View.GONE);
remoteRenderLayout.setVisibility(View.GONE);
}
}
@SuppressLint("NewApi")
void fullScreen() {
int flag = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
getWindow().getDecorView().setSystemUiVisibility(flag);
}
public void switchCamera() {
if (engineServer != null) {
engineServer.switchCamera(null);
}
}
}

View File

@@ -0,0 +1,276 @@
package com.tianrun.sipcall.call;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;
import com.tianrun.sipcall.R;
import com.tianrun.sipcall.SipEngine;
import com.tianrun.sipcall.ui.TrBaseActivity;
import com.tianrun.sipcall.utils.CONS;
import com.tianrun.sipcall.utils.logmy;
import blue.view.EngineServer;
import blue.view.SMPercentFrameLayout;
import blue.view.SMSurfaceViewRenderer;
public class InCallMeetingActivity extends TrBaseActivity implements OnClickListener {
public static Handler handler_CallActivity;
public static String TAG = "CallMeetingActivity";
private Handler handler = new Handler(this);
private PowerManager powerManager = null;
private WakeLock wakeLock = null;
private SMSurfaceViewRenderer localRender;
private SMSurfaceViewRenderer remoteRender;
private SMPercentFrameLayout localRenderLayout;
private SMPercentFrameLayout remoteRenderLayout;
private ImageButton incall_answer, incall_hangup;
private TextView show;
private EngineServer engineServer;
private int callid = -1;//当前通话的id
private String callnumber = "未知";
private String callstate = "未知";
private int calltype = 0; //0音频1视频
private boolean VIDEOSTATE = false;
public static Intent incallIntent;
@SuppressLint("InvalidWakeLockTag")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// fullScreen();
setContentView(R.layout.incallmeetingactivity);
handler_CallActivity = handler;
powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
//获取PowerManager.WakeLock对象后面的参数|表示同时传入两个值最后的是调试用的Tag
wakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
//点亮屏幕
wakeLock.acquire();
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock kl = km.newKeyguardLock("unLock");
kl.disableKeyguard();
initview();
incallIntent = getIntent();
setDate(this.getIntent());
}
private void initview() {
show = (TextView) findViewById(R.id.show);
incall_answer = (ImageButton) findViewById(R.id.incall_answer);
incall_hangup = (ImageButton) findViewById(R.id.incall_hangup);
incall_hangup.setOnClickListener(this);
incall_answer.setOnClickListener(this);
//下面为视频部分
localRender = (SMSurfaceViewRenderer) findViewById(R.id.local_video_view);
remoteRender = (SMSurfaceViewRenderer) findViewById(R.id.remote_video_view);
localRenderLayout = (SMPercentFrameLayout) findViewById(R.id.local_video_layout);
remoteRenderLayout = (SMPercentFrameLayout) findViewById(R.id.remote_video_layout);
engineServer = new EngineServer(localRender, remoteRender, localRenderLayout, remoteRenderLayout, true);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
fullScreen();
incallIntent = getIntent();
setDate(intent);
}
@Override
protected void onResume() {
super.onResume();
if (callstate.equals("来电")) {
incall_answer.setVisibility(View.VISIBLE);
} else {
incall_answer.setVisibility(View.GONE);
}
show.setText(callnumber + callstate);
//控件显示号码,来电,去电,通话中...
if (incall_answer.getVisibility() == View.VISIBLE) {
incall_answer.setVisibility(View.GONE);
SipEngine.getInstance().answer(callid);
}
}
@Override
protected void onPause() {
super.onPause();
// onDestroy();
}
@Override
protected void onDestroy() {
stopVideoStream(true);
super.onDestroy();
SipEngine.getInstance().hangup(callid);
handler_CallActivity = null;
if (wakeLock != null) {
wakeLock.release();
wakeLock = null;
}
}
/**
* 变更通话数据
*/
public void setDate(Intent intent) {
Bundle bundle = intent.getExtras();
callid = bundle.getInt("callid");
callnumber = bundle.getString("callnumber");
callstate = bundle.getString("callstate");
calltype = bundle.getInt("calltype");
}
/**
* 停止视频
*
* @param isExit 是否完全退出视频
*/
public synchronized void stopVideoStream(boolean isExit) {
if (VIDEOSTATE && engineServer != null) {
engineServer.stopVideoStream(isExit);
VIDEOSTATE = false;
}
}
@Override
public boolean handleMessage(Message m) {
switch (m.what) {
case CONS.CALLSTATE:
callstate = (String) m.obj;
show.setText(callnumber + callstate);
if (callstate.equals("挂断")) {
stopVideoStream(true);
finish();
}
break;
case CONS.MEDIASTATE:
CallMediaUtils utils = (CallMediaUtils) m.obj;
int r = utils.getR();
int l = utils.getL();
int payload = utils.getPayload();
if (r != 0 || l != 0) {
//开始视频
ShowVideoView(true);
startVideoStream(SipEngine.getInstance().getip(), r, l, payload);
} else {
//开始音频
stopVideoStream(false);
ShowVideoView(false);
}
break;
case CONS.CALLDOWN:
stopVideoStream(true);
finish();
break;
}
return true;
}
private synchronized void startVideoStream(String server, int rport, int lport, final int payload) {
int BitRate = 768;
int FrameRate = 10;
int w = 480;
int h = 270;
String camerafb = "Front";
int c = 1;
switch (camerafb) {
case "Front":
c = 1;
break;
case "Post":
c = 0;
break;
case "Usb":
c = 2;
break;
}
c = 0;
logmy.e(callnumber + "--" + server + "--" + rport + "--" + lport);
if (engineServer != null) {
ShowVideoView(true);
/*
* 开始视频
* @param context
* @param server 服务器地址
* @param rport 远程端口
* @param lport 本地端口
* @param payload payload
* @param BitRate 带宽
* @param FrameRate 帧率
* @param w 宽
* @param h 高
* @param camtype 摄像头前后外置
* @param videoHwAcceleration 是否启用硬编
* @param recordTx 是否录制远程画面
* @param recordRx 是否录制本地画面
* @param saveVideoDir 录制画面存放的文件
*/
engineServer.startVideoStream(this, server, rport, lport, payload, BitRate, FrameRate, w, h, c, true);
VIDEOSTATE = true;
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.incall_hangup:
SipEngine.getInstance().hangup(callid);
if (SipEngine.callPagesConfig.size() == 0) {
finish();
}
break;
case R.id.incall_answer:
incall_answer.setVisibility(View.GONE);
SipEngine.getInstance().answer(callid);
break;
}
}
public void ShowVideoView(boolean show) {
if (show) {
localRenderLayout.setVisibility(View.VISIBLE);
remoteRenderLayout.setVisibility(View.VISIBLE);
} else {
localRenderLayout.setVisibility(View.GONE);
remoteRenderLayout.setVisibility(View.GONE);
}
}
@SuppressLint("NewApi")
void fullScreen() {
int flag = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
getWindow().getDecorView().setSystemUiVisibility(flag);
}
public void switchCamera() {
if (engineServer != null) {
engineServer.switchCamera(null);
}
}
}

View File

@@ -0,0 +1,221 @@
package com.tianrun.sipcall.call;
import android.content.Context;
import android.util.Log;
import com.bluetel.media.MediaConstraintsAndScalingType;
import com.bluetel.media.SMCodec;
import com.bluetel.media.SMConnection;
import com.bluetel.media.SMMediaEngine;
import com.bluetel.media.SMMediaStream;
import com.bluetel.media.SMVideoCapturer;
import com.bluetel.media.SMVideoRenderer;
import com.bluetel.media.SMVideoSource;
import com.bluetel.media.SMVideoTrack;
import org.webrtc.Camera1Enumerator;
import org.webrtc.CameraVideoCapturer;
import org.webrtc.EglBase;
import org.webrtc.RendererCommon;
import org.webrtc.VideoCapturer;
import blue.view.EngineServer;
import blue.view.SMPercentFrameLayout;
import blue.view.SMSurfaceViewRenderer;
public class MyEngineServer {
public static final String TAG = "EngineServer";
private EglBase rootEglBase;
private SMConnection connection;
private SMMediaEngine engine;
private SMVideoCapturer videoCapturer;
private SMVideoSource videoSource;
private SMMediaStream mediaStream;
private SMSurfaceViewRenderer localRender;
private SMSurfaceViewRenderer remoteRender;
private SMPercentFrameLayout localRenderLayout;
private SMPercentFrameLayout remoteRenderLayout;
public static final String VIDEO_TRACK_ID = "ARDAMSv0";
public static final String VIDEO_TRACK_ID2 = "ARDAMSv1";
public static final String AUDIO_TRACK_ID = "ARDAMSa0";
public static final String MAX_VIDEO_WIDTH_CONSTRAINT = "maxWidth";
public static final String MIN_VIDEO_WIDTH_CONSTRAINT = "minWidth";
public static final String MAX_VIDEO_HEIGHT_CONSTRAINT = "maxHeight";
public static final String MIN_VIDEO_HEIGHT_CONSTRAINT = "minHeight";
public static final String MAX_VIDEO_FPS_CONSTRAINT = "maxFrameRate";
public static final String MIN_VIDEO_FPS_CONSTRAINT = "minFrameRate";
public static final int MAX_VIDEO_WIDTH = 1920;
public static final int MAX_VIDEO_HEIGHT = 1080;
public static final int MAX_VIDEO_FPS = 30;
private static final int LOCAL_X_CONNECTED = 72;
private static final int LOCAL_Y_CONNECTED = 72;
private static final int LOCAL_WIDTH_CONNECTED = 25;
private static final int LOCAL_HEIGHT_CONNECTED = 25;
private static final int REMOTE_X = 0;
private static final int REMOTE_Y = 0;
private static final int REMOTE_WIDTH = 100;
private static final int REMOTE_HEIGHT = 100;
private static final String LAYOUT_AVERAGE = "LAYOUT_AVERAGE";
private static final String LAYOUT_REMOTEFULL = "LAYOUT_REMOTEFULL";
private static final String LAYOUT_LOCALFULL = "LAYOUT_LOCALFULL";
private static final String LAYOUT_PRIMARY = "LAYOUT_PRIMARY";
private String mLayoutState = "LAYOUT_PRIMARY";
public MyEngineServer(SMSurfaceViewRenderer var1, SMSurfaceViewRenderer var2, SMPercentFrameLayout var3, SMPercentFrameLayout var4, boolean var5) {
this.localRender = var1;
this.remoteRender = var2;
this.localRenderLayout = var3;
this.remoteRenderLayout = var4;
this.rootEglBase = EglBase.create();
if (var5) {
var1.init(this.rootEglBase.getEglBaseContext(), (RendererCommon.RendererEvents)null);
}
var2.init(this.rootEglBase.getEglBaseContext(), (RendererCommon.RendererEvents)null);
var1.setZOrderMediaOverlay(true);
this.updateVideoView();
}
private void updateVideoView() {
this.remoteRenderLayout.setPosition(0, 0, 100, 100);
this.remoteRender.setScalingType(MediaConstraintsAndScalingType.SCALE_ASPECT_FIT());
this.remoteRender.setMirror(false);
this.localRenderLayout.setPosition(72, 72, 25, 25);
this.localRender.setScalingType(MediaConstraintsAndScalingType.SCALE_ASPECT_FIT());
if (this.mLayoutState.equals("LAYOUT_PRIMARY")) {
this.localRenderLayout.setPosition(72, 72, 25, 25);
this.localRender.setScalingType(MediaConstraintsAndScalingType.SCALE_ASPECT_FIT());
} else if (this.mLayoutState.equals("LAYOUT_AVERAGE")) {
this.localRenderLayout.setPosition(50, 0, 50, 100);
this.localRender.setScalingType(MediaConstraintsAndScalingType.SCALE_ASPECT_FIT());
this.remoteRenderLayout.setPosition(0, 0, 50, 100);
this.remoteRender.setScalingType(MediaConstraintsAndScalingType.SCALE_ASPECT_FIT());
} else if (this.mLayoutState.equals("LAYOUT_REMOTEFULL")) {
this.localRenderLayout.setPosition(100, 100, 0, 0);
this.localRender.setScalingType(MediaConstraintsAndScalingType.SCALE_ASPECT_FIT());
this.remoteRenderLayout.setPosition(0, 0, 100, 100);
this.remoteRender.setScalingType(MediaConstraintsAndScalingType.SCALE_ASPECT_FIT());
} else if (this.mLayoutState.equals("LAYOUT_LOCALFULL")) {
this.localRenderLayout.setPosition(0, 0, 100, 100);
this.localRender.setScalingType(MediaConstraintsAndScalingType.SCALE_ASPECT_FIT());
this.remoteRenderLayout.setPosition(100, 100, 0, 0);
this.remoteRender.setScalingType(MediaConstraintsAndScalingType.SCALE_ASPECT_FIT());
}
this.localRender.setMirror(false);
this.remoteRender.requestLayout();
this.localRender.requestLayout();
}
public synchronized void startVideoStream(Context var1, String var2, int var3, int var4, final int var5, int var6, int var7, int var8, int var9, int var10, boolean var11) {
SMMediaEngine.initializeGlobals(var1, true, true, var11);
this.engine = SMMediaEngine.create();
this.connection = this.engine.createConnection(new SMConnection.ConnectionObserver() {
public void onAddStream(SMMediaStream var1) {
if (var1.videoTracks.size() == 1) {
SMVideoTrack var2 = (SMVideoTrack)var1.videoTracks.get(0);
var2.setEnabled(true);
var2.addRenderer(new SMVideoRenderer(MyEngineServer.this.remoteRender));
}
}
public void onRemoveStream(SMMediaStream var1) {
}
public SMCodec onReceiveVideoTrack(int var1, int var2) {
return new SMCodec(var5, 1);
}
});
this.connection.bindLocalAddr((String)null, var4, var4 + 1);
this.connection.addRemoteAddr(var2, var3, var3 + 1);
String var12 = Camera1Enumerator.getDeviceName(var10);
Log.d("EngineServer", "Opening camera: " + var12);
this.videoCapturer = SMVideoCapturer.create(var12, (CameraVideoCapturer.CameraEventsHandler)null, false);
if (this.videoCapturer == null) {
Log.d("EngineServer", "Failed to open camera");
} else {
this.videoSource = this.createVideoSource(this.videoCapturer, 1280, 720);
this.videoSource.adaptOutputFormat(var8, var9, var7);
SMVideoTrack var13 = this.engine.createVideoTrack("ARDAMSv0", this.videoSource);
var13.setEnabled(true);
SMVideoRenderer var14 = new SMVideoRenderer(this.localRender);
var13.addRenderer(var14);
this.mediaStream = this.engine.createLocalMediaStream("ARDAMS");
this.mediaStream.addTrack(var13);
int var15 = var6 * 1000;
var15 = (int)((float)var15 * 0.9F);
int var16 = var15 / 2;
int var17 = (int)((double)var15 * 0.75D);
this.mediaStream.setVideoCodec(new SMCodec(var5, 1, 20, var16, var15, var17, false));
this.connection.addSendStream(this.mediaStream);
}
}
public synchronized void stopVideoStream(boolean var1) {
if (this.connection != null) {
this.connection.dispose();
this.connection = null;
}
if (this.videoCapturer != null) {
this.videoCapturer.stopCapture();
this.videoCapturer.dispose();
this.videoCapturer = null;
}
if (this.videoSource != null) {
this.videoSource.dispose();
}
if (this.rootEglBase != null && var1) {
this.rootEglBase.release();
this.rootEglBase = null;
}
if (this.remoteRender != null && var1) {
this.remoteRender.release();
this.remoteRender = null;
}
if (this.localRender != null && var1) {
this.localRender.release();
this.localRender = null;
}
if (this.engine != null && var1) {
this.engine.dispose();
this.engine = null;
}
}
private SMVideoSource createVideoSource(VideoCapturer var1, int var2, int var3) {
return (new MediaConstraintsAndScalingType(this.engine, var1, var2, var3)).createVideoSource();
}
public synchronized void adjustVideoView(int var1) {
if (var1 == 1) {
this.mLayoutState = "LAYOUT_AVERAGE";
} else if (var1 == 2) {
this.mLayoutState = "LAYOUT_REMOTEFULL";
} else if (var1 == 3) {
this.mLayoutState = "LAYOUT_LOCALFULL";
} else {
this.mLayoutState = "LAYOUT_PRIMARY";
}
this.updateVideoView();
}
public synchronized void setLayoutState(String var1) {
this.mLayoutState = var1;
}
public synchronized void switchCamera(CameraVideoCapturer.CameraSwitchHandler var1) {
if (this.videoCapturer != null) {
this.videoCapturer.switchCamera(var1);
}
}
}

View File

@@ -0,0 +1,103 @@
package com.tianrun.sipcall.call.utils;
public class InCallUtils {
private String callNumber;
private boolean isHolder;
private boolean isVideo;
private int rPort;
private int lPort;
private String timeThreadId;
private String callState;
private boolean isCurrentCall;
private int payload;
private int callId;
public InCallUtils(String callNumber, boolean isHolder, boolean isVideo,
int rPort, int lPort, String timeThreadId, String callState,
boolean isCurrentCall, int payload,int callId) {
super();
this.callNumber = callNumber;
this.isHolder = isHolder;
this.isVideo = isVideo;
this.rPort = rPort;
this.lPort = lPort;
this.timeThreadId = timeThreadId;
this.callState = callState;
this.isCurrentCall = isCurrentCall;
this.payload = payload;
this.callId = callId;
}
public int getCallId() {
return callId;
}
public void setCallId(int callId) {
this.callId = callId;
}
public int getPayload() {
return payload;
}
public void setPayload(int payload) {
this.payload = payload;
}
public boolean isCurrentCall() {
return isCurrentCall;
}
public void setCurrentCall(boolean isCurrentCall) {
this.isCurrentCall = isCurrentCall;
}
public String getCallState() {
return callState;
}
public void setCallState(String callState) {
this.callState = callState;
}
public String getCallNumber() {
return callNumber;
}
public void setCallNumber(String callNumber) {
this.callNumber = callNumber;
}
public boolean isHolder() {
return isHolder;
}
public void setHolder(boolean isHolder) {
this.isHolder = isHolder;
}
public boolean isVideo() {
return isVideo;
}
public void setVideo(boolean isVideo) {
this.isVideo = isVideo;
}
public int getrPort() {
return rPort;
}
public void setrPort(int rPort) {
this.rPort = rPort;
}
public int getlPort() {
return lPort;
}
public void setlPort(int lPort) {
this.lPort = lPort;
}
public String getTimeThreadId() {
return timeThreadId;
}
public void setTimeThreadId(String timeThreadId) {
this.timeThreadId = timeThreadId;
}
}

View File

@@ -0,0 +1,68 @@
package com.tianrun.sipcall.db;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class DBHead {
public String name;
public String desc;
public String audio_code;
public String video_code;
public String status;
public String id;
public boolean isSelected = false;
public static List<DBHead> allGroups = new ArrayList<>();
public DBHead(String id, String name) {
this.id = id;
this.name = name;
}
public DBHead(JSONObject o) {
name = o.getString("topic");
desc = o.getString("description");
audio_code = o.getString("audio_code");
video_code = o.getString("video_code");
status = o.getString("audio_status");
id = o.getString("task_uuid");
}
public static DBHead newHead4Total() {
DBHead u = new DBHead("-999", "全部");
return u;
}
public boolean isAll() {
return id.equals("-999");
}
public static void onGetGroups(JSONArray list) {
allGroups.clear();
for (Object o : list) {
allGroups.add(new DBHead((JSONObject) o));
}
}
public static DBHead getByUUID(String uuid) {
for (DBHead d : allGroups) {
if (d.id.equals(uuid)){
return d;
}
}
return null;
}
public static DBHead getByCode(String code) {
for (DBHead d : allGroups) {
if (d.audio_code.equals(code) || d.video_code.equals(code)) {
return d;
}
}
return null;
}
}

View File

@@ -0,0 +1,23 @@
package com.tianrun.sipcall.db;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tianrun.sipcall.net.Net;
public class DBRoot {
public static void onGetData(int cmd, String content) {
switch (cmd) {
case Net.CMD_getUsers:
JSONArray allUsers = JSONObject.parseObject(content).getJSONArray("agents");
DBUser.onGetUsers(allUsers);
break;
case Net.CMD_getGroups:
JSONArray list = JSONArray.parseArray(content);
DBHead.onGetGroups(list);
break;
default:
break;
}
}
}

View File

@@ -0,0 +1,62 @@
package com.tianrun.sipcall.db;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class DBUser {
public static List<DBUser> allUser = new ArrayList<>();
public static HashMap<String, DBUser> mapUsers = new HashMap<>();
public static DBUser mySelf;
public String name = "";
public String phone = "";
public String status = "";
public boolean isManager = false;
public boolean isAddFlag = false;
public DBUser(String name, String phone, String status) {
this.name = name;
this.phone = phone;
this.status = status;
}
public DBUser(JSONObject d) {
this.name = d.getString("name");
this.phone = d.getString("extn");
this.status = d.getString("sip_state");
this.isManager = d.getString("weight").equals("1");
}
public boolean isBusy() {
return status.equals("busy");
}
public boolean isOnline() {
return status.equals("true");
}
public boolean isOffline() {
return status.equals("false");
}
public static void onGetUsers(JSONArray array) {
allUser.clear();
DBUser u;
for (Object o : array) {
u = new DBUser((JSONObject) o);
allUser.add(u);
mapUsers.put(u.phone, u);
if (mySelf != null && u.phone == mySelf.phone) {
mySelf = u;
}
}
}
public static DBUser getUser(String phoneNo) {
return mapUsers.get(phoneNo);
}
}

View File

@@ -0,0 +1,359 @@
package com.tianrun.sipcall.login;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.tianrun.sipcall.App;
import com.tianrun.sipcall.R;
import com.tianrun.sipcall.SipEngine;
import com.tianrun.sipcall.call.InCallActivity;
import com.tianrun.sipcall.call.InCallMeetingActivity;
import com.tianrun.sipcall.db.DBUser;
import com.tianrun.sipcall.net.Net;
import com.tianrun.sipcall.ui.ActivityMgr;
import com.tianrun.sipcall.ui.TrBaseActivity;
import com.tianrun.sipcall.ui.UIUtl;
import com.tianrun.sipcall.utils.CONS;
import com.tianrun.sipcall.utils.HttpUtl;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class LoginActivity extends TrBaseActivity {
private TextView show;
private EditText username, userpw, userip, userport;
/**
* 账号密码服务器地址端口直接在这输入
*/
private String name = "";
private String pw = "";
private int port = 0;
private String ip = "";
QMUITipDialog dialogLoading;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
show = findViewById(R.id.show);
username = findViewById(R.id.username);
userpw = findViewById(R.id.userpw);
userip = findViewById(R.id.userip);
userport = findViewById(R.id.userport);
if (Build.VERSION.SDK_INT >= 23) {//6.0才用动态权限
initPermission();
}
String str = getUserInfor();
if (str != null && !str.isEmpty()) {
JSONObject obj = JSONObject.parseObject(str);
username.setText(obj.getString("name"));
userpw.setText(obj.getString("password"));
userip.setText(obj.getString("ip"));
userport.setText(obj.getInteger("port").toString());
handler.postDelayed(new Runnable() {
@Override
public void run() {
boolean donotAutoLogin = false;
Intent intent = getIntent();
if (intent != null) {
Bundle bundle = intent.getExtras();
if(bundle != null) {
donotAutoLogin = bundle.getBoolean("donotAutoLogin");
}
}
if (!donotAutoLogin) {
doLogin();
}
}
}, 100);
}
}
@Override
protected void onResume() {
super.onResume();
if (InCallActivity.handler_CallActivity != null) {
startActivity(InCallActivity.incallIntent);
return;
}
if (InCallMeetingActivity.handler_CallActivity != null) {
startActivity(InCallMeetingActivity.incallIntent);
return;
}
if (SipEngine.getInstance().onLine) {
startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish();
return;
}
}
public void login(View view) {
doLogin();
}
public void doLogin() {
if (SipEngine.getInstance().isonLine())
return;
if (!isEnable())
return;
dialogLoading = UIUtl.toastLoading("");
SipEngine.getInstance().init();//先初始化
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
SipEngine.getInstance().Register(
name,
pw,
ip,
port);//再注册
}
}, 1000);
}
private boolean isEnable() {
boolean a = false;
boolean b = false;
boolean c = false;
boolean d = false;
if (username.getText().toString() != null && !username.getText().toString().equals("")) {
name = username.getText().toString();
a = true;
}
if (userpw.getText().toString() != null && !userpw.getText().toString().equals("")) {
pw = userpw.getText().toString();
b = true;
}
if (userip.getText().toString() != null && !userip.getText().toString().equals("")) {
ip = userip.getText().toString();
c = true;
}
if (userport.getText().toString() != null && !userport.getText().toString().equals("")) {
port = Integer.parseInt(userport.getText().toString());
d = true;
}
return a && b && c && d;
}
public String getUserInfor() {
SharedPreferences sp = getSharedPreferences("UserInfor", MODE_PRIVATE);
return sp.getString("content", null);
}
public void saveUserInfor(String name, String password, String ip, int port) {
JSONObject jo = new JSONObject();
jo.put("name", name);
jo.put("password", password);
jo.put("ip", ip);
jo.put("port", port);
SharedPreferences sp = getSharedPreferences("UserInfor", MODE_PRIVATE);
sp.edit().putString("content", jo.toJSONString()).commit();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public boolean handleMessage(Message m) {
switch (m.what) {
case CONS.LOGINSHOW:
String str = (String) m.obj;
show.setText(str);
break;
case CONS.LOGINFAILED:
if(dialogLoading != null) {
dialogLoading.dismiss();
}
case CONS.LOGIN:
if(dialogLoading != null) {
dialogLoading.dismiss();
}
if (isEnable()) {
saveUserInfor(this.name, this.pw, this.ip, this.port);
}
startActivity(new Intent(this, MainActivity.class));
DBUser.mySelf = new DBUser("", this.name, "true");
finish();
break;
}
return true;
}
/****************************************权限设置***************************************/
// 所需的全部权限
public static String[] permissions = new String[]{
Manifest.permission.NFC,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.INTERNET,
// Manifest.permission.READ_LOGS,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.READ_PHONE_STATE,
// Manifest.permission.WRITE_SETTINGS,
Manifest.permission.CAMERA,
Manifest.permission.MODIFY_AUDIO_SETTINGS,
// Manifest.permission.BIND_APPWIDGET,
// Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS,
// Manifest.permission.SYSTEM_OVERLAY_WINDOW,
Manifest.permission.RESTART_PACKAGES,
// Manifest.permission.SYSTEM_ALERT_WINDOW,
// Manifest.permission.SET_TIME_ZONE,
Manifest.permission.READ_CALL_LOG,
Manifest.permission.BROADCAST_STICKY,
Manifest.permission.GET_ACCOUNTS,
Manifest.permission.BLUETOOTH,
Manifest.permission.CHANGE_WIFI_MULTICAST_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.VIBRATE,
Manifest.permission.DISABLE_KEYGUARD,
Manifest.permission.WAKE_LOCK,
Manifest.permission.CALL_PHONE,
Manifest.permission.WRITE_CONTACTS,
Manifest.permission.READ_CONTACTS,
Manifest.permission.RECEIVE_BOOT_COMPLETED,
Manifest.permission.PROCESS_OUTGOING_CALLS,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.KILL_BACKGROUND_PROCESSES,
Manifest.permission.READ_EXTERNAL_STORAGE
};
List<String> mPermissionList = new ArrayList<>();
private final int mRequestCode = 100;//权限请求码
private void initPermission() {
mPermissionList.clear();//清空已经允许的没有通过的权限
//逐个判断是否还有未通过的权限
for (int i = 0; i < permissions.length; i++) {
if (ContextCompat.checkSelfPermission(this, permissions[i]) !=
PackageManager.PERMISSION_GRANTED) {
mPermissionList.add(permissions[i]);//添加还未授予的权限到mPermissionList中
}
}
//申请权限
if (mPermissionList.size() > 0) {//有权限没有通过,需要申请
ActivityCompat.requestPermissions(this, permissions, mRequestCode);
} else {
//权限已经都通过了,可以将程序继续打开了
CONS.requestPermission_ACTION_MANAGE_OVERLAY_PERMISSION(this);
CONS.requestPermission_ACTION_MANAGE_WRITE_SETTINGS(this);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 101:
break;
case 102:
break;
default:
boolean hasPermissionDismiss = false;//有权限没有通过
if (mRequestCode == requestCode) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == -1) {
hasPermissionDismiss = true;
Log.e("main", permissions[i]);
break;
}
}
}
if (hasPermissionDismiss) {//如果有没有被允许的权限
showPermissionDialog();
} else {
//权限已经都通过了,可以将程序继续打开了
}
break;
}
}
AlertDialog mPermissionDialog;
private void showPermissionDialog() {
if (mPermissionDialog == null) {
mPermissionDialog = new AlertDialog.Builder(this)
.setMessage("已禁用权限,请手动授予")
.setPositiveButton("设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
cancelPermissionDialog();
Uri packageURI = Uri.parse("package:" + App.getContext());
Intent intent = new Intent(Settings.
ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
startActivity(intent);
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//关闭页面或者做其他操作
cancelPermissionDialog();
}
})
.create();
}
mPermissionDialog.show();
}
private void cancelPermissionDialog() {
mPermissionDialog.cancel();
}
public void exit2(View view) {
Net.login(this.name, this.pw, new HttpUtl.CallBack() {
@Override
public void onRequestComplete(int cmd, String result, Object orgs) {
ActivityMgr.sendMsg(CONS.LOGIN, null);
}
@Override
public void onRequestError(int cmd, String result, Object orgs) {
UIUtl.toastI("取得token失败");
}
}, null);
}
}

View File

@@ -0,0 +1,563 @@
package com.tianrun.sipcall.login;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qmuiteam.qmui.skin.QMUISkinManager;
import com.qmuiteam.qmui.util.QMUIDisplayHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIBottomSheet;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.popup.QMUIPopups;
import com.qmuiteam.qmui.widget.popup.QMUIQuickAction;
import com.qmuiteam.qmui.widget.tab.QMUITabBuilder;
import com.qmuiteam.qmui.widget.tab.QMUITabIndicator;
import com.qmuiteam.qmui.widget.tab.QMUITabSegment;
import com.tianrun.sipcall.App;
import com.tianrun.sipcall.R;
import com.tianrun.sipcall.SipEngine;
import com.tianrun.sipcall.call.CallActivity;
import com.tianrun.sipcall.call.CreateGroupActivity;
import com.tianrun.sipcall.call.CreateMeetingActivity;
import com.tianrun.sipcall.db.DBHead;
import com.tianrun.sipcall.db.DBUser;
import com.tianrun.sipcall.net.Net;
import com.tianrun.sipcall.net.NetPkg;
import com.tianrun.sipcall.ui.ActivityMgr;
import com.tianrun.sipcall.ui.TrAdapter;
import com.tianrun.sipcall.ui.TrBaseActivity;
import com.tianrun.sipcall.ui.UIUtl;
import com.tianrun.sipcall.utils.CONS;
import com.tianrun.sipcall.utils.HttpUtl;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends TrBaseActivity {
TextView textVolum;
TextView textSelfNum;
QMUITabSegment mTabSegment;
ViewPager mContentViewPager;
Button buttonAddGroup;
ImageView imageViewAddGroupIcon;
View StartMeetingVideo;
View StartMeetingVoice;
View ButtonDelGroup;
// TrAdapter adapter;
TrAdapter adapterUser;
AudioManager audioManager;
ImageView buttonAddVol;
ImageView buttonDelVol;
DBHead currSelectData;
GridView gridUser;
List<Object> allUsers = new ArrayList<>();
List<DBHead> headers = new ArrayList<>();
private int mCurrentDialogStyle = com.qmuiteam.qmui.R.style.QMUI_Dialog;
private PagerAdapter mPagerAdapter = new PagerAdapter() {
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public int getCount() {
return headers.size();
}
@Override
public Object instantiateItem(final ViewGroup container, int position) {
// ContentPage page = ContentPage.getPage(position);
View view = getPageView(position);
// view.setTag(page);
// ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
// ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
// container.addView(view, params);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public int getItemPosition(@NonNull Object object) {
View view = (View) object;
return 0;
}
};
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textVolum = findViewById(R.id.Volumne);
textSelfNum = findViewById(R.id.textViewSelfNum);
mTabSegment = findViewById(R.id.HeadList);
gridUser = findViewById(R.id.GridUser);
mContentViewPager = findViewById(R.id.contentViewPager);
buttonAddGroup = findViewById(R.id.buttonAddGroup);
imageViewAddGroupIcon = findViewById(R.id.imageViewAddGroupIcon);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
StartMeetingVoice = findViewById(R.id.StartMeetingVoice);
StartMeetingVideo = findViewById(R.id.StartMeetingVideo);
ButtonDelGroup = findViewById(R.id.ButtonDelGroup);
buttonAddVol = findViewById(R.id.imageViewAddVoice);
buttonAddVol.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
chgVolum(v, true);
return true;
}
});
buttonDelVol = findViewById(R.id.imageViewDelVoice);
buttonDelVol.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
chgVolum(v, false);
return true;
}
});
ButtonDelGroup.setVisibility(View.INVISIBLE);
StartMeetingVoice.setVisibility(View.INVISIBLE);
StartMeetingVideo.setVisibility(View.INVISIBLE);
refreshView();
currSelectData = DBHead.newHead4Total();
currSelectData.isSelected = true;
headers.add(currSelectData);
initTabAndPager();
Net.getGroups(null, null);
Net.getUsers(null, null);
checkBeforeMeetingState();
}
// 处理当前分机号可能有需要加入的会议
private void checkBeforeMeetingState() {
Net.getUserInfor(DBUser.mySelf.phone, new HttpUtl.CallBack() {
@Override
public void onRequestComplete(int cmd, String result, Object orgs) {
JSONArray array = JSONObject.parseObject(result).getJSONArray("agents");
JSONObject jo = array.getJSONObject(0);
JSONArray comment = jo.getJSONArray("comment");
if (comment != null && comment.size() > 0) {
List<String> list = new ArrayList<>();
for (Object o : comment) {
JSONObject com = (JSONObject) o;
String name = com.getString("topic") + "" + ((com.getString("type").equals("video_profile")) ? "视频会议" : "语音会议") + "";
list.add(name);
}
UIUtl.showBottomSheetList("您有会议需要加入", list, new QMUIBottomSheet.BottomListSheetBuilder.OnSheetItemClickListener() {
@Override
public void onClick(QMUIBottomSheet dialog, View itemView, int position, String tag) {
JSONObject o = comment.getJSONObject(position);
SipEngine.getInstance().CallNumber(o.getString("nbr"), (o.getString("type").equals("video_profile")) ? true : false);
}
});
}
}
@Override
public void onRequestError(int cmd, String result, Object orgs) {
}
}, null);
}
void refreshHeaders() {
DBHead h = headers.get(0);
headers.clear();
headers.add(h);
headers.addAll(DBHead.allGroups);
mPagerAdapter.notifyDataSetChanged();
mTabSegment.reset();
QMUITabBuilder tabBuilder = mTabSegment.tabBuilder();
for (int i = 0; i < headers.size(); i++) {
mTabSegment.addTab(tabBuilder.setText(headers.get(i).name).build(this));
}
mTabSegment.notifyDataChanged();
}
private void initTabAndPager() {
mContentViewPager.setAdapter(mPagerAdapter);
// mContentViewPager.setCurrentItem(mDestPage.getPosition(), false);
QMUITabBuilder tabBuilder = mTabSegment.tabBuilder();
for (int i = 0; i < headers.size(); i++) {
mTabSegment.addTab(tabBuilder.setText(headers.get(i).name).build(this));
}
int space = QMUIDisplayHelper.dp2px(this, 16);
mTabSegment.setIndicator(new QMUITabIndicator(
QMUIDisplayHelper.dp2px(this, 2), false, true));
mTabSegment.setMode(QMUITabSegment.MODE_SCROLLABLE);
mTabSegment.setItemSpaceInScrollMode(space);
mTabSegment.setupWithViewPager(mContentViewPager, false);
mTabSegment.setPadding(space, 0, space, 0);
mTabSegment.addOnTabSelectedListener(new QMUITabSegment.OnTabSelectedListener() {
@Override
public void onTabSelected(int index) {
currSelectData = headers.get(index);
if (currSelectData.isAll()) {
ButtonDelGroup.setVisibility(View.INVISIBLE);
StartMeetingVoice.setVisibility(View.INVISIBLE);
StartMeetingVideo.setVisibility(View.INVISIBLE);
} else {
StartMeetingVoice.setVisibility(View.VISIBLE);
StartMeetingVideo.setVisibility(View.VISIBLE);
if (DBUser.mySelf.isManager) {
ButtonDelGroup.setVisibility(View.VISIBLE);
} else {
ButtonDelGroup.setVisibility(View.INVISIBLE);
}
}
//显示分机
allUsers.clear();
if(currSelectData.isAll()) {
allUsers.addAll(DBUser.allUser);
setUsers();
} else {
setUsers();
//取得数据
Net.getGroupMenbers(currSelectData.id, null, currSelectData.id);
}
}
@Override
public void onTabUnselected(int index) {
}
@Override
public void onTabReselected(int index) {
}
@Override
public void onDoubleTap(int index) {
}
});
}
public void refreshView() {
//通话音量
int max = audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
int current = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
textVolum.setText("音量:" + current);
if (DBUser.mySelf != null && DBUser.mySelf.phone != null) {
textSelfNum.setText("分机号:" + DBUser.mySelf.phone);
}
if (DBUser.mySelf != null && DBUser.mySelf.isManager) {
buttonAddGroup.setVisibility(View.VISIBLE);
imageViewAddGroupIcon.setVisibility(View.VISIBLE);
} else {
buttonAddGroup.setVisibility(View.INVISIBLE);
imageViewAddGroupIcon.setVisibility(View.INVISIBLE);
}
}
void chgVolum(View v, boolean isAdd) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (!v.isPressed()) {
return;
}
if (isAdd) {
addVolume(v);
} else {
delVolume(v);
}
if (v.isPressed()) {
chgVolum(v, isAdd);
}
}
}, 100);
}
static Runnable runGetUsers = new Runnable() {
@Override
public void run() {
Net.getUsers(null, null);
}
};
public View getPageView(int pos) {
return gridUser;
}
public void getUsersData() {
handler.postDelayed(runGetUsers, 3000);
}
public class UserViews {
public TextView textViewName;
public TextView textViewNum;
public ImageView imageViewStatus;
public ImageView imageViewPhoneIcon;
public ImageView imageViewAddflag;
}
public void setUsers() {
if (DBUser.allUser == null) return;
if (adapterUser == null) {
adapterUser = UIUtl.setList(this, gridUser, R.layout.list_item_user, allUsers, new TrAdapter.Callback() {
@Override
public void initCallback(Object data, int position, View prefabView, ViewGroup parent) {
UserViews views = null;
if (prefabView.getTag() == null) {
views = new UserViews();
views.textViewName = prefabView.findViewById(R.id.textViewName);
views.textViewNum = prefabView.findViewById(R.id.textViewNum);
views.imageViewStatus = prefabView.findViewById(R.id.imageViewStatus);
views.imageViewAddflag = prefabView.findViewById(R.id.imageViewAddflag);
views.imageViewPhoneIcon = prefabView.findViewById(R.id.imageView3PhoneIcon);
prefabView.setTag(views);
} else {
views = (UserViews) (prefabView.getTag());
}
DBUser d = (DBUser) data;
views.textViewName.setText(d.name);
views.textViewNum.setText(d.phone);
if (d.isOffline()) {
views.imageViewStatus.setColorFilter(Color.GRAY);
} else if (d.isOnline()) {
views.imageViewStatus.setColorFilter(Color.GREEN);
} else if (d.isBusy()) {
views.imageViewStatus.setColorFilter(Color.RED);
} else {
views.imageViewStatus.setColorFilter(Color.GRAY);
}
if (d.isAddFlag) {
views.imageViewPhoneIcon.setVisibility(View.INVISIBLE);
views.imageViewAddflag.setVisibility(View.VISIBLE);
} else {
views.imageViewPhoneIcon.setVisibility(View.VISIBLE);
views.imageViewAddflag.setVisibility(View.INVISIBLE);
}
}
@Override
public void clickCallback(Object data, AdapterView<?> parent, View view, int position, long id) {
DBUser d = (DBUser) data;
if (d.isAddFlag) {
//TODO:
return;
}
QMUIQuickAction qa = QMUIPopups.quickAction(MainActivity.this,
QMUIDisplayHelper.dp2px(MainActivity.this, 56),
QMUIDisplayHelper.dp2px(MainActivity.this, 56))
.shadow(true)
.dimAmount(0.5f)
.skinManager(QMUISkinManager.defaultInstance(MainActivity.this))
.edgeProtection(QMUIDisplayHelper.dp2px(MainActivity.this, 20))
.addAction(new QMUIQuickAction.Action().icon(R.drawable.voice2).text("语音").onClick(
new QMUIQuickAction.OnClickListener() {
@Override
public void onClick(QMUIQuickAction quickAction, QMUIQuickAction.Action action, int position) {
quickAction.dismiss();
SipEngine.getInstance().CallNumber(d.phone, false);
}
}
))
.addAction(new QMUIQuickAction.Action().icon(R.drawable.video).text("视频").onClick(
new QMUIQuickAction.OnClickListener() {
@Override
public void onClick(QMUIQuickAction quickAction, QMUIQuickAction.Action action, int position) {
quickAction.dismiss();
SipEngine.getInstance().CallNumber(d.phone, true);
}
}
));
if (DBUser.mySelf.isManager) {
qa.addAction(new QMUIQuickAction.Action().icon(android.R.drawable.ic_delete).text("移除").onClick(
new QMUIQuickAction.OnClickListener() {
@Override
public void onClick(QMUIQuickAction quickAction, QMUIQuickAction.Action action, int position) {
quickAction.dismiss();
//TODO:移除分机
}
}
));
}
qa.show(view);
}
});
} else {
adapterUser.notifyDataSetChanged();
}
}
// public void refreshHeadList() {
// adapter.notifyDataSetChanged();
// }
public void call(View view) {
startActivity(new Intent(MainActivity.this, CallActivity.class));
}
public void meeting(View view) {
}
public void message(View view) {
}
public void report(View view) {
}
// public void exit(View view) {
// if (ActivityMgr.getActivity(LoginActivity.class) == null) {
// Intent intent = new Intent(this, LoginActivity.class);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// startActivity(intent);
// }
// finish();
// SipEngine.getInstance().Unregister();
// }
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public boolean handleMessage(Message m) {
switch (m.what) {
case CONS.FINISH:
finish();
break;
case Net.CMD_getUsers:
getUsersData();
if (currSelectData.isAll()) {
allUsers.clear();
allUsers.addAll(DBUser.allUser);
setUsers();
}
break;
case Net.CMD_getGroupMenbers:
NetPkg pkg = (NetPkg)(m.obj);
String oldUUID = pkg.orgs.toString();
if (!currSelectData.isAll() && oldUUID.equals(currSelectData.id)) {
//TODO:解析数据
//根据权限来处理
if (DBUser.mySelf.isManager) {
DBUser u = new DBUser("", "添加分机", "false");
u.isAddFlag = true;
allUsers.add(u);
}
setUsers();
}
break;
case Net.CMD_getGroups:
refreshHeaders();
break;
}
return true;
}
@Override
protected void onStop() {
super.onStop();
handler.removeCallbacks(runGetUsers);
}
public void addVolume(View view) {
// UIUtl.toast("音量加");
// int max = audioManager.getStreamMaxVolume( AudioManager.STREAM_VOICE_CALL );
audioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_RAISE, 0);
int current = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
textVolum.setText("音量:" + current);
}
public void delVolume(View view) {
// UIUtl.toastW("音量减");
audioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_LOWER, 0);
int current = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
textVolum.setText("音量:" + current);
}
public void addGroup(View view) {
startActivity(new Intent(this, CreateGroupActivity.class));
}
public void addTmpMeeting(View view) {
startActivity(new Intent(this, CreateMeetingActivity.class));
}
public void logout(View v) {
SipEngine.getInstance().onLine = false;
SipEngine.getInstance().isRelogin = true;
// SipEngine.getInstance().Unregister();
// SipEngine.getInstance().stop();
Intent intent = new Intent(App.getContext(), LoginActivity.class);
Bundle bundle = new Bundle();
bundle.putBoolean("donotAutoLogin", true);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
public void doMeetingVoice4Group(View v) {
if (currSelectData.isAll()) {
return;
}
SipEngine.getInstance().CallNumber(currSelectData.audio_code, false);
}
public void doMeetingVideo4Group(View v) {
if (currSelectData.isAll()) {
return;
}
SipEngine.getInstance().CallNumber(currSelectData.video_code, true);
}
public void deleteGroup(View v) {
if (currSelectData.isAll()) {
return;
}
new QMUIDialog.MessageDialogBuilder(this)
.setTitle("提示")
.setMessage("确定要删除分组吗?")
.setSkinManager(QMUISkinManager.defaultInstance(this))
.addAction("取消", new QMUIDialogAction.ActionListener() {
@Override
public void onClick(QMUIDialog dialog, int index) {
dialog.dismiss();
}
})
.addAction(0, "删除", QMUIDialogAction.ACTION_PROP_NEGATIVE, new QMUIDialogAction.ActionListener() {
@Override
public void onClick(QMUIDialog dialog, int index) {
//TODO:
dialog.dismiss();
}
})
.create(mCurrentDialogStyle).show();
}
}

View File

@@ -0,0 +1,95 @@
package com.tianrun.sipcall.net;
import android.util.Log;
import com.alibaba.fastjson.JSONObject;
import com.tianrun.sipcall.App;
import com.tianrun.sipcall.db.DBRoot;
import com.tianrun.sipcall.ui.ActivityMgr;
import com.tianrun.sipcall.ui.UIUtl;
import com.tianrun.sipcall.utils.HttpUtl;
public class Net {
public static String ip = "47.111.20.34";
public static int port = 29003;
private static final String TAG = "NetDisPatch";
public static final int CMD_login = 7000;
public static final int CMD_getUsers = 7001;
public static final int CMD_createMeeting = 7002;
public static final int CMD_getUserInfor = 7003;
public static final int CMD_getGroups = 7004;
public static final int CMD_getGroupMenbers = 7005;
static HttpUtl.CallBack _callback = new HttpUtl.CallBack() {
@Override
public void onRequestComplete(int cmd, String result, Object params) {
Log.i(TAG, "onRequestComplete: " + result);
DBRoot.onGetData(cmd, result);
Object[] _params = (Object[])params;
HttpUtl.CallBack callback = (HttpUtl.CallBack)(_params[0]);
Object orgs = _params[1];
if(ActivityMgr.topActivity != null && callback != null) {
ActivityMgr.topActivity.handler.post(new Runnable() {
@Override
public void run() {
if (callback != null) {
callback.onRequestComplete(cmd, result, orgs);
}
}
});
}
ActivityMgr.sendMsg(cmd, new NetPkg(result, orgs));
}
@Override
public void onRequestError(int cmd, String result, Object orgs) {
Log.e(TAG, "onRequestError: " + result);
if (orgs != null) {
((HttpUtl.CallBack) orgs).onRequestError(cmd, result, orgs);
}
UIUtl.toastI(result);
}
};
public static void login(String username, String password, HttpUtl.CallBack callBack, Object orgs) {
username = "root";
password = "12345678aa";
String url = "http://" + ip + ":" + port + "/api/login?" + "username=" + username + "&" + "password=" + password;
Object[] params = {callBack, orgs};
HttpUtl.doGetAsyn(url, _callback, CMD_login, params);
}
public static void getUserInfor(String extn, HttpUtl.CallBack callBack, Object orgs) {
String url = "http://" + ip + ":" + port + "/api/ola/agents?extn=" + extn;
Object[] params = {callBack, orgs};
HttpUtl.doGetAsyn(url, _callback, CMD_getUserInfor, params);
}
public static void getUsers(HttpUtl.CallBack callBack, Object orgs) {
String url = "http://" + ip + ":" + port + "/api/ola/agents";
Object[] params = {callBack, orgs};
HttpUtl.doGetAsyn(url, _callback, CMD_getUsers, params);
}
public static void createMeeting(String topic, String description, String members, HttpUtl.CallBack callBack, Object orgs) {
String url = "http://" + ip + ":" + port + "/api/conferences/conference/insert";
String _params = "topic=" + topic + "&description=" + description + "&members=" + members;
Object[] params = {callBack, orgs};
HttpUtl.doPostAsyn(url, _params, _callback, CMD_createMeeting, params);
}
public static void getGroups(HttpUtl.CallBack callBack, Object orgs) {
String url = "http://" + ip + ":" + port + "/api/conferences/conference/list";
Object[] params = {callBack, orgs};
HttpUtl.doGetAsyn(url, _callback, CMD_getGroups, params);
}
public static void getGroupMenbers(String task_uuid, HttpUtl.CallBack callBack, Object orgs) {
String url = "http://" + ip + ":" + port + "/api/conferences/conference/"+task_uuid;
Object[] params = {callBack, orgs};
HttpUtl.doGetAsyn(url, _callback, CMD_getGroupMenbers, params);
}
}

View File

@@ -0,0 +1,11 @@
package com.tianrun.sipcall.net;
public class NetPkg {
public String content;
public Object orgs;
public NetPkg(String content, Object orgs) {
this.content = content;
this.orgs = orgs;
}
}

View File

@@ -0,0 +1,36 @@
package com.tianrun.sipcall.ui;
import com.tianrun.sipcall.utils.CONS;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListSet;
public class ActivityMgr {
public static Map<Class, TrBaseActivity> actives = new ConcurrentHashMap<>();
public static TrBaseActivity topActivity;
public static TrBaseActivity getActivity(Class _class){
return actives.get(_class);
}
public static void onShowActivity(TrBaseActivity a) {
topActivity = a;
if(!actives.containsKey(a.getClass())) {
actives.put(a.getClass(), a);
}
}
public static void onHideActivity(TrBaseActivity a) {
actives.remove(a.getClass());
if(a == topActivity) {
topActivity = null;
}
}
public static void sendMsg(int menu, Object obj) {
for(TrBaseActivity a : actives.values()) {
CONS.SENDMESSAGETO( a.handler, menu, obj);
}
}
}

View File

@@ -0,0 +1,67 @@
package com.tianrun.sipcall.ui;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import com.tianrun.sipcall.R;
import com.tianrun.sipcall.login.MainActivity;
import java.util.List;
public class TrAdapter extends BaseAdapter {
public interface Callback {
void initCallback(Object data, int position, View prefabView, ViewGroup parent);
void clickCallback(Object data, AdapterView<?> parent, View view, int position, long id);
}
public List<Object> list = null;
private Context context;
private LayoutInflater inflater;
private int convertViewId;
private Callback callback;
public TrAdapter(Context context, int convertViewId, List<Object> list, Callback callback) {
inflater = LayoutInflater.from(context);
this.convertViewId = convertViewId;
this.list = list;
this.context = context;
this.callback = callback;
}
public List<Object> getList()
{
return list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
convertView = inflater.inflate(convertViewId, null);
callback.initCallback(getItem(position), position, convertView, parent);
return convertView;
}
}

View File

@@ -0,0 +1,34 @@
package com.tianrun.sipcall.ui;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class TrBaseActivity extends AppCompatActivity implements Handler.Callback {
public Handler handler = new Handler(this);
@Override
public boolean handleMessage(@NonNull Message msg) {
return false;
}
@Override
protected void onResume() {
super.onResume();
ActivityMgr.onShowActivity(this);
}
@Override
protected void onStop() {
super.onStop();
ActivityMgr.onHideActivity(this);
}
}

View File

@@ -0,0 +1,168 @@
package com.tianrun.sipcall.ui;
import android.content.Context;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import androidx.core.content.ContextCompat;
import com.qmuiteam.qmui.skin.QMUISkinManager;
import com.qmuiteam.qmui.widget.dialog.QMUIBottomSheet;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.tianrun.sipcall.App;
import java.util.List;
public class UIUtl {
public static void toast(String tip) {
if (ActivityMgr.topActivity == null) return;
try {
ActivityMgr.topActivity.handler.post(new Runnable() {
@Override
public void run() {
QMUITipDialog tipDialog = new QMUITipDialog.Builder(ActivityMgr.topActivity)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_NOTHING)
.setTipWord(tip)
.create();
tipDialog.show();
hideToast(tipDialog);
}
});
} catch (Exception e) {
System.out.println(e);
}
}
public static void toastI(String tip) {
if (ActivityMgr.topActivity == null) return;
try {
ActivityMgr.topActivity.handler.post(new Runnable() {
@Override
public void run() {
QMUITipDialog tipDialog = new QMUITipDialog.Builder(ActivityMgr.topActivity)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_INFO)
.setTipWord(tip)
.create();
tipDialog.show();
hideToast(tipDialog);
}
});
} catch (Exception e) {
System.out.println(e);
}
}
public static void toastS(String tip) {
if (ActivityMgr.topActivity == null) return;
try {
ActivityMgr.topActivity.handler.post(new Runnable() {
@Override
public void run() {
QMUITipDialog tipDialog = new QMUITipDialog.Builder(ActivityMgr.topActivity)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_SUCCESS)
.setTipWord(tip)
.create();
tipDialog.show();
hideToast(tipDialog);
}
});
} catch (Exception e) {
System.out.println(e);
}
}
public static void toastW(String tip) {
if (ActivityMgr.topActivity == null) return;
try {
ActivityMgr.topActivity.handler.post(new Runnable() {
@Override
public void run() {
QMUITipDialog tipDialog = new QMUITipDialog.Builder(ActivityMgr.topActivity)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_FAIL)
.setTipWord(tip)
.create();
tipDialog.show();
hideToast(tipDialog);
}
});
} catch (Exception e) {
System.out.println(e);
}
}
public static QMUITipDialog toastLoading(String tip) {
if (ActivityMgr.topActivity == null) return null;
QMUITipDialog tipDialog = new QMUITipDialog.Builder(ActivityMgr.topActivity)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord(tip)
.create();
tipDialog.show();
// hideToast(tipDialog);
return tipDialog;
}
private static void hideToast(QMUITipDialog tipDialog) {
if (ActivityMgr.topActivity == null) return;
ActivityMgr.topActivity.handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
tipDialog.dismiss();
} catch (Exception e) {
System.out.println(e);
}
}
}, 1200);
}
public static TrAdapter setList(Context context, GridView grid, int convertViewId, Object list, TrAdapter.Callback callback) {
TrAdapter adapter = new TrAdapter(context, convertViewId, (List<Object>) list, callback);
grid.setAdapter(adapter);
grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
callback.clickCallback(adapter.getItem(position), parent, view, position, id);
}
});
return adapter;
}
public static void showBottomSheetList(
CharSequence title,
List<String> items, QMUIBottomSheet.BottomListSheetBuilder.OnSheetItemClickListener onClick) {
showBottomSheetList(true, true, title, items, false, true, onClick);
}
public static void showBottomSheetList(boolean gravityCenter,
boolean addCancelBtn,
CharSequence title,
List<String> items,
boolean allowDragDismiss,
boolean withMark, QMUIBottomSheet.BottomListSheetBuilder.OnSheetItemClickListener onClick) {
QMUIBottomSheet.BottomListSheetBuilder builder = new QMUIBottomSheet.BottomListSheetBuilder(App.getContext());
builder.setGravityCenter(gravityCenter)
.setSkinManager(QMUISkinManager.defaultInstance(App.getContext()))
.setTitle(title)
.setAddCancelBtn(addCancelBtn)
.setAllowDrag(allowDragDismiss)
.setNeedRightMark(withMark)
.setOnSheetItemClickListener(new QMUIBottomSheet.BottomListSheetBuilder.OnSheetItemClickListener() {
@Override
public void onClick(QMUIBottomSheet dialog, View itemView, int position, String tag) {
dialog.dismiss();
// Toast.makeText(getActivity(), "Item " + (position + 1), Toast.LENGTH_SHORT).show();
onClick.onClick(dialog, itemView, position, tag);
}
});
if (withMark) {
builder.setCheckedIndex(40);
}
for (int i = 1; i <= items.size(); i++) {
builder.addItem(items.get(i));
}
builder.build().show();
}
}

View File

@@ -0,0 +1,166 @@
package com.tianrun.sipcall.utils;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import com.tianrun.sipcall.App;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Date;
public class CONS {
public static final int LOGIN = 200;
public static final int LOGINSHOW = 201;
public static final int CALLSTATE = 202;
public static final int MEDIASTATE = 203;
public static final int CALLDOWN = 204;
public static final int FINISH = 205;
public static final int SETSPEN = 206;
public static final int SETTEXT = 207;
public static final int INCOMINGMESSAGE = 208;//来短信了
public static final int showpic = 209;
public static final int LOGINFAILED = 230;
public static void SENDMESSAGETO(Handler handler, int menu, Object object) {
if (handler != null) {
Message.obtain(handler, menu, object).sendToTarget();
}
}
/**
* Java文件操作 获取文件扩展名
* IMG_20170905_100435.jpg.mp3-->mp3
* Created on: 2017-9-28
* Author: lyf
*/
public static String getExtensionName(String filename) {
if ((filename != null) && (filename.length() > 0)) {
int dot = filename.lastIndexOf('.');
if ((dot >-1) && (dot < (filename.length() - 1))) {
return filename.substring(dot + 1);
}
}
return filename;
}
/**
* Java文件操作 获取不带扩展名的文件名
* IMG_20170905_100435.jpg.mp3-->IMG_20170905_100435.jpg
* Created on: 2017-9-28
* Author: lyf
*/
public static String getFileNameNoEx(String filename) {
if ((filename != null) && (filename.length() > 0)) {
int dot = filename.lastIndexOf('.');
if ((dot >-1) && (dot < (filename.length()))) {
return filename.substring(0, dot);
}
}
return filename;
}
public static final int REQUEST_CODE_ASK_WRITE_SETTINGS = 101;//允许程序读取或写入系统设置
public static void requestPermission_ACTION_MANAGE_WRITE_SETTINGS(Activity c){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if( !Settings.System.canWrite(c)){
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
Uri.parse("package:" + App.getContext().getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
c.startActivityForResult(intent, REQUEST_CODE_ASK_WRITE_SETTINGS);
}else{
//有了权限,你要做什么呢?具体的动作
}
}
}
public static final int REQUEST_OVERLAY = 102;//悬浮窗口权限申请
public static void requestPermission_ACTION_MANAGE_OVERLAY_PERMISSION(Activity c) {
if (Build.VERSION.SDK_INT >= 23) {
if (!Settings.canDrawOverlays(c)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + App.getContext().getPackageName()));
c.startActivityForResult(intent, REQUEST_OVERLAY);
} else {
}
}
}
public static long forChannel(File f1,File f2) throws Exception{
long time=new Date().getTime();
int length=2097152;
FileInputStream in=new FileInputStream(f1);
FileOutputStream out=new FileOutputStream(f2);
FileChannel inC=in.getChannel();
FileChannel outC=out.getChannel();
ByteBuffer b=null;
while(true){
if(inC.position()==inC.size()){
inC.close();
outC.close();
return new Date().getTime()-time;
}
if((inC.size()-inC.position())<length){
length=(int)(inC.size()-inC.position());
}else
length=2097152;
b=ByteBuffer.allocateDirect(length);
inC.read(b);
b.flip();
outC.write(b);
outC.force(false);
}
}
public static String getFileSuffix(File f) {
String name = f.getName();
if (name != null && !"".equals(name)) {
if (name.contains(".")) {
return name.substring(name.lastIndexOf("."));
}
}
return name;
}
//防止华为机型未加入白名单时按返回键回到桌面再锁屏后几秒钟进程被杀
// public static void onBackPressed(Activity activity) {
// IntentWrapper.onBackPressed(activity);
// }
}

View File

@@ -0,0 +1,379 @@
package com.tianrun.sipcall.utils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.util.Log;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
/**
* Http请求的工具类
*
* @author suming
*
*/
public class HttpUtl {
//超时时间
private static final int TIMEOUT_IN_MILLIONS = 10000;
public interface CallBack {
void onRequestComplete(int cmd, String result, Object orgs);
void onRequestError(int cmd, String result, Object orgs);
}
public static String token;
/**
* 异步的Get请求
*
* @param urlStr
* @param callBack
*/
public static void doGetAsyn(final String urlStr, final CallBack callBack, int cmd, Object orgs) {
new Thread() {
public void run() {
try {
String result = doGet(urlStr);
if (callBack != null) {
callBack.onRequestComplete(cmd, result, orgs);
}
} catch (Exception e) {
e.printStackTrace();
if (callBack != null) {
callBack.onRequestError(cmd, e.toString(), orgs);
}
}
};
}.start();
}
/**
* 异步的Post请求
*
* @param urlStr
* @param params
* @param callBack
* @throws Exception
*/
public static void doPostAsyn(final String urlStr, final String params, final CallBack callBack, int cmd, Object orgs) {
new Thread() {
public void run() {
try {
String result = doPost(urlStr, params);
if (callBack != null) {
callBack.onRequestComplete(cmd, result, orgs);
}
} catch (Exception e) {
e.printStackTrace();
if (callBack != null) {
callBack.onRequestError(cmd, e.toString(), orgs);
}
}
};
}.start();
}
/**
* Get请求获得返回数据
*
* @param urlStr
* @return
* @throws Exception
*/
public static String doGet(String urlStr) throws Exception {
URL url = null;
HttpURLConnection conn = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
Log.i("http", "原始" + urlStr);
// String encodURL = URLEncoder.encode(urlStr, "UTF-8");
String encodURL = Uri.encode(urlStr);
encodURL = encodURL.replaceAll("%3A", ":");
encodURL = encodURL.replaceAll("%2F", "/");
encodURL = encodURL.replaceAll("%3F", "?");
encodURL = encodURL.replaceAll("%26", "&");
encodURL = encodURL.replaceAll("%3D", "=");
url = new URL(encodURL);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(TIMEOUT_IN_MILLIONS);
conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);
conn.setRequestMethod("GET");
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("charset", "utf-8");
if(token != null) {
conn.setRequestProperty("X-Auth-Token", token);
}
int retCode = conn.getResponseCode();
if (retCode == 200) {
if (token == null) {
token = conn.getHeaderField("X-Auth-Token");
}
is = conn.getInputStream();
baos = new ByteArrayOutputStream();
int len = -1;
byte[] buf = new byte[128];
while ((len = is.read(buf)) != -1) {
baos.write(buf, 0, len);
}
baos.flush();
if (baos.toString()==null||baos.toString().equals("")) {
Log.i("http", "result为空");
} else {
Log.i("http", baos.toString());
}
return baos.toString();
} else {
throw new RuntimeException(" responseCode :" + retCode);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
try {
if (baos != null)
baos.close();
} catch (IOException e) {
}
conn.disconnect();
}
// return null;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url
* 发送请求的 URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
* @throws Exception
*/
public static String doPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("charset", "utf-8");
if(token != null) {
conn.setRequestProperty("X-Auth-Token", token);
}
conn.setUseCaches(false);
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setReadTimeout(TIMEOUT_IN_MILLIONS);
conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);
if (param != null && !param.trim().equals("")) {
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
}
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
if (result .equals("{}")){
result = conn.getResponseCode()+"";
}
} catch (Exception e) {
e.printStackTrace();
Log.i("http", e.toString());
}
// 使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
if (result==null&&result.equals("")) {
Log.i("http", "result为空");
} else {
Log.i("http", result);
}
return result;
}
/**
* 使用Post上传文件
*
* @param actionUrl
* @param params
* @param files
* @return
* @throws IOException
*/
public static String post(String actionUrl, Map<String, String> params, Map<String, File> files)
throws IOException {
String BOUNDARY = java.util.UUID.randomUUID().toString();
String PREFIX = "--", LINEND = "\r\n";
String MULTIPART_FROM_DATA = "multipart/form-data";
String CHARSET = "UTF-8";
URL uri = new URL(actionUrl);
HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
conn.setReadTimeout(5 * 1000);
conn.setDoInput(true);// 允许输入
conn.setDoOutput(true);// 允许输出
conn.setUseCaches(false);
conn.setRequestMethod("POST"); // Post方式
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Charsert", "UTF-8");
conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);
if(token != null) {
conn.setRequestProperty("X-Auth-Token", token);
}
// 首先组拼文本类型的参数
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINEND);
sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);
sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
sb.append(LINEND);
sb.append(entry.getValue());
sb.append(LINEND);
}
DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
outStream.write(sb.toString().getBytes());
// 发送文件数据
if (files != null)
for (Map.Entry<String, File> file : files.entrySet()) {
StringBuilder sb1 = new StringBuilder();
sb1.append(PREFIX);
sb1.append(BOUNDARY);
sb1.append(LINEND);
sb1.append(
"Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getKey() + "\"" + LINEND);
sb1.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINEND);
sb1.append(LINEND);
outStream.write(sb1.toString().getBytes());
InputStream is = new FileInputStream(file.getValue());
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
is.close();
outStream.write(LINEND.getBytes());
}
// 请求结束标志
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
outStream.write(end_data);
outStream.flush();
// 得到响应码
int res = conn.getResponseCode();
InputStream in = conn.getInputStream();
InputStreamReader isReader = new InputStreamReader(in);
BufferedReader bufReader = new BufferedReader(isReader);
String line = null;
String data = "OK";
while ((line = bufReader.readLine()) == null)
data += line;
System.out.println(data);
if (res == 200) {
int ch;
StringBuilder sb2 = new StringBuilder();
while ((ch = in.read()) != -1) {
sb2.append((char) ch);
}
}
outStream.close();
conn.disconnect();
return in.toString();
}
/**
* 获取网落图片资源
*
* @param url
* @return
*/
public static Bitmap getHttpBitmap(String url) {
URL myFileURL;
Bitmap bitmap = null;
try {
myFileURL = new URL(url);
// 获得连接
HttpURLConnection conn = (HttpURLConnection) myFileURL.openConnection();
// 设置超时时间为6000毫秒conn.setConnectionTiem(0);表示没有时间限制
conn.setConnectTimeout(6000);
// 连接设置获得数据流
conn.setDoInput(true);
// 不使用缓存
conn.setUseCaches(false);
// 这句可有可无,没有影响
// conn.connect();
// 得到数据流
InputStream is = conn.getInputStream();
// 解析得到图片
bitmap = BitmapFactory.decodeStream(is);
// 关闭数据流
is.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return bitmap;
}
}

View File

@@ -0,0 +1,11 @@
package com.tianrun.sipcall.utils;
import android.util.Log;
public class logmy {
public static final String tag = "测试";
public static void e(String str){
Log.e(tag,str);
}
}