마이크 볼륨 설정 추가
@ -9,8 +9,8 @@ android {
|
|||||||
applicationId = 'kr.co.rito.ritosip'
|
applicationId = 'kr.co.rito.ritosip'
|
||||||
minSdkVersion 29
|
minSdkVersion 29
|
||||||
targetSdkVersion 35
|
targetSdkVersion 35
|
||||||
versionCode = 100
|
versionCode = 104
|
||||||
versionName = '1.0.0'
|
versionName = '1.0.4'
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
cFlags '-DHAVE_INTTYPES_H -lstdc++'
|
cFlags '-DHAVE_INTTYPES_H -lstdc++'
|
||||||
@ -45,6 +45,7 @@ android {
|
|||||||
// minifyEnabled false
|
// minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
|
||||||
'proguard-rules.pro'
|
'proguard-rules.pro'
|
||||||
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
android.applicationVariants.all { variant ->
|
android.applicationVariants.all { variant ->
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
android:maxSdkVersion="32" />
|
android:maxSdkVersion="32" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="28"
|
android:maxSdkVersion="32"
|
||||||
tools:ignore="ScopedStorage" />
|
tools:ignore="ScopedStorage" />
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||||
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
||||||
|
@ -29,6 +29,7 @@ module vp8.so
|
|||||||
module vp9.so
|
module vp9.so
|
||||||
module av1.so
|
module av1.so
|
||||||
module snapshot.so
|
module snapshot.so
|
||||||
|
module fakevideo.so
|
||||||
module stun.so
|
module stun.so
|
||||||
module turn.so
|
module turn.so
|
||||||
module ice.so
|
module ice.so
|
||||||
@ -37,11 +38,13 @@ module dtls_srtp.so
|
|||||||
module gzrtp.so
|
module gzrtp.so
|
||||||
module uuid.so
|
module uuid.so
|
||||||
module vumeter.so
|
module vumeter.so
|
||||||
|
module webrtc_aecm.so
|
||||||
module_app account.so
|
module_app account.so
|
||||||
module_app debug_cmd.so
|
module_app debug_cmd.so
|
||||||
module_app mwi.so
|
module_app mwi.so
|
||||||
avcodec_h264enc h264_mediacodec
|
avcodec_h264enc h264_mediacodec
|
||||||
video_fps 30
|
video_fps 30
|
||||||
|
mic_volume 20
|
||||||
evdev_device /dev/input/event0
|
evdev_device /dev/input/event0
|
||||||
opus_samplerate 48000
|
opus_samplerate 48000
|
||||||
opus_stereo no
|
opus_stereo no
|
||||||
|
@ -1785,6 +1785,18 @@ JNIEXPORT jint JNICALL Java_com_tutpro_baresip_plus_Api_call_1set_1video_1source
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_tutpro_baresip_plus_Api_call_1set_1video_1fake(
|
||||||
|
JNIEnv *env, jobject obj, jlong call)
|
||||||
|
{
|
||||||
|
(void)env;
|
||||||
|
(void)obj;
|
||||||
|
int err;
|
||||||
|
re_thread_enter();
|
||||||
|
err = video_set_source(call_video((struct call *)call), "fakevideo", NULL);
|
||||||
|
re_thread_leave();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_com_tutpro_baresip_plus_Api_call_1destroy(
|
JNIEXPORT void JNICALL Java_com_tutpro_baresip_plus_Api_call_1destroy(
|
||||||
JNIEnv *env, jobject obj, jlong call)
|
JNIEnv *env, jobject obj, jlong call)
|
||||||
{
|
{
|
||||||
@ -1808,6 +1820,36 @@ JNIEXPORT jint JNICALL Java_com_tutpro_baresip_plus_Api_cmd_1exec(
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL Java_com_tutpro_baresip_plus_Api_set_1audio_1source(JNIEnv *env, jobject obj)
|
||||||
|
{
|
||||||
|
(void)obj;
|
||||||
|
struct list *aucodecl = baresip_ausrcl();
|
||||||
|
struct le *le;
|
||||||
|
char codec_buf[256];
|
||||||
|
char *start = &(codec_buf[0]);
|
||||||
|
unsigned int left = sizeof codec_buf;
|
||||||
|
int len;
|
||||||
|
for (le = list_head(aucodecl); le != NULL; le = le->next) {
|
||||||
|
const struct ausrc *ac = le->data;
|
||||||
|
if (start == &(codec_buf[0]))
|
||||||
|
len = re_snprintf(start, left, "<%s>", ac->name);
|
||||||
|
else
|
||||||
|
len = re_snprintf(start, left, ",<%s>", ac->name);
|
||||||
|
if (len == -1) {
|
||||||
|
LOGE("failed to print codec to buffer\n");
|
||||||
|
codec_buf[0] = '\0';
|
||||||
|
return (*env)->NewStringUTF(env, codec_buf);
|
||||||
|
}
|
||||||
|
start = start + len;
|
||||||
|
left = left - len;
|
||||||
|
}
|
||||||
|
*start = '\0';
|
||||||
|
return (*env)->NewStringUTF(env, codec_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_com_tutpro_baresip_plus_Api_audio_1codecs(JNIEnv *env, jobject obj)
|
JNIEXPORT jstring JNICALL Java_com_tutpro_baresip_plus_Api_audio_1codecs(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
(void)obj;
|
(void)obj;
|
||||||
|
@ -98,6 +98,7 @@ object Api {
|
|||||||
external fun call_state(callp: Long): Int
|
external fun call_state(callp: Long): Int
|
||||||
external fun call_has_video(callp: Long): Boolean
|
external fun call_has_video(callp: Long): Boolean
|
||||||
external fun call_set_video_source(callp: Long, front: Boolean): Int
|
external fun call_set_video_source(callp: Long, front: Boolean): Int
|
||||||
|
external fun call_set_video_fake(callp: Long): Int // added by ritoseo
|
||||||
external fun call_set_video_direction(callp: Long, dir: Int)
|
external fun call_set_video_direction(callp: Long, dir: Int)
|
||||||
external fun call_set_video_mute(callp: Long, mute: Boolean) // added by ritoseo
|
external fun call_set_video_mute(callp: Long, mute: Boolean) // added by ritoseo
|
||||||
external fun call_set_media_direction(callp: Long, adir: Int, vdir: Int)
|
external fun call_set_media_direction(callp: Long, adir: Int, vdir: Int)
|
||||||
@ -113,6 +114,7 @@ object Api {
|
|||||||
|
|
||||||
external fun message_send(uap: Long, peer_uri: String, message: String, time: String): Int
|
external fun message_send(uap: Long, peer_uri: String, message: String, time: String): Int
|
||||||
|
|
||||||
|
external fun set_audio_source(): String
|
||||||
external fun audio_codecs(): String
|
external fun audio_codecs(): String
|
||||||
external fun video_codecs(): String
|
external fun video_codecs(): String
|
||||||
|
|
||||||
|
@ -35,14 +35,12 @@ import android.telecom.TelecomManager
|
|||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.util.JsonReader
|
|
||||||
import android.util.Size
|
import android.util.Size
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.annotation.ColorRes
|
import androidx.annotation.ColorRes
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
@ -63,11 +61,8 @@ import org.json.JSONObject
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.nio.ByteBuffer
|
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.time.Clock
|
|
||||||
import java.time.LocalDate
|
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.concurrent.schedule
|
import kotlin.concurrent.schedule
|
||||||
@ -269,7 +264,6 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sipReqeustReceiver = object : BroadcastReceiver() {
|
sipReqeustReceiver = object : BroadcastReceiver() {
|
||||||
fun sendContactList() {
|
fun sendContactList() {
|
||||||
val resArr : JSONArray = JSONArray()
|
val resArr : JSONArray = JSONArray()
|
||||||
@ -570,11 +564,17 @@ class BaresipService: Service() {
|
|||||||
if(param != null) {
|
if(param != null) {
|
||||||
val json = JSONObject(param)
|
val json = JSONObject(param)
|
||||||
val device_name = json.getString("device_name")
|
val device_name = json.getString("device_name")
|
||||||
|
val mic_volume = json.getString("mic_volume")
|
||||||
val display_type = json.getString("display_type")
|
val display_type = json.getString("display_type")
|
||||||
|
|
||||||
Config.replaceVariable("device_name", device_name)
|
Config.replaceVariable("device_name", device_name)
|
||||||
BaresipService.deviceName = device_name
|
BaresipService.deviceName = device_name
|
||||||
|
|
||||||
|
val mic_volume_int = mic_volume.toInt()
|
||||||
|
if(mic_volume_int >= 0 && mic_volume_int <= 24) {
|
||||||
|
Utils.setMicVolumeByMix(mic_volume_int)
|
||||||
|
}
|
||||||
|
|
||||||
Config.replaceVariable("far_view_display_id", display_type)
|
Config.replaceVariable("far_view_display_id", display_type)
|
||||||
BaresipService.farViewDisplayId = display_type.toInt()
|
BaresipService.farViewDisplayId = display_type.toInt()
|
||||||
Config.save()
|
Config.save()
|
||||||
@ -759,14 +759,28 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val scope = CoroutineScope(Dispatchers.Default)
|
val scope = CoroutineScope(Dispatchers.Default)
|
||||||
var captureCount = 0
|
var captureCount : Long = 0
|
||||||
var running = true
|
var running = true
|
||||||
|
|
||||||
val job = scope.launch {
|
val job = scope.launch {
|
||||||
println("camera capture manager is running...")
|
println("camera capture manager is running...")
|
||||||
Utils.deleteFiles("/mnt/obb", "jpg")
|
Utils.deleteFiles("/mnt/obb", "jpg")
|
||||||
var updateDate = LocalDateTime.now()
|
var updateDate = LocalDateTime.now()
|
||||||
|
var cameraState = -1
|
||||||
while (running) {
|
while (running) {
|
||||||
|
|
||||||
|
// var devices = am.getDevices(AudioManager.GET_DEVICES_INPUTS)
|
||||||
|
// for (device in devices) {
|
||||||
|
// var typeName = "모름 ${device.type}"
|
||||||
|
// if(device.type == AudioDeviceInfo.TYPE_USB_HEADSET) {
|
||||||
|
// typeName = "USB헤드셋(${device.id})"
|
||||||
|
// } else if(device.type == AudioDeviceInfo.TYPE_BUILTIN_MIC) {
|
||||||
|
// typeName = "내장마이크(${device.id})"
|
||||||
|
// }
|
||||||
|
// println("[입력장치] ${typeName} : ${device.productName}")
|
||||||
|
// }
|
||||||
|
updateAudioSourceDevice(applicationContext)
|
||||||
|
|
||||||
if(File("/mnt/obb/camera_near.rgb565.done").exists() && !File("/mnt/obb/camera_near.jpg").exists()) {
|
if(File("/mnt/obb/camera_near.rgb565.done").exists() && !File("/mnt/obb/camera_near.jpg").exists()) {
|
||||||
try {
|
try {
|
||||||
val nearBuf = Utils.readFileToByteBuffer("/mnt/obb/camera_near.rgb565")
|
val nearBuf = Utils.readFileToByteBuffer("/mnt/obb/camera_near.rgb565")
|
||||||
@ -970,25 +984,88 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
val camera1 = Utils.checkCameraConnection(0)
|
val camera1 = Utils.checkCameraConnection(0)
|
||||||
val camera2 = Utils.checkCameraConnection(1)
|
val camera2 = Utils.checkCameraConnection(1)
|
||||||
|
val prevCamera1 = Utils.propertyGet("sys.ritosip.camera1.status")
|
||||||
Utils.propertySet("sys.ritosip.camera1.status", camera1)
|
Utils.propertySet("sys.ritosip.camera1.status", camera1)
|
||||||
//call.setVideoSource(!BaresipService.cameraFront)
|
//call.setVideoSource(!BaresipService.cameraFront)
|
||||||
val prevCamera2 = Utils.propertyGet("sys.ritosip.camera2.status")
|
val prevCamera2 = Utils.propertyGet("sys.ritosip.camera2.status")
|
||||||
Utils.propertySet("sys.ritosip.camera2.status", camera2)
|
Utils.propertySet("sys.ritosip.camera2.status", camera2)
|
||||||
if(camera2 != prevCamera2) {
|
if(camera1 != "plugin" && camera2 != "plugin" && cameraState != 0) {
|
||||||
if(uas.size > 0) {
|
if(uas.size > 0) {
|
||||||
val ua = uas[0]
|
val ua = uas[0]
|
||||||
val call = ua.currentCall()
|
val call = ua.currentCall()
|
||||||
|
|
||||||
if(call != null) {
|
if(call != null) {
|
||||||
if(camera2 == "plugin") {
|
call.setVideoFake()
|
||||||
BaresipService.cameraFront = false; // Contents Input
|
cameraState = 0
|
||||||
call.setVideoSource(false)
|
|
||||||
} else {
|
|
||||||
BaresipService.cameraFront = true; // Camera Input
|
|
||||||
call.setVideoSource(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if(camera1 == "plugin" && camera2 != "plugin" && (cameraState == 0 || cameraState == 2)) {
|
||||||
|
if(uas.size > 0) {
|
||||||
|
val ua = uas[0]
|
||||||
|
val call = ua.currentCall()
|
||||||
|
|
||||||
|
if(call != null) {
|
||||||
|
Log.d(TAG, "RITO camera1 detect!")
|
||||||
|
//val process = Runtime.getRuntime().exec("ritosysc shell-order=killall android.hardware.camera.provider@2.4-service android.hardware.camera.provider@2.4-external-service cameraserver android.hardware.tv.input@1.0-service")
|
||||||
|
if(cameraState == 0) {
|
||||||
|
val process = Runtime.getRuntime()
|
||||||
|
.exec("ritosysc shell-order=killall cameraserver")
|
||||||
|
process.waitFor()
|
||||||
|
process.destroy()
|
||||||
|
delay(1500) // 1초마다 실행
|
||||||
|
}
|
||||||
|
BaresipService.cameraFront = true;
|
||||||
|
call.setVideoSource(true)
|
||||||
|
cameraState = 1
|
||||||
|
//delay(3000) // 1초마다 실행
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(camera2 == "plugin" && cameraState != 2) {
|
||||||
|
if(uas.size > 0) {
|
||||||
|
val ua = uas[0]
|
||||||
|
val call = ua.currentCall()
|
||||||
|
|
||||||
|
if(call != null) {
|
||||||
|
Log.d(TAG, "RITO camera2 detect!")
|
||||||
|
//val process = Runtime.getRuntime().exec("ritosysc shell-order=killall android.hardware.camera.provider@2.4-service android.hardware.camera.provider@2.4-external-service cameraserver android.hardware.tv.input@1.0-service")
|
||||||
|
// val process = Runtime.getRuntime().exec("ritosysc shell-order=killall cameraserver")
|
||||||
|
// process.waitFor()
|
||||||
|
// process.destroy()
|
||||||
|
// delay(1500) // 1초마다 실행
|
||||||
|
BaresipService.cameraFront = false;
|
||||||
|
call.setVideoSource(false)
|
||||||
|
cameraState = 2
|
||||||
|
//delay(3000) // 1초마다 실행
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else if(camera2 != prevCamera2) {
|
||||||
|
// if(uas.size > 0) {
|
||||||
|
// val ua = uas[0]
|
||||||
|
// val call = ua.currentCall()
|
||||||
|
//
|
||||||
|
// if(call != null) {
|
||||||
|
// cameraState = 2
|
||||||
|
// if(camera2 == "plugin") {
|
||||||
|
// BaresipService.cameraFront = false; // Contents Input
|
||||||
|
// call.setVideoSource(false)
|
||||||
|
// } else {
|
||||||
|
// BaresipService.cameraFront = true; // Camera Input
|
||||||
|
// call.setVideoSource(true)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(uas.size > 0) {
|
||||||
|
val ua = uas[0]
|
||||||
|
val call = ua.currentCall()
|
||||||
|
|
||||||
|
if(call == null) {
|
||||||
|
cameraState = -1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cameraState = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
if(BaresipService.cameraFront) {
|
if(BaresipService.cameraFront) {
|
||||||
@ -1000,15 +1077,17 @@ class BaresipService: Service() {
|
|||||||
val usbMicExist = Utils.checkUsbMicrophone()
|
val usbMicExist = Utils.checkUsbMicrophone()
|
||||||
if(usbMicExist) {
|
if(usbMicExist) {
|
||||||
Utils.propertySet("sys.ritosip.usb.microphone", "connected")
|
Utils.propertySet("sys.ritosip.usb.microphone", "connected")
|
||||||
if(audioInputDevice == "usb") {
|
// if(audioInputDevice == "usb") {
|
||||||
Utils.propertySet("sys.rito.audio.input.device", "usb")
|
// Utils.propertySet("sys.rito.audio.input.device", "usb")
|
||||||
} else {
|
// } else {
|
||||||
Utils.propertySet("sys.rito.audio.input.device", "codec")
|
// Utils.propertySet("sys.rito.audio.input.device", "codec")
|
||||||
}
|
// }
|
||||||
} else {
|
} else {
|
||||||
Utils.propertySet("sys.ritosip.usb.microphone", "disconnected")
|
Utils.propertySet("sys.ritosip.usb.microphone", "disconnected")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Utils.setAudioSourceDevice(audioInputDevice)
|
||||||
|
|
||||||
delay(100) // 1초마다 실행
|
delay(100) // 1초마다 실행
|
||||||
|
|
||||||
val now = LocalDateTime.now()
|
val now = LocalDateTime.now()
|
||||||
@ -1051,7 +1130,7 @@ class BaresipService: Service() {
|
|||||||
if (farFilePath.length > 0)
|
if (farFilePath.length > 0)
|
||||||
Utils.propertySet("sys.ritosip.far_screen_file", farFilePath)
|
Utils.propertySet("sys.ritosip.far_screen_file", farFilePath)
|
||||||
} else {
|
} else {
|
||||||
Utils.propertySet("sys.ritosip.near_screen_file", "")
|
//Utils.propertySet("sys.ritosip.near_screen_file", "")
|
||||||
Utils.propertySet("sys.ritosip.far_screen_file", "")
|
Utils.propertySet("sys.ritosip.far_screen_file", "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1068,6 +1147,54 @@ class BaresipService: Service() {
|
|||||||
Utils.propertySet("sys.ritosip.display_split_mode", BaresipService.displaySplitMode.toString())
|
Utils.propertySet("sys.ritosip.display_split_mode", BaresipService.displaySplitMode.toString())
|
||||||
Utils.propertySet("sys.ritosip.sip.total_duration", BaresipService.totalDurationSeconds.toString())
|
Utils.propertySet("sys.ritosip.sip.total_duration", BaresipService.totalDurationSeconds.toString())
|
||||||
|
|
||||||
|
// Call 중이 아닌 경우 Local Camera 화면 캡쳐
|
||||||
|
val camera1 = Utils.checkCameraConnection(0)
|
||||||
|
if(cameraState == -1) {
|
||||||
|
if(camera1 == "plugin") {
|
||||||
|
//Utils.runShellOrderSuper("killall -9 v4l2-ctl")
|
||||||
|
Utils.runShellOrderSuper("timeout 2s v4l2-ctl --device=/dev/video20 --stream-mmap=3 --stream-to=/mnt/obb/camera.rgb888 --stream-count=1 && chmod 666 /mnt/obb/camera.rgb888")
|
||||||
|
|
||||||
|
try {
|
||||||
|
val nearBuf = Utils.readFileToByteBuffer("/mnt/obb/camera.rgb888")
|
||||||
|
var bufSize = nearBuf.capacity()
|
||||||
|
var width : Int = 1280
|
||||||
|
var height : Int = 720
|
||||||
|
if(bufSize == 1280 * 720 * 3) {
|
||||||
|
width = 1280
|
||||||
|
height = 720
|
||||||
|
} else if(bufSize == 1920 * 1080 * 3) {
|
||||||
|
width = 1920
|
||||||
|
height = 1080
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bufSize > 0) {
|
||||||
|
var nearFilePath = "/mnt/obb/near_$captureCount.jpg"
|
||||||
|
Utils.saveRGB888AsJPG(
|
||||||
|
applicationContext,
|
||||||
|
nearBuf,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
nearFilePath
|
||||||
|
)
|
||||||
|
|
||||||
|
val destFile = File(nearFilePath)
|
||||||
|
destFile.setReadable(true, false)
|
||||||
|
Utils.propertySet("sys.ritosip.near_screen_file", nearFilePath)
|
||||||
|
}
|
||||||
|
} catch(e : Exception) {
|
||||||
|
//e.printStackTrace()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var nearFilePath = "/mnt/obb/near_$captureCount.jpg"
|
||||||
|
Utils.saveDrawableAsJpg(applicationContext, R.drawable.nocamera, nearFilePath)
|
||||||
|
|
||||||
|
val destFile = File(nearFilePath)
|
||||||
|
destFile.setReadable(true, false)
|
||||||
|
Utils.propertySet("sys.ritosip.near_screen_file", nearFilePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
captureCount++
|
captureCount++
|
||||||
delay(100)
|
delay(100)
|
||||||
|
|
||||||
@ -1161,7 +1288,7 @@ class BaresipService: Service() {
|
|||||||
CallHistoryNew.save()
|
CallHistoryNew.save()
|
||||||
}
|
}
|
||||||
|
|
||||||
val value = Utils.readNumberFromFile("/sdcard/Documents/sip_total_duration")
|
val value = Utils.readNumberFromFile("/sdcard/Documents/sip_total_duration.txt")
|
||||||
if(value != null) {
|
if(value != null) {
|
||||||
BaresipService.totalDurationSeconds = value
|
BaresipService.totalDurationSeconds = value
|
||||||
}
|
}
|
||||||
@ -1225,6 +1352,8 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
applyTransportConfiguration()
|
applyTransportConfiguration()
|
||||||
|
|
||||||
|
Utils.setMicVolumeByMix(BaresipService.micVolume)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"Start Content Observer" -> {
|
"Start Content Observer" -> {
|
||||||
@ -1826,7 +1955,9 @@ class BaresipService: Service() {
|
|||||||
/* Added by ritoseo */
|
/* Added by ritoseo */
|
||||||
val duration = call.duration()
|
val duration = call.duration()
|
||||||
BaresipService.totalDurationSeconds += duration
|
BaresipService.totalDurationSeconds += duration
|
||||||
Utils.saveNumberToFile("/sdcard/Documents/sip_total_duration", BaresipService.totalDurationSeconds)
|
Utils.saveNumberToFile("/sdcard/Documents/sip_total_duration.txt", BaresipService.totalDurationSeconds)
|
||||||
|
//Utils.saveNumberToFile(File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), "sip_total_duration").absolutePath, BaresipService.totalDurationSeconds)
|
||||||
|
|
||||||
/* ---------------- */
|
/* ---------------- */
|
||||||
|
|
||||||
if (!Utils.isVisible()) {
|
if (!Utils.isVisible()) {
|
||||||
@ -2267,11 +2398,15 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setCallVolume() {
|
private fun setCallVolume() {
|
||||||
|
println("Call volume setting!")
|
||||||
|
callVolume = 0
|
||||||
if (callVolume != 0)
|
if (callVolume != 0)
|
||||||
for (streamType in listOf(AudioManager.STREAM_MUSIC, AudioManager.STREAM_VOICE_CALL)) {
|
for (streamType in listOf(AudioManager.STREAM_MUSIC, AudioManager.STREAM_VOICE_CALL)) {
|
||||||
origVolume[streamType] = am.getStreamVolume(streamType)
|
origVolume[streamType] = am.getStreamVolume(streamType)
|
||||||
val maxVolume = am.getStreamMaxVolume(streamType)
|
val maxVolume = am.getStreamMaxVolume(streamType)
|
||||||
am.setStreamVolume(streamType, (callVolume * 0.1 * maxVolume).roundToInt(), 0)
|
am.setStreamVolume(streamType, (callVolume * 0.1 * maxVolume).roundToInt(), 0)
|
||||||
|
println("Orig/new/max $streamType volume is " +
|
||||||
|
"${origVolume[streamType]}/${am.getStreamVolume(streamType)}/$maxVolume")
|
||||||
Log.d(TAG, "Orig/new/max $streamType volume is " +
|
Log.d(TAG, "Orig/new/max $streamType volume is " +
|
||||||
"${origVolume[streamType]}/${am.getStreamVolume(streamType)}/$maxVolume")
|
"${origVolume[streamType]}/${am.getStreamVolume(streamType)}/$maxVolume")
|
||||||
}
|
}
|
||||||
@ -2548,6 +2683,26 @@ class BaresipService: Service() {
|
|||||||
var nearViewDisplayId = 2
|
var nearViewDisplayId = 2
|
||||||
var farViewLayout : Rect = Rect(0, 0, 1920, 1080)
|
var farViewLayout : Rect = Rect(0, 0, 1920, 1080)
|
||||||
var nearViewLayout : Rect = Rect(0, 0, 1920, 1080)
|
var nearViewLayout : Rect = Rect(0, 0, 1920, 1080)
|
||||||
|
var audioDeviceUsbId = -1
|
||||||
|
var audioDeviceCodecId = -1
|
||||||
|
var micVolume = 20
|
||||||
|
|
||||||
|
fun updateAudioSourceDevice(ctx: Context) {
|
||||||
|
val am = ctx.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
|
var devices = am.getDevices(AudioManager.GET_DEVICES_INPUTS)
|
||||||
|
var usbId = -1
|
||||||
|
var codecId = -1
|
||||||
|
for (device in devices) {
|
||||||
|
if(device.type == AudioDeviceInfo.TYPE_USB_HEADSET) {
|
||||||
|
usbId = device.id
|
||||||
|
} else if(device.type == AudioDeviceInfo.TYPE_BUILTIN_MIC) {
|
||||||
|
codecId = device.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
audioDeviceUsbId = usbId
|
||||||
|
audioDeviceCodecId = codecId
|
||||||
|
}
|
||||||
|
|
||||||
fun requestAudioFocus(ctx: Context): Boolean {
|
fun requestAudioFocus(ctx: Context): Boolean {
|
||||||
Log.d(TAG, "Requesting audio focus")
|
Log.d(TAG, "Requesting audio focus")
|
||||||
|
@ -46,6 +46,10 @@ class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir: Str
|
|||||||
return Api.call_set_video_source(callp, front)
|
return Api.call_set_video_source(callp, front)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setVideoFake(): Int {
|
||||||
|
return Api.call_set_video_fake(callp)
|
||||||
|
}
|
||||||
|
|
||||||
fun hold(): Boolean {
|
fun hold(): Boolean {
|
||||||
return Api.call_hold(callp, true) == 0
|
return Api.call_hold(callp, true) == 0
|
||||||
}
|
}
|
||||||
|
@ -211,6 +211,14 @@ object Config {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Added by ritoseo */
|
/* Added by ritoseo */
|
||||||
|
val micVolume = previousVariable("mic_volume")
|
||||||
|
if (micVolume != "") {
|
||||||
|
config = "${config}mic_volume $micVolume\n"
|
||||||
|
BaresipService.micVolume = micVolume.toInt()
|
||||||
|
} else {
|
||||||
|
config = "${config}mic_volume ${BaresipService.micVolume}\n"
|
||||||
|
}
|
||||||
|
|
||||||
for (size in defaultSizes)
|
for (size in defaultSizes)
|
||||||
videoSizes.add(size.toString())
|
videoSizes.add(size.toString())
|
||||||
/********************/
|
/********************/
|
||||||
@ -225,12 +233,15 @@ object Config {
|
|||||||
Size(videoSize.substringBefore("x").toInt(),
|
Size(videoSize.substringBefore("x").toInt(),
|
||||||
videoSize.substringAfter("x").toInt())
|
videoSize.substringAfter("x").toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BaresipService.videoSize = Size(1280, 720)
|
||||||
|
|
||||||
//BaresipService.videoSize = Size(640, 480)
|
//BaresipService.videoSize = Size(640, 480)
|
||||||
config = "${config}video_size " +
|
config = "${config}video_size " +
|
||||||
"${BaresipService.videoSize.width}x${BaresipService.videoSize.height}\n"
|
"${BaresipService.videoSize.width}x${BaresipService.videoSize.height}\n"
|
||||||
|
|
||||||
/* Added by ritoseo */
|
/* Added by ritoseo */
|
||||||
config = "${config}video_bitrate 60000000\n"
|
config = "${config}video_bitrate 100000000\n"
|
||||||
config = "${config}rtp_video_tos 184\n"
|
config = "${config}rtp_video_tos 184\n"
|
||||||
config = "${config}rtp_bandwidth 512-8192\n"
|
config = "${config}rtp_bandwidth 512-8192\n"
|
||||||
/********************/
|
/********************/
|
||||||
|
@ -11,6 +11,7 @@ import android.content.*
|
|||||||
import android.content.Intent.ACTION_CALL
|
import android.content.Intent.ACTION_CALL
|
||||||
import android.content.Intent.ACTION_DIAL
|
import android.content.Intent.ACTION_DIAL
|
||||||
import android.content.Intent.ACTION_VIEW
|
import android.content.Intent.ACTION_VIEW
|
||||||
|
import android.content.pm.PackageInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
@ -19,10 +20,8 @@ import android.media.AudioManager
|
|||||||
import android.media.MediaActionSound
|
import android.media.MediaActionSound
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.*
|
import android.os.*
|
||||||
import android.os.StrictMode.VmPolicy
|
|
||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.provider.MediaStore.Audio.Radio
|
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
@ -48,14 +47,18 @@ import androidx.lifecycle.Observer
|
|||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import com.tutpro.baresip.plus.Utils.getAppVersion
|
||||||
import com.tutpro.baresip.plus.Utils.showSnackBar
|
import com.tutpro.baresip.plus.Utils.showSnackBar
|
||||||
import com.tutpro.baresip.plus.databinding.ActivityMainBinding
|
import com.tutpro.baresip.plus.databinding.ActivityMainBinding
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.json.JSONObject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.HashMap
|
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
|
||||||
@ -138,6 +141,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
private lateinit var callStartButton: AppCompatButton
|
private lateinit var callStartButton: AppCompatButton
|
||||||
private lateinit var callHistoryButton: AppCompatButton
|
private lateinit var callHistoryButton: AppCompatButton
|
||||||
private lateinit var settingButton: AppCompatButton
|
private lateinit var settingButton: AppCompatButton
|
||||||
|
private lateinit var layoutButton: AppCompatButton
|
||||||
|
private lateinit var serverButton: AppCompatButton
|
||||||
|
private lateinit var volumeButton: AppCompatButton
|
||||||
|
private lateinit var networkButton: AppCompatButton
|
||||||
|
private lateinit var backwardButton: AppCompatButton
|
||||||
|
|
||||||
private var callHandler: Handler = Handler(Looper.getMainLooper())
|
private var callHandler: Handler = Handler(Looper.getMainLooper())
|
||||||
private var callRunnable: Runnable? = null
|
private var callRunnable: Runnable? = null
|
||||||
@ -191,6 +199,9 @@ class MainActivity : AppCompatActivity() {
|
|||||||
lateinit var navUpList : HashMap<View, View>
|
lateinit var navUpList : HashMap<View, View>
|
||||||
lateinit var navDownList : HashMap<View, View>
|
lateinit var navDownList : HashMap<View, View>
|
||||||
|
|
||||||
|
lateinit var navUpServerList : HashMap<View, View>
|
||||||
|
lateinit var navDownServerList : HashMap<View, View>
|
||||||
|
|
||||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||||
if(!isKeyboardVisible) {
|
if(!isKeyboardVisible) {
|
||||||
val currentFocusView = currentFocus
|
val currentFocusView = currentFocus
|
||||||
@ -214,6 +225,24 @@ class MainActivity : AppCompatActivity() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(navUpServerList.contains(currentFocusView)) {
|
||||||
|
val view = navUpServerList.get(currentFocusView)!!
|
||||||
|
if(view.isVisible) {
|
||||||
|
view.requestFocus()
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
if(currentFocusView == binding.btnApply) {
|
||||||
|
binding.radioDhcp.requestFocus()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(currentFocusView == binding.aorSpinner) {
|
||||||
|
callStartButton.requestFocus()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(event.keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
|
else if(event.keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
|
||||||
if(navDownList.contains(currentFocusView)) {
|
if(navDownList.contains(currentFocusView)) {
|
||||||
@ -223,12 +252,22 @@ class MainActivity : AppCompatActivity() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(navDownServerList.contains(currentFocusView)) {
|
||||||
|
val view = navDownServerList.get(currentFocusView)!!
|
||||||
|
if(view.isVisible) {
|
||||||
|
view.requestFocus()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if(event.keyCode == KeyEvent.KEYCODE_ENTER) {
|
} else if(event.keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||||
if(currentFocusView == binding.editIp ||
|
if(currentFocusView == binding.editIp ||
|
||||||
currentFocusView == binding.editGateway ||
|
currentFocusView == binding.editGateway ||
|
||||||
currentFocusView == binding.editNetmask ||
|
currentFocusView == binding.editNetmask ||
|
||||||
currentFocusView == binding.editDns) {
|
currentFocusView == binding.editDns ||
|
||||||
|
currentFocusView == binding.editDisplayName ||
|
||||||
|
currentFocusView == binding.editSipId ||
|
||||||
|
currentFocusView == binding.editSipPassword
|
||||||
|
) {
|
||||||
if(imm.isActive) {
|
if(imm.isActive) {
|
||||||
imm.showSoftInput(currentFocusView, InputMethodManager.SHOW_IMPLICIT)
|
imm.showSoftInput(currentFocusView, InputMethodManager.SHOW_IMPLICIT)
|
||||||
imm.restartInput(currentFocusView)
|
imm.restartInput(currentFocusView)
|
||||||
@ -242,6 +281,9 @@ class MainActivity : AppCompatActivity() {
|
|||||||
if(navUpList.contains(currentFocusView) || navDownList.contains(currentFocusView)) {
|
if(navUpList.contains(currentFocusView) || navDownList.contains(currentFocusView)) {
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
|
if(navUpServerList.contains(currentFocusView) || navDownServerList.contains(currentFocusView)) {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
|
||||||
if(found) {
|
if(found) {
|
||||||
return true
|
return true
|
||||||
@ -253,6 +295,12 @@ class MainActivity : AppCompatActivity() {
|
|||||||
currentFocusView == binding.editDns) {
|
currentFocusView == binding.editDns) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(currentFocusView == binding.editDisplayName ||
|
||||||
|
currentFocusView == binding.editSipId ||
|
||||||
|
currentFocusView == binding.editSipPassword) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -389,6 +437,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
setupKeyboardVisibilityListener()
|
setupKeyboardVisibilityListener()
|
||||||
|
|
||||||
|
Utils.propertySet("sys.ritosip.version", getAppVersion(this))
|
||||||
|
|
||||||
// Must be done after view has been created
|
// Must be done after view has been created
|
||||||
this.setShowWhenLocked(true)
|
this.setShowWhenLocked(true)
|
||||||
this.setTurnScreenOn( true)
|
this.setTurnScreenOn( true)
|
||||||
@ -453,10 +503,213 @@ class MainActivity : AppCompatActivity() {
|
|||||||
// binding.baseButtonLayout.visibility = View.INVISIBLE
|
// binding.baseButtonLayout.visibility = View.INVISIBLE
|
||||||
// binding.mainActivityLayout.visibility = View.INVISIBLE
|
// binding.mainActivityLayout.visibility = View.INVISIBLE
|
||||||
// binding.defaultLayout.visibility = View.INVISIBLE
|
// binding.defaultLayout.visibility = View.INVISIBLE
|
||||||
|
|
||||||
|
// binding.networkSettingLayout.visibility = View.VISIBLE
|
||||||
|
// binding.radioDhcp.requestFocus()
|
||||||
|
|
||||||
|
binding.settingLayout.visibility = View.VISIBLE
|
||||||
|
binding.dialogButtonLayout.requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
networkButton = binding.dialogButtonNetwork
|
||||||
|
networkButton.setOnClickListener {
|
||||||
|
binding.networkSettingLayout.bringToFront()
|
||||||
binding.networkSettingLayout.visibility = View.VISIBLE
|
binding.networkSettingLayout.visibility = View.VISIBLE
|
||||||
binding.radioDhcp.requestFocus()
|
binding.radioDhcp.requestFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layoutButton = binding.dialogButtonLayout
|
||||||
|
layoutButton.setOnClickListener {
|
||||||
|
binding.layoutSettingLayout.bringToFront()
|
||||||
|
binding.layoutSettingLayout.visibility = View.VISIBLE
|
||||||
|
var splitMode = Utils.propertyGet("sys.ritosip.display_split_mode")
|
||||||
|
if(splitMode == "2") {
|
||||||
|
binding.layoutType2.requestFocus()
|
||||||
|
} else if(splitMode == "3") {
|
||||||
|
binding.layoutType3.requestFocus()
|
||||||
|
} else if(splitMode == "4") {
|
||||||
|
binding.layoutType4.requestFocus()
|
||||||
|
} else if(splitMode == "5") {
|
||||||
|
binding.layoutType5.requestFocus()
|
||||||
|
} else if(splitMode == "6") {
|
||||||
|
binding.layoutType6.requestFocus()
|
||||||
|
} else if(splitMode == "7") {
|
||||||
|
binding.layoutType7.requestFocus()
|
||||||
|
} else if(splitMode == "8") {
|
||||||
|
binding.layoutType8.requestFocus()
|
||||||
|
} else if(splitMode == "9") {
|
||||||
|
binding.layoutType9.requestFocus()
|
||||||
|
} else if(splitMode == "10") {
|
||||||
|
binding.layoutType10.requestFocus()
|
||||||
|
} else {
|
||||||
|
binding.layoutType1.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.layoutType1.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout1\"}")
|
||||||
|
}
|
||||||
|
binding.layoutType2.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout2\"}")
|
||||||
|
}
|
||||||
|
binding.layoutType3.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout3\"}")
|
||||||
|
}
|
||||||
|
binding.layoutType4.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout4\"}")
|
||||||
|
}
|
||||||
|
binding.layoutType5.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout5\"}")
|
||||||
|
}
|
||||||
|
binding.layoutType6.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout6\"}")
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.layoutType7.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout7\"}")
|
||||||
|
}
|
||||||
|
binding.layoutType8.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout8\"}")
|
||||||
|
}
|
||||||
|
binding.layoutType9.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout9\"}")
|
||||||
|
}
|
||||||
|
binding.layoutType10.setOnClickListener {
|
||||||
|
sendSettingByBroadcast("layout_setting", "{\"layout\":\"layout10\"}")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
binding.dialogButtonLayoutInCall.setOnClickListener {
|
||||||
|
binding.layoutSettingLayout.bringToFront()
|
||||||
|
binding.layoutSettingLayout.visibility = View.VISIBLE
|
||||||
|
var splitMode = Utils.propertyGet("sys.ritosip.display_split_mode")
|
||||||
|
if(splitMode == "2") {
|
||||||
|
binding.layoutType2.requestFocus()
|
||||||
|
} else if(splitMode == "3") {
|
||||||
|
binding.layoutType3.requestFocus()
|
||||||
|
} else if(splitMode == "4") {
|
||||||
|
binding.layoutType4.requestFocus()
|
||||||
|
} else if(splitMode == "5") {
|
||||||
|
binding.layoutType5.requestFocus()
|
||||||
|
} else if(splitMode == "6") {
|
||||||
|
binding.layoutType6.requestFocus()
|
||||||
|
} else if(splitMode == "7") {
|
||||||
|
binding.layoutType7.requestFocus()
|
||||||
|
} else if(splitMode == "8") {
|
||||||
|
binding.layoutType8.requestFocus()
|
||||||
|
} else if(splitMode == "9") {
|
||||||
|
binding.layoutType9.requestFocus()
|
||||||
|
} else if(splitMode == "10") {
|
||||||
|
binding.layoutType10.requestFocus()
|
||||||
|
} else {
|
||||||
|
binding.layoutType1.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serverButton = binding.dialogButtonServer
|
||||||
|
serverButton.setOnClickListener {
|
||||||
|
binding.serverSettingLayout.bringToFront()
|
||||||
|
binding.serverSettingLayout.visibility = View.VISIBLE
|
||||||
|
binding.editDisplayName.setText(Utils.propertyGet("sys.ritosip.account.display_name"))
|
||||||
|
binding.editSipId.setText(Utils.propertyGet("sys.ritosip.account.account_name"))
|
||||||
|
binding.editSipServer.setText(Utils.propertyGet("sys.ritosip.account.server_address"))
|
||||||
|
var transport = Utils.propertyGet("sys.ritosip.account.prefer_transport")
|
||||||
|
if(transport == "tcp") {
|
||||||
|
binding.radioTransportTcp.isChecked = true
|
||||||
|
} else if(transport == "tls") {
|
||||||
|
binding.radioTransportTls.isChecked = true
|
||||||
|
} else {
|
||||||
|
binding.radioTransportUdp.isChecked = true
|
||||||
|
}
|
||||||
|
var encryption = Utils.propertyGet("sys.ritosip.account.media_encryption")
|
||||||
|
if(encryption == "srtp") {
|
||||||
|
binding.radioEncryptSrtp.isChecked = true
|
||||||
|
} else {
|
||||||
|
binding.radioEncryptNone.isChecked = true
|
||||||
|
}
|
||||||
|
binding.editDisplayName.requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
volumeButton = binding.dialogButtonVolume
|
||||||
|
volumeButton.setOnClickListener {
|
||||||
|
binding.volumeSettingLayout.bringToFront()
|
||||||
|
binding.volumeSettingLayout.visibility = View.VISIBLE
|
||||||
|
binding.seekbarMicVolume.requestFocus()
|
||||||
|
|
||||||
|
binding.seekbarMicVolume.progress = BaresipService.micVolume
|
||||||
|
val currentValue = binding.seekbarMicVolume.progress
|
||||||
|
binding.textMicVolume.setText(currentValue.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.dialogButtonVolumeInCall.setOnClickListener {
|
||||||
|
binding.volumeSettingLayout.bringToFront()
|
||||||
|
binding.volumeSettingLayout.visibility = View.VISIBLE
|
||||||
|
binding.seekbarMicVolume.requestFocus()
|
||||||
|
|
||||||
|
binding.seekbarMicVolume.progress = BaresipService.micVolume
|
||||||
|
val currentValue = binding.seekbarMicVolume.progress
|
||||||
|
binding.textMicVolume.setText(currentValue.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.seekbarMicVolume.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
|
||||||
|
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
|
||||||
|
// progress: 현재 값
|
||||||
|
// fromUser: 사용자가 직접 움직였는지 여부
|
||||||
|
val currentValue = progress
|
||||||
|
println("현재 값: $currentValue")
|
||||||
|
binding.textMicVolume.setText(currentValue.toString())
|
||||||
|
Utils.setMicVolumeByMix(currentValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartTrackingTouch(seekBar: SeekBar?) {
|
||||||
|
// 터치 시작 시 호출
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopTrackingTouch(seekBar: SeekBar?) {
|
||||||
|
// 터치 끝날 때 호출
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
binding.btnDoneVolume.setOnClickListener {
|
||||||
|
binding.volumeSettingLayout.visibility = View.INVISIBLE
|
||||||
|
if(binding.settingLayout.visibility == View.VISIBLE) {
|
||||||
|
binding.dialogButtonVolume.requestFocus()
|
||||||
|
} else if(binding.settingLayoutInCall.visibility == View.VISIBLE) {
|
||||||
|
binding.dialogButtonVolumeInCall.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backwardButton = binding.dialogButtonBackward
|
||||||
|
backwardButton.setOnClickListener {
|
||||||
|
if(binding.settingLayout.visibility == View.VISIBLE) {
|
||||||
|
binding.settingLayout.visibility = View.INVISIBLE
|
||||||
|
binding.settingBtn.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.dialogButtonHangUp.setOnClickListener {
|
||||||
|
if(binding.settingLayoutInCall.visibility == View.VISIBLE) {
|
||||||
|
hangupButton.performClick()
|
||||||
|
binding.settingLayoutInCall.visibility = View.INVISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.dialogButtonBackwardInCall.setOnClickListener {
|
||||||
|
if(binding.settingLayoutInCall.visibility == View.VISIBLE) {
|
||||||
|
binding.settingLayoutInCall.visibility = View.INVISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.layoutBackward.setOnClickListener {
|
||||||
|
binding.layoutSettingLayout.visibility = View.INVISIBLE
|
||||||
|
if(binding.settingLayout.visibility == View.VISIBLE) {
|
||||||
|
binding.dialogButtonLayout.requestFocus()
|
||||||
|
} else if(binding.settingLayoutInCall.visibility == View.VISIBLE) {
|
||||||
|
binding.dialogButtonLayoutInCall.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BaresipService.supportedCameras = Utils.supportedCameras(applicationContext).isNotEmpty()
|
BaresipService.supportedCameras = Utils.supportedCameras(applicationContext).isNotEmpty()
|
||||||
|
|
||||||
@ -530,12 +783,87 @@ class MainActivity : AppCompatActivity() {
|
|||||||
showCustomToast(applicationContext, "STATIC 적용되었습니다.")
|
showCustomToast(applicationContext, "STATIC 적용되었습니다.")
|
||||||
binding.networkSettingLayout.visibility = View.INVISIBLE
|
binding.networkSettingLayout.visibility = View.INVISIBLE
|
||||||
}
|
}
|
||||||
|
binding.dialogButtonNetwork.requestFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
binding.btnCancel.setOnClickListener { _ ->
|
binding.btnCancel.setOnClickListener { _ ->
|
||||||
binding.networkSettingLayout.visibility = View.INVISIBLE
|
binding.networkSettingLayout.visibility = View.INVISIBLE
|
||||||
|
binding.dialogButtonNetwork.requestFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
binding.btnApplyServer.setOnClickListener { _ ->
|
||||||
|
showCustomToast(applicationContext, "적용되었습니다.")
|
||||||
|
var param : JSONObject = JSONObject()
|
||||||
|
param.put("display_name", binding.editDisplayName.text)
|
||||||
|
param.put("account_name", binding.editSipId.text)
|
||||||
|
var password = binding.editSipPassword.text.toString()
|
||||||
|
if(password.isEmpty()) {
|
||||||
|
if (File(filesDir.absolutePath + "/accounts").exists()) {
|
||||||
|
val accounts = String(
|
||||||
|
Utils.getFileContents(filesDir.absolutePath + "/accounts")!!,
|
||||||
|
Charsets.UTF_8
|
||||||
|
).lines().toMutableList()
|
||||||
|
|
||||||
|
password = getPassword(accounts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param.put("password", password)
|
||||||
|
param.put("server_address", binding.editSipServer.text)
|
||||||
|
var transport = "udp"
|
||||||
|
if(binding.radioTransportTcp.isChecked) {
|
||||||
|
transport = "tcp"
|
||||||
|
} else if(binding.radioTransportTls.isChecked) {
|
||||||
|
transport = "tls"
|
||||||
|
}
|
||||||
|
param.put("transport", transport)
|
||||||
|
var encrypt = "none"
|
||||||
|
if(binding.radioEncryptSrtp.isChecked) {
|
||||||
|
encrypt = "srtpo"
|
||||||
|
}
|
||||||
|
param.put("media_encryption", encrypt)
|
||||||
|
println("PARAM >> " + param.toString())
|
||||||
|
sendSettingByBroadcast("set_account", param.toString())
|
||||||
|
binding.serverSettingLayout.visibility = View.INVISIBLE
|
||||||
|
binding.dialogButtonServer.requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.btnCancelServer.setOnClickListener { _ ->
|
||||||
|
binding.serverSettingLayout.visibility = View.INVISIBLE
|
||||||
|
binding.dialogButtonServer.requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
navUpServerList = HashMap<View, View>()
|
||||||
|
navDownServerList = HashMap<View, View>()
|
||||||
|
|
||||||
|
navUpServerList.put(binding.editDisplayName, binding.btnApplyServer)
|
||||||
|
navUpServerList.put(binding.editSipId, binding.editDisplayName)
|
||||||
|
navUpServerList.put(binding.editSipPassword, binding.editSipId)
|
||||||
|
navUpServerList.put(binding.editSipServer, binding.editSipPassword)
|
||||||
|
navUpServerList.put(binding.radioTransportUdp, binding.editSipServer)
|
||||||
|
navUpServerList.put(binding.radioTransportTcp, binding.editSipServer)
|
||||||
|
navUpServerList.put(binding.radioTransportTls, binding.editSipServer)
|
||||||
|
navUpServerList.put(binding.radioEncryptNone, binding.radioTransportUdp)
|
||||||
|
navUpServerList.put(binding.radioEncryptSrtp, binding.radioTransportUdp)
|
||||||
|
navUpServerList.put(binding.btnApplyServer, binding.radioEncryptNone)
|
||||||
|
navUpServerList.put(binding.btnCancelServer, binding.radioEncryptNone)
|
||||||
|
//navUpList.put(binding.btnApply, binding.radioDhcp)
|
||||||
|
|
||||||
|
navDownServerList.put(binding.editDisplayName, binding.editSipId)
|
||||||
|
navDownServerList.put(binding.editSipId, binding.editSipPassword)
|
||||||
|
navDownServerList.put(binding.editSipPassword, binding.editSipServer)
|
||||||
|
navDownServerList.put(binding.editSipServer, binding.radioTransportUdp)
|
||||||
|
navDownServerList.put(binding.radioTransportUdp, binding.radioEncryptNone)
|
||||||
|
navDownServerList.put(binding.radioTransportTcp, binding.radioEncryptNone)
|
||||||
|
navDownServerList.put(binding.radioTransportTls, binding.radioEncryptNone)
|
||||||
|
navDownServerList.put(binding.radioEncryptNone, binding.btnApplyServer)
|
||||||
|
navDownServerList.put(binding.radioEncryptSrtp, binding.btnApplyServer)
|
||||||
|
navDownServerList.put(binding.btnApplyServer, binding.editDisplayName)
|
||||||
|
navDownServerList.put(binding.btnCancelServer, binding.editDisplayName)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
updateFieldsVisibility()
|
updateFieldsVisibility()
|
||||||
|
|
||||||
val radioGroup = findViewById<RadioGroup>(R.id.radioGroup)
|
val radioGroup = findViewById<RadioGroup>(R.id.radioGroup)
|
||||||
@ -1179,11 +1507,12 @@ class MainActivity : AppCompatActivity() {
|
|||||||
else
|
else
|
||||||
getString(R.string.audio_permissions)
|
getString(R.string.audio_permissions)
|
||||||
) { requestPermissionsLauncher.launch(permissions) }
|
) { requestPermissionsLauncher.launch(permissions) }
|
||||||
else
|
// else
|
||||||
startBaresip()
|
// startBaresip()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startBaresip()
|
||||||
addVideoLayoutViews()
|
addVideoLayoutViews()
|
||||||
|
|
||||||
if (!BaresipService.isServiceRunning) {
|
if (!BaresipService.isServiceRunning) {
|
||||||
@ -1192,7 +1521,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
Utils.getFileContents(filesDir.absolutePath + "/accounts")!!,
|
Utils.getFileContents(filesDir.absolutePath + "/accounts")!!,
|
||||||
Charsets.UTF_8
|
Charsets.UTF_8
|
||||||
).lines().toMutableList()
|
).lines().toMutableList()
|
||||||
askPasswords(accounts)
|
//askPasswords(accounts)
|
||||||
} else {
|
} else {
|
||||||
// Baresip is started for the first time
|
// Baresip is started for the first time
|
||||||
requestPermissionsLauncher.launch(permissions)
|
requestPermissionsLauncher.launch(permissions)
|
||||||
@ -1201,6 +1530,14 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
} // OnCreate
|
} // OnCreate
|
||||||
|
|
||||||
|
fun sendSettingByBroadcast(req : String, param : String) {
|
||||||
|
val responseIntent = Intent("kr.co.rito.ritosip.REQUEST")
|
||||||
|
responseIntent.putExtra("request", req)
|
||||||
|
responseIntent.putExtra("param", param)
|
||||||
|
responseIntent.setPackage("kr.co.rito.ritosip");
|
||||||
|
sendBroadcast(responseIntent)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
Log.d(TAG, "Main onStart")
|
Log.d(TAG, "Main onStart")
|
||||||
@ -2055,6 +2392,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
hangupButton.performClick()
|
hangupButton.performClick()
|
||||||
}
|
}
|
||||||
videoLayout.addView(hb)
|
videoLayout.addView(hb)
|
||||||
|
hb.visibility = View.INVISIBLE // by ritoseo
|
||||||
|
|
||||||
// Info Button
|
// Info Button
|
||||||
val ib = ImageButton(this)
|
val ib = ImageButton(this)
|
||||||
@ -2354,13 +2692,50 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
when (event?.scanCode) {
|
when (event?.scanCode) {
|
||||||
SCANCODE_OPTION -> {
|
SCANCODE_OPTION -> {
|
||||||
val dialog = findViewById<FrameLayout>(R.id.dialogLayout)
|
// val dialog = findViewById<FrameLayout>(R.id.dialogLayout)
|
||||||
if(dialog.isVisible) {
|
// if(dialog.isVisible) {
|
||||||
dialog.visibility = View.INVISIBLE
|
// dialog.visibility = View.INVISIBLE
|
||||||
|
// } else {
|
||||||
|
// dialog.visibility = View.VISIBLE
|
||||||
|
// findViewById<AppCompatButton>(R.id.dialogButtonImg1).requestFocus()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// val dialog = findViewById<FrameLayout>(R.id.settingLayout)
|
||||||
|
// if (dialog.isVisible) {
|
||||||
|
// dialog.visibility = View.INVISIBLE
|
||||||
|
// } else {
|
||||||
|
// dialog.bringToFront()
|
||||||
|
// dialog.visibility = View.VISIBLE
|
||||||
|
// findViewById<AppCompatButton>(R.id.dialogButtonLayout).requestFocus()
|
||||||
|
// }
|
||||||
|
if(binding.layoutSettingLayout.visibility == View.VISIBLE ||
|
||||||
|
binding.networkSettingLayout.visibility == View.VISIBLE ||
|
||||||
|
binding.serverSettingLayout.visibility == View.VISIBLE ||
|
||||||
|
binding.volumeSettingLayout.visibility == View.VISIBLE)
|
||||||
|
return true
|
||||||
|
|
||||||
|
if (Call.inCall()) {
|
||||||
|
val dialog = findViewById<FrameLayout>(R.id.settingLayoutInCall)
|
||||||
|
if (dialog.isVisible) {
|
||||||
|
dialog.visibility = View.INVISIBLE
|
||||||
|
println("settingLayoutInCall 비활성화")
|
||||||
|
} else {
|
||||||
|
dialog.bringToFront()
|
||||||
|
dialog.visibility = View.VISIBLE
|
||||||
|
findViewById<AppCompatButton>(R.id.dialogButtonLayoutInCall).requestFocus()
|
||||||
|
println("settingLayoutInCall 활성화")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dialog.visibility = View.VISIBLE
|
val dialog = findViewById<FrameLayout>(R.id.settingLayout)
|
||||||
findViewById<AppCompatButton>(R.id.dialogButtonImg1).requestFocus()
|
if (dialog.isVisible) {
|
||||||
|
dialog.visibility = View.INVISIBLE
|
||||||
|
} else {
|
||||||
|
dialog.bringToFront()
|
||||||
|
dialog.visibility = View.VISIBLE
|
||||||
|
findViewById<AppCompatButton>(R.id.dialogButtonLayout).requestFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// val dialog = findViewById<FrameLayout>(R.id.dialogBase)
|
// val dialog = findViewById<FrameLayout>(R.id.dialogBase)
|
||||||
// val customButton = LayoutInflater.from(this).inflate(R.layout.image_button, null)
|
// val customButton = LayoutInflater.from(this).inflate(R.layout.image_button, null)
|
||||||
// dialog.addView(customButton)
|
// dialog.addView(customButton)
|
||||||
@ -3097,6 +3472,19 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getPassword(accounts: MutableList<String>) : String {
|
||||||
|
if (accounts.isNotEmpty()) {
|
||||||
|
val account = accounts.removeAt(0)
|
||||||
|
val params = account.substringAfter(">")
|
||||||
|
if ((Utils.paramValue(params, "auth_user") != "") &&
|
||||||
|
(Utils.paramValue(params, "auth_pass") != "")) {
|
||||||
|
return Utils.paramValue(params, "auth_pass").trim('"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
private fun askPasswords(accounts: MutableList<String>) {
|
private fun askPasswords(accounts: MutableList<String>) {
|
||||||
if (accounts.isNotEmpty()) {
|
if (accounts.isNotEmpty()) {
|
||||||
val account = accounts.removeAt(0)
|
val account = accounts.removeAt(0)
|
||||||
@ -3315,8 +3703,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
callVideoButton.visibility = View.INVISIBLE
|
callVideoButton.visibility = View.INVISIBLE
|
||||||
callVideoButton.isEnabled = false
|
callVideoButton.isEnabled = false
|
||||||
switchVideoLayout(true)
|
switchVideoLayout(true)
|
||||||
hangupButton.visibility = View.VISIBLE
|
hangupButton.visibility = View.INVISIBLE
|
||||||
hangupButton.isEnabled = true
|
hangupButton.isEnabled = false
|
||||||
if (Build.VERSION.SDK_INT < 31) {
|
if (Build.VERSION.SDK_INT < 31) {
|
||||||
Log.d(TAG, "Setting audio mode to MODE_IN_COMMUNICATION")
|
Log.d(TAG, "Setting audio mode to MODE_IN_COMMUNICATION")
|
||||||
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||||
@ -3470,7 +3858,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
//callVideoButton.visibility = View.VISIBLE
|
//callVideoButton.visibility = View.VISIBLE
|
||||||
callVideoButton.visibility = View.INVISIBLE // modified by ritoseo
|
callVideoButton.visibility = View.INVISIBLE // modified by ritoseo
|
||||||
callVideoButton.isEnabled = true
|
callVideoButton.isEnabled = true
|
||||||
|
|
||||||
|
binding.callBackground.visibility = View.GONE
|
||||||
hangupButton.visibility = View.INVISIBLE
|
hangupButton.visibility = View.INVISIBLE
|
||||||
|
binding.callBackground.visibility = View.GONE
|
||||||
answerButton.visibility = View.INVISIBLE
|
answerButton.visibility = View.INVISIBLE
|
||||||
answerVideoButton.visibility = View.INVISIBLE
|
answerVideoButton.visibility = View.INVISIBLE
|
||||||
rejectButton.visibility = View.INVISIBLE
|
rejectButton.visibility = View.INVISIBLE
|
||||||
@ -3501,8 +3892,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
securityButton.visibility = View.INVISIBLE
|
securityButton.visibility = View.INVISIBLE
|
||||||
diverter.visibility = View.GONE
|
diverter.visibility = View.GONE
|
||||||
callButton.visibility = View.INVISIBLE
|
callButton.visibility = View.INVISIBLE
|
||||||
hangupButton.visibility = View.VISIBLE
|
|
||||||
hangupButton.isEnabled = true
|
binding.callBackground.visibility = View.VISIBLE
|
||||||
|
hangupButton.visibility = View.INVISIBLE
|
||||||
|
hangupButton.isEnabled = false
|
||||||
answerButton.visibility = View.INVISIBLE
|
answerButton.visibility = View.INVISIBLE
|
||||||
answerVideoButton.visibility = View.INVISIBLE
|
answerVideoButton.visibility = View.INVISIBLE
|
||||||
rejectButton.visibility = View.INVISIBLE
|
rejectButton.visibility = View.INVISIBLE
|
||||||
@ -3528,6 +3921,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
callButton.visibility = View.INVISIBLE
|
callButton.visibility = View.INVISIBLE
|
||||||
callVideoButton.visibility = View.INVISIBLE
|
callVideoButton.visibility = View.INVISIBLE
|
||||||
switchVideoLayout(true)
|
switchVideoLayout(true)
|
||||||
|
|
||||||
|
binding.callBackground.visibility = View.GONE
|
||||||
hangupButton.visibility = View.INVISIBLE
|
hangupButton.visibility = View.INVISIBLE
|
||||||
answerButton.visibility = View.VISIBLE
|
answerButton.visibility = View.VISIBLE
|
||||||
answerButton.isEnabled = true
|
answerButton.isEnabled = true
|
||||||
@ -3603,8 +3998,9 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
switchVideoLayout(true)
|
switchVideoLayout(true)
|
||||||
|
|
||||||
hangupButton.visibility = View.VISIBLE
|
binding.callBackground.visibility = View.VISIBLE
|
||||||
hangupButton.isEnabled = true
|
hangupButton.visibility = View.INVISIBLE
|
||||||
|
hangupButton.isEnabled = false
|
||||||
answerButton.visibility = View.INVISIBLE
|
answerButton.visibility = View.INVISIBLE
|
||||||
answerVideoButton.visibility = View.INVISIBLE
|
answerVideoButton.visibility = View.INVISIBLE
|
||||||
rejectButton.visibility = View.INVISIBLE
|
rejectButton.visibility = View.INVISIBLE
|
||||||
|
@ -14,6 +14,8 @@ import android.graphics.Bitmap.createScaledBitmap
|
|||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
import android.hardware.camera2.CameraAccessException
|
import android.hardware.camera2.CameraAccessException
|
||||||
import android.hardware.camera2.CameraCharacteristics
|
import android.hardware.camera2.CameraCharacteristics
|
||||||
import android.hardware.camera2.CameraManager
|
import android.hardware.camera2.CameraManager
|
||||||
@ -49,6 +51,9 @@ import androidx.lifecycle.Lifecycle
|
|||||||
import androidx.lifecycle.ProcessLifecycleOwner
|
import androidx.lifecycle.ProcessLifecycleOwner
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import java.net.Inet4Address
|
import java.net.Inet4Address
|
||||||
@ -1175,6 +1180,62 @@ object Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun rgb888ToBitmap(rgbData: ByteArray, width: Int, height: Int): Bitmap? {
|
||||||
|
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||||
|
val pixels = IntArray(width * height)
|
||||||
|
for (i in pixels.indices) {
|
||||||
|
val b = rgbData[i * 3].toInt() and 0xFF
|
||||||
|
val g = rgbData[i * 3 + 1].toInt() and 0xFF
|
||||||
|
val r = rgbData[i * 3 + 2].toInt() and 0xFF
|
||||||
|
pixels[i] = 0xFF shl 24 or (r shl 16) or (g shl 8) or b
|
||||||
|
}
|
||||||
|
bitmap.setPixels(pixels, 0, width, 0, 0, width, height)
|
||||||
|
return bitmap
|
||||||
|
}
|
||||||
|
fun saveRGB888AsJPG(context: Context, rgb565Data: ByteBuffer, width: Int, height: Int, fileName: String) {
|
||||||
|
// RGB565 포맷의 빈 Bitmap 생성
|
||||||
|
val bitmap = rgb888ToBitmap(rgb565Data.array(), width, height)
|
||||||
|
if(bitmap == null)
|
||||||
|
return
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 저장할 파일 경로 설정
|
||||||
|
val file = File(fileName)
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileOutputStream(file).use { fos ->
|
||||||
|
// Bitmap을 JPG 형식으로 저장 (품질 90%)
|
||||||
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)
|
||||||
|
fos.flush()
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
} catch(e: java.lang.Exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveDrawableAsJpg(context: Context, drawableResId: Int, filename: String): Boolean {
|
||||||
|
val drawable: Drawable? = ContextCompat.getDrawable(context, drawableResId)
|
||||||
|
if (drawable == null || drawable !is BitmapDrawable) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val bitmap: Bitmap = drawable.bitmap
|
||||||
|
|
||||||
|
val file = File(filename)
|
||||||
|
return try {
|
||||||
|
FileOutputStream(file).use { out ->
|
||||||
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)
|
||||||
|
}
|
||||||
|
true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun copyFile(sourcePath: String, destinationPath: String): Boolean {
|
fun copyFile(sourcePath: String, destinationPath: String): Boolean {
|
||||||
return try {
|
return try {
|
||||||
FileInputStream(sourcePath).use { input ->
|
FileInputStream(sourcePath).use { input ->
|
||||||
@ -1259,7 +1320,7 @@ object Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setAudioSourceDevice(dev : String) {
|
fun setAudioSourceDeviceV1(dev : String) {
|
||||||
propertySet("sys.rito.audio.input.device", dev)
|
propertySet("sys.rito.audio.input.device", dev)
|
||||||
//val process = Runtime.getRuntime().exec("ritosysc shell-order=killall audioserver")
|
//val process = Runtime.getRuntime().exec("ritosysc shell-order=killall audioserver")
|
||||||
val process = Runtime.getRuntime().exec("ritosysc shell-order=killall android.hardware.audio.service")
|
val process = Runtime.getRuntime().exec("ritosysc shell-order=killall android.hardware.audio.service")
|
||||||
@ -1267,6 +1328,22 @@ object Utils {
|
|||||||
process.destroy()
|
process.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setAudioSourceDevice(dev : String) {
|
||||||
|
propertySet("sys.ritosip.audio.input.device", dev)
|
||||||
|
if(dev == "usb") {
|
||||||
|
if(BaresipService.audioDeviceUsbId == -1) {
|
||||||
|
propertySet("sys.ritosip.audio.source", BaresipService.audioDeviceCodecId.toString())
|
||||||
|
propertySet("sys.ritosip.audio.source.volume", "0")
|
||||||
|
} else {
|
||||||
|
propertySet("sys.ritosip.audio.source", BaresipService.audioDeviceUsbId.toString())
|
||||||
|
propertySet("sys.ritosip.audio.source.volume", "100")
|
||||||
|
}
|
||||||
|
} else if(dev == "codec") {
|
||||||
|
propertySet("sys.ritosip.audio.source", BaresipService.audioDeviceCodecId.toString())
|
||||||
|
propertySet("sys.ritosip.audio.source.volume", "100")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun checkNetworkIpType() {
|
fun checkNetworkIpType() {
|
||||||
val process = Runtime.getRuntime().exec("ritosysc shell-order=rm /mnt/obb/ip_static;grep STATIC /data/misc/ethernet/ipconfig.txt && touch /mnt/obb/ip_static")
|
val process = Runtime.getRuntime().exec("ritosysc shell-order=rm /mnt/obb/ip_static;grep STATIC /data/misc/ethernet/ipconfig.txt && touch /mnt/obb/ip_static")
|
||||||
process.waitFor()
|
process.waitFor()
|
||||||
@ -1279,6 +1356,28 @@ object Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun runShellOrder(order : String) {
|
||||||
|
val process = Runtime.getRuntime().exec(order)
|
||||||
|
process.waitFor()
|
||||||
|
process.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setMicVolumeByMix(volume : Int) {
|
||||||
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
|
Utils.runShellOrderSuper("tinymix -D 3 \"Mic Capture Volume\" ${volume}")
|
||||||
|
BaresipService.micVolume = volume
|
||||||
|
Config.replaceVariable("mic_volume", volume.toString())
|
||||||
|
Config.save()
|
||||||
|
propertySet("sys.ritosip.mic.volume", volume.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runShellOrderSuper(order : String) {
|
||||||
|
val process = Runtime.getRuntime().exec("ritosysc shell-order=" + order)
|
||||||
|
process.waitFor()
|
||||||
|
process.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
fun save(dev : String) {
|
fun save(dev : String) {
|
||||||
propertySet("sys.rito.audio.input.device", dev)
|
propertySet("sys.rito.audio.input.device", dev)
|
||||||
//val process = Runtime.getRuntime().exec("ritosysc shell-order=killall audioserver")
|
//val process = Runtime.getRuntime().exec("ritosysc shell-order=killall audioserver")
|
||||||
@ -1315,7 +1414,17 @@ object Utils {
|
|||||||
val file = File("/d/hdmirx/status") // 파일 경로 설정
|
val file = File("/d/hdmirx/status") // 파일 경로 설정
|
||||||
file.bufferedReader().use { reader ->
|
file.bufferedReader().use { reader ->
|
||||||
val line = reader.readLine() // 첫 번째 줄 읽기
|
val line = reader.readLine() // 첫 번째 줄 읽기
|
||||||
return line.split(":")[1].trim()
|
val plugStatus = line.split(":")[1].trim()
|
||||||
|
if(plugStatus == "plugin") {
|
||||||
|
val line2 = reader.readLine() // 두 번째 줄 읽기
|
||||||
|
val lockStatus = line2.split(":")[1].trim().startsWith("Lock")
|
||||||
|
|
||||||
|
if (lockStatus) {
|
||||||
|
return "plugin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "plugout"
|
||||||
}
|
}
|
||||||
} else if(idx == 1) {
|
} else if(idx == 1) {
|
||||||
val file = File("/sys/module/lt6911uxc/parameters/status") // 파일 경로 설정
|
val file = File("/sys/module/lt6911uxc/parameters/status") // 파일 경로 설정
|
||||||
@ -1334,13 +1443,21 @@ object Utils {
|
|||||||
fun saveNumberToFile(path: String, number: Int) {
|
fun saveNumberToFile(path: String, number: Int) {
|
||||||
val file = File(path)
|
val file = File(path)
|
||||||
try {
|
try {
|
||||||
|
//println("파일 존재 여부: ${file.exists()}, 디렉토리 여부: ${file.isDirectory}, 파일 여부: ${file.isFile}")
|
||||||
|
if(!file.exists()) {
|
||||||
|
file.createNewFile()
|
||||||
|
}
|
||||||
|
|
||||||
file.writeText(number.toString())
|
file.writeText(number.toString())
|
||||||
|
|
||||||
Log.d("FileSave", "숫자 저장 완료: $number")
|
Log.d("FileSave", "숫자 저장 완료: $number")
|
||||||
|
|
||||||
RandomAccessFile(path, "rw").use { raf ->
|
RandomAccessFile(path, "rw").use { raf ->
|
||||||
raf.fd.sync() // eMMC에 확실히 기록
|
raf.fd.sync() // eMMC에 확실히 기록
|
||||||
raf.close()
|
raf.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.setWritable(true, false)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.e("FileSave", "파일 저장 실패 : " + e.toString())
|
Log.e("FileSave", "파일 저장 실패 : " + e.toString())
|
||||||
}
|
}
|
||||||
|
BIN
app/src/main/res/drawable/backward.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
24
app/src/main/res/drawable/bg_button_selector_2.xml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_focused="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#FFFFFF" />
|
||||||
|
<solid android:color="#0098FF" /> <!-- 포커스 배경 (주황색 강조) -->
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#FFFFFF" />
|
||||||
|
<solid android:color="#26A7FF" /> <!-- 포커스 배경 (주황색 강조) -->
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#88FFFFFF" />
|
||||||
|
<solid android:color="#c2c2c2" /> <!-- 포커스 배경 (회색) -->
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
5
app/src/main/res/drawable/hangup_big.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="128dp" android:width="128dp"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@color/colorTrafficRed" android:pathData="M12,9c-1.6,0 -3.15,0.25 -4.6,0.72v3.1c0,0.39 -0.23,0.74 -0.56,0.9 -0.98,0.49 -1.87,1.12 -2.66,1.85 -0.18,0.18 -0.43,0.28 -0.7,0.28 -0.28,0 -0.53,-0.11 -0.71,-0.29L0.29,13.08c-0.18,-0.17 -0.29,-0.42 -0.29,-0.7 0,-0.28 0.11,-0.53 0.29,-0.71C3.34,8.78 7.46,7 12,7s8.66,1.78 11.71,4.67c0.18,0.18 0.29,0.43 0.29,0.71 0,0.28 -0.11,0.53 -0.29,0.71l-2.48,2.48c-0.18,0.18 -0.43,0.29 -0.71,0.29 -0.27,0 -0.52,-0.11 -0.7,-0.28 -0.79,-0.74 -1.69,-1.36 -2.67,-1.85 -0.33,-0.16 -0.56,-0.5 -0.56,-0.9v-3.1C15.15,9.25 13.6,9 12,9z"/>
|
||||||
|
</vector>
|
BIN
app/src/main/res/drawable/layout.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable/layout1.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable/layout10.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable/layout2.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable/layout3.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable/layout4.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable/layout5.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable/layout6.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/drawable/layout7.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable/layout8.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable/layout9.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable/network.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
app/src/main/res/drawable/nocamera.png
Normal file
After Width: | Height: | Size: 924 KiB |
BIN
app/src/main/res/drawable/server.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
app/src/main/res/drawable/volume.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
@ -19,6 +19,15 @@
|
|||||||
app:srcCompat="@drawable/osvc_splash" />
|
app:srcCompat="@drawable/osvc_splash" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/callBackground"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/colorBlack"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/defaultLayout"
|
android:id="@+id/defaultLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -662,6 +671,228 @@
|
|||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/settingLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginHorizontal="60px"
|
||||||
|
android:layout_marginVertical="150px"
|
||||||
|
android:background="@drawable/custom_border"
|
||||||
|
android:visibility="invisible">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/dialogButtonLayout"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="90px"
|
||||||
|
android:layout_marginTop="250px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/layout"
|
||||||
|
android:drawablePadding="25px"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:nextFocusLeft="@id/dialogButtonBackward"
|
||||||
|
android:nextFocusRight="@id/dialogButtonServer"
|
||||||
|
android:nextFocusUp="@id/dialogButtonLayout"
|
||||||
|
android:nextFocusDown="@id/dialogButtonLayout"
|
||||||
|
android:text="레이아웃설정"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/dialogButtonServer"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="432px"
|
||||||
|
android:layout_marginTop="250px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/server"
|
||||||
|
android:drawablePadding="25px"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="서버설정"
|
||||||
|
android:nextFocusLeft="@id/dialogButtonLayout"
|
||||||
|
android:nextFocusRight="@id/dialogButtonNetwork"
|
||||||
|
android:nextFocusUp="@id/dialogButtonServer"
|
||||||
|
android:nextFocusDown="@id/dialogButtonServer"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/dialogButtonNetwork"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="774px"
|
||||||
|
android:layout_marginTop="250px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/network"
|
||||||
|
android:drawablePadding="25px"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="네트워크설정"
|
||||||
|
android:nextFocusLeft="@id/dialogButtonServer"
|
||||||
|
android:nextFocusRight="@id/dialogButtonVolume"
|
||||||
|
android:nextFocusUp="@id/dialogButtonNetwork"
|
||||||
|
android:nextFocusDown="@id/dialogButtonNetwork"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/dialogButtonVolume"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="1116px"
|
||||||
|
android:layout_marginTop="250px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/volume"
|
||||||
|
android:drawablePadding="25px"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="볼륨설정"
|
||||||
|
android:nextFocusLeft="@id/dialogButtonNetwork"
|
||||||
|
android:nextFocusRight="@id/dialogButtonBackward"
|
||||||
|
android:nextFocusUp="@id/dialogButtonVolume"
|
||||||
|
android:nextFocusDown="@id/dialogButtonVolume"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/dialogButtonBackward"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="1458px"
|
||||||
|
android:layout_marginTop="250px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/backward"
|
||||||
|
android:drawablePadding="25px"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="돌아가기"
|
||||||
|
android:nextFocusLeft="@id/dialogButtonVolume"
|
||||||
|
android:nextFocusRight="@id/dialogButtonLayout"
|
||||||
|
android:nextFocusUp="@id/dialogButtonBackward"
|
||||||
|
android:nextFocusDown="@id/dialogButtonBackward"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/settingLayoutInCall"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginHorizontal="150px"
|
||||||
|
android:layout_marginVertical="150px"
|
||||||
|
android:background="@drawable/custom_border"
|
||||||
|
android:visibility="invisible">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/dialogButtonLayoutInCall"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="100px"
|
||||||
|
android:layout_marginTop="250px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/layout"
|
||||||
|
android:drawablePadding="25px"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:nextFocusLeft="@id/dialogButtonBackwardInCall"
|
||||||
|
android:nextFocusRight="@id/dialogButtonHangUp"
|
||||||
|
android:nextFocusUp="@id/dialogButtonLayoutInCall"
|
||||||
|
android:nextFocusDown="@id/dialogButtonLayoutInCall"
|
||||||
|
android:text="레이아웃설정"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/dialogButtonHangUp"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="480px"
|
||||||
|
android:layout_marginTop="250px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/hangup_big"
|
||||||
|
android:drawablePadding="25px"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="통화종료"
|
||||||
|
android:nextFocusLeft="@id/dialogButtonLayoutInCall"
|
||||||
|
android:nextFocusRight="@id/dialogButtonVolumeInCall"
|
||||||
|
android:nextFocusUp="@id/dialogButtonHangUp"
|
||||||
|
android:nextFocusDown="@id/dialogButtonHangUp"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/dialogButtonVolumeInCall"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="860px"
|
||||||
|
android:layout_marginTop="250px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/volume"
|
||||||
|
android:drawablePadding="25px"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="볼륨설정"
|
||||||
|
android:nextFocusLeft="@id/dialogButtonHangUp"
|
||||||
|
android:nextFocusRight="@id/dialogButtonBackwardInCall"
|
||||||
|
android:nextFocusUp="@id/dialogButtonVolumeInCall"
|
||||||
|
android:nextFocusDown="@id/dialogButtonVolumeInCall"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/dialogButtonBackwardInCall"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="1240px"
|
||||||
|
android:layout_marginTop="250px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/backward"
|
||||||
|
android:drawablePadding="25px"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="돌아가기"
|
||||||
|
android:nextFocusLeft="@id/dialogButtonVolumeInCall"
|
||||||
|
android:nextFocusRight="@id/dialogButtonLayoutInCall"
|
||||||
|
android:nextFocusUp="@id/dialogButtonBackwardInCall"
|
||||||
|
android:nextFocusDown="@id/dialogButtonBackwardInCall"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/networkSettingLayout"
|
android:id="@+id/networkSettingLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -761,6 +992,8 @@
|
|||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:paddingHorizontal="20dp"
|
android:paddingHorizontal="20dp"
|
||||||
android:paddingVertical="10dp"
|
android:paddingVertical="10dp"
|
||||||
|
android:nextFocusLeft="@id/btnApply"
|
||||||
|
android:nextFocusRight="@id/btnCancel"
|
||||||
android:text="적용하기"
|
android:text="적용하기"
|
||||||
android:textSize="24sp" />
|
android:textSize="24sp" />
|
||||||
|
|
||||||
@ -771,10 +1004,549 @@
|
|||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:paddingHorizontal="20dp"
|
android:paddingHorizontal="20dp"
|
||||||
android:paddingVertical="10dp"
|
android:paddingVertical="10dp"
|
||||||
|
android:nextFocusLeft="@id/btnApply"
|
||||||
|
android:nextFocusRight="@id/btnCancel"
|
||||||
android:text="취소하기"
|
android:text="취소하기"
|
||||||
android:textSize="24sp" />
|
android:textSize="24sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/serverSettingLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/custom_border"
|
||||||
|
android:visibility="invisible">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="서버 설정"
|
||||||
|
android:textSize="34sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="16dp">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="200px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="표시명"
|
||||||
|
android:textSize="24sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/editDisplayName"
|
||||||
|
android:layout_width="1000px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="16dp">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="200px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="인증 사용자명"
|
||||||
|
android:textSize="24sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/editSipId"
|
||||||
|
android:layout_width="1000px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="phone"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="16dp">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="200px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="인증 암호"
|
||||||
|
android:textSize="24sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/editSipPassword"
|
||||||
|
android:layout_width="1000px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="16dp">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="200px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="SIP 서버주소"
|
||||||
|
android:textSize="24sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/editSipServer"
|
||||||
|
android:layout_width="1000px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="200px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="트랜스포트"
|
||||||
|
android:textSize="24sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/radioGroupTransport"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingBottom="16dp">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/radioTransportUdp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:checked="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:paddingRight="15dp"
|
||||||
|
android:nextFocusUp="@id/editSipServer"
|
||||||
|
android:text="UDP"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/radioTransportTcp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:paddingRight="15dp"
|
||||||
|
android:nextFocusUp="@id/editSipServer"
|
||||||
|
android:text="TCP"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/radioTransportTls"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:paddingRight="15dp"
|
||||||
|
android:nextFocusUp="@id/editSipServer"
|
||||||
|
android:text="TLS"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="200px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="미디어 암호화"
|
||||||
|
android:textSize="24sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/radioGroupEncrypt"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingBottom="16dp">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/radioEncryptNone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:checked="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:paddingRight="15dp"
|
||||||
|
android:nextFocusDown="@id/btnApplyServer"
|
||||||
|
android:text="사용안함"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/radioEncryptSrtp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:paddingRight="15dp"
|
||||||
|
android:nextFocusDown="@id/btnApplyServer"
|
||||||
|
android:text="SRTP"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnApplyServer"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="10dp"
|
||||||
|
android:nextFocusUp="@id/radioEncryptNone"
|
||||||
|
android:nextFocusLeft="@id/btnApplyServer"
|
||||||
|
android:nextFocusRight="@id/btnCancelServer"
|
||||||
|
android:text="적용하기"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnCancelServer"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="10dp"
|
||||||
|
android:nextFocusUp="@id/radioEncryptNone"
|
||||||
|
android:nextFocusLeft="@id/btnApplyServer"
|
||||||
|
android:nextFocusRight="@id/btnCancelServer"
|
||||||
|
android:text="취소하기"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/volumeSettingLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/custom_border"
|
||||||
|
android:visibility="invisible">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="볼륨 설정"
|
||||||
|
android:textSize="34sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="200px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="마이크볼륨"
|
||||||
|
android:textSize="24sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekbarMicVolume"
|
||||||
|
android:layout_width="600px"
|
||||||
|
android:max="24"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:nextFocusUp="@id/seekbarMicVolume"
|
||||||
|
android:nextFocusLeft="@id/seekbarMicVolume"
|
||||||
|
android:nextFocusRight="@id/seekbarMicVolume"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textMicVolume"
|
||||||
|
android:layout_width="200px"
|
||||||
|
android:layout_marginLeft="30px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text=""
|
||||||
|
android:textSize="36sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnDoneVolume"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="10dp"
|
||||||
|
android:nextFocusUp="@id/seekbarMicVolume"
|
||||||
|
android:nextFocusLeft="@id/btnDoneVolume"
|
||||||
|
android:nextFocusRight="@id/btnDoneVolume"
|
||||||
|
android:nextFocusDown="@id/btnDoneVolume"
|
||||||
|
android:text="돌아가기"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/layoutSettingLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/custom_border"
|
||||||
|
android:visibility="invisible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="레이아웃 설정"
|
||||||
|
android:textSize="34sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType1"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="155px"
|
||||||
|
android:layout_marginTop="140px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout1"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType10"
|
||||||
|
android:nextFocusRight="@id/layoutType2"
|
||||||
|
android:nextFocusUp="@id/layoutBackward"
|
||||||
|
android:nextFocusDown="@id/layoutType6" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType2"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="495px"
|
||||||
|
android:layout_marginTop="140px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout2"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType1"
|
||||||
|
android:nextFocusRight="@id/layoutType3"
|
||||||
|
android:nextFocusUp="@id/layoutBackward"
|
||||||
|
android:nextFocusDown="@id/layoutType7" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType3"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="835px"
|
||||||
|
android:layout_marginTop="140px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout3"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType2"
|
||||||
|
android:nextFocusRight="@id/layoutType4"
|
||||||
|
android:nextFocusUp="@id/layoutBackward"
|
||||||
|
android:nextFocusDown="@id/layoutType8" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType4"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="1175px"
|
||||||
|
android:layout_marginTop="140px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout4"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType3"
|
||||||
|
android:nextFocusRight="@id/layoutType5"
|
||||||
|
android:nextFocusUp="@id/layoutBackward"
|
||||||
|
android:nextFocusDown="@id/layoutType9" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType5"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="1515px"
|
||||||
|
android:layout_marginTop="140px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout5"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType4"
|
||||||
|
android:nextFocusRight="@id/layoutType6"
|
||||||
|
android:nextFocusUp="@id/layoutBackward"
|
||||||
|
android:nextFocusDown="@id/layoutType10" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType6"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="155px"
|
||||||
|
android:layout_marginTop="420px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout6"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType5"
|
||||||
|
android:nextFocusRight="@id/layoutType7"
|
||||||
|
android:nextFocusUp="@id/layoutType1"
|
||||||
|
android:nextFocusDown="@id/layoutBackward" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType7"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="495px"
|
||||||
|
android:layout_marginTop="420px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout7"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType6"
|
||||||
|
android:nextFocusRight="@id/layoutType8"
|
||||||
|
android:nextFocusUp="@id/layoutType2"
|
||||||
|
android:nextFocusDown="@id/layoutBackward" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType8"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="835px"
|
||||||
|
android:layout_marginTop="420px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout8"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType7"
|
||||||
|
android:nextFocusRight="@id/layoutType9"
|
||||||
|
android:nextFocusUp="@id/layoutType3"
|
||||||
|
android:nextFocusDown="@id/layoutBackward" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType9"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="1175px"
|
||||||
|
android:layout_marginTop="420px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout9"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType8"
|
||||||
|
android:nextFocusRight="@id/layoutType10"
|
||||||
|
android:nextFocusUp="@id/layoutType4"
|
||||||
|
android:nextFocusDown="@id/layoutBackward" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutType10"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="1515px"
|
||||||
|
android:layout_marginTop="420px"
|
||||||
|
android:background="@drawable/bg_button_selector_2"
|
||||||
|
android:drawableTop="@drawable/layout10"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutType9"
|
||||||
|
android:nextFocusRight="@id/layoutType1"
|
||||||
|
android:nextFocusUp="@id/layoutType5"
|
||||||
|
android:nextFocusDown="@id/layoutBackward" />
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/layoutBackward"
|
||||||
|
android:layout_width="250px"
|
||||||
|
android:layout_height="210px"
|
||||||
|
android:layout_marginLeft="835px"
|
||||||
|
android:layout_marginTop="780px"
|
||||||
|
android:background="@drawable/bg_button_selector"
|
||||||
|
android:drawableTop="@drawable/backward"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:nextFocusLeft="@id/layoutBackward"
|
||||||
|
android:nextFocusRight="@id/layoutBackward"
|
||||||
|
android:nextFocusUp="@id/layoutType8"
|
||||||
|
android:nextFocusDown="@id/layoutType3" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|