introduced support for sending and receiving messages
This commit is contained in:
@@ -91,7 +91,7 @@ class Account(val accp: String) {
|
||||
return null
|
||||
}
|
||||
|
||||
fun findUA(aor: String): UserAgent? {
|
||||
fun findUa(aor: String): UserAgent? {
|
||||
for (ua in MainActivity.uas) {
|
||||
if (ua.account.aor == aor) return ua
|
||||
}
|
||||
|
||||
@@ -21,6 +21,10 @@ import java.io.ObjectInputStream
|
||||
import android.support.v4.content.LocalBroadcastManager
|
||||
import android.os.Build
|
||||
import android.support.v4.app.NotificationCompat.VISIBILITY_PRIVATE
|
||||
import java.nio.charset.StandardCharsets
|
||||
import kotlin.experimental.and
|
||||
import android.R.attr.name
|
||||
import java.nio.charset.Charset
|
||||
|
||||
class BaresipService: Service() {
|
||||
|
||||
@@ -120,6 +124,21 @@ class BaresipService: Service() {
|
||||
}
|
||||
}
|
||||
|
||||
file = File(path, "messages")
|
||||
if (file.exists()) {
|
||||
try {
|
||||
val fis = FileInputStream(file)
|
||||
val ois = ObjectInputStream(fis)
|
||||
@SuppressWarnings("unchecked")
|
||||
MainActivity.messages = ois.readObject() as ArrayList<Message>
|
||||
Log.d(LOG_TAG, "Restored ${MainActivity.messages.size} messages")
|
||||
ois.close()
|
||||
fis.close()
|
||||
} catch (e: Exception) {
|
||||
Log.w(LOG_TAG, "InputStream exception: - " + e.toString())
|
||||
}
|
||||
}
|
||||
|
||||
ContactsActivity.generateContacts(path + "/contacts")
|
||||
|
||||
Thread(Runnable { baresipStart(path) }).start()
|
||||
@@ -191,7 +210,7 @@ class BaresipService: Service() {
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun addUA(uap: String) {
|
||||
fun uaAdd(uap: String) {
|
||||
Log.d(LOG_TAG, "addUA at BaresipService")
|
||||
val ua = UserAgent(uap)
|
||||
MainActivity.uas.add(ua)
|
||||
@@ -205,14 +224,13 @@ class BaresipService: Service() {
|
||||
}
|
||||
val intent = Intent("service event")
|
||||
intent.putExtra("event", "ua added")
|
||||
intent.putExtra("uap", uap)
|
||||
intent.putExtra("callp", "")
|
||||
intent.putExtra("params", arrayListOf(uap))
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
|
||||
updateStatusNotification()
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun updateStatus(event: String, uap: String, callp: String) {
|
||||
fun uaEvent(event: String, uap: String, callp: String) {
|
||||
Log.d(LOG_TAG, "updateStatus got event $event/$uap/$callp")
|
||||
if (!IS_SERVICE_RUNNING) return
|
||||
val ua = UserAgent.find(MainActivity.uas, uap)
|
||||
@@ -295,11 +313,76 @@ class BaresipService: Service() {
|
||||
}
|
||||
val intent = Intent("service event")
|
||||
intent.putExtra("event", event)
|
||||
intent.putExtra("uap", uap)
|
||||
intent.putExtra("callp", callp)
|
||||
intent.putExtra("params", arrayListOf(uap, callp))
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
|
||||
}
|
||||
|
||||
|
||||
@Keep
|
||||
fun messageEvent(uap: String, peer: String, msg: ByteArray) {
|
||||
Log.d(LOG_TAG, "message event $uap/$peer")
|
||||
var s = "Decoding of message failed!"
|
||||
try {
|
||||
s = String(msg, StandardCharsets.UTF_8)
|
||||
Log.d(LOG_TAG, "UTF-8 $s")
|
||||
} catch (e: Exception) {
|
||||
Log.e(LOG_TAG, "UTF-8 decode failed")
|
||||
}
|
||||
val timeStamp = System.currentTimeMillis().toString()
|
||||
if (!Utils.isVisible()) {
|
||||
val cnb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
|
||||
cnb.setSmallIcon(R.drawable.ic_stat)
|
||||
.setColor(0x0ca1fd)
|
||||
.setContentIntent(npi)
|
||||
.setDefaults(Notification.DEFAULT_SOUND)
|
||||
.setAutoCancel(true)
|
||||
.setContentTitle("Message from ${ContactsActivity.contactName(peer)}")
|
||||
.setContentText(s)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
cnb.setVibrate(LongArray(0))
|
||||
.setVisibility(VISIBILITY_PRIVATE)
|
||||
.setPriority(Notification.PRIORITY_HIGH)
|
||||
}
|
||||
/* val view = RemoteViews(getPackageName(), R.layout.call_notification)
|
||||
view.setTextViewText(R.id.callFrom, "Call from ${Api.call_peeruri(callp)}")
|
||||
cnb.setContent(view) */
|
||||
val replyIntent = Intent(this, MainActivity::class.java)
|
||||
replyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
replyIntent.putExtra("action", "reply")
|
||||
replyIntent.putExtra("uap", uap)
|
||||
replyIntent.putExtra("peer", peer)
|
||||
val replyPendingIntent = PendingIntent.getActivity(this,
|
||||
0, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
val archiveIntent = Intent(this, MainActivity::class.java)
|
||||
archiveIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
archiveIntent.putExtra("action", "archive")
|
||||
archiveIntent.putExtra("uap", uap)
|
||||
archiveIntent.putExtra("time", timeStamp)
|
||||
val archivePendingIntent = PendingIntent.getActivity(this,
|
||||
1, archiveIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
val deleteIntent = Intent(this, MainActivity::class.java)
|
||||
deleteIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
deleteIntent.putExtra("action", "delete")
|
||||
deleteIntent.putExtra("uap", uap)
|
||||
deleteIntent.putExtra("time", timeStamp)
|
||||
val deletePendingIntent = PendingIntent.getActivity(this,
|
||||
2, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
/* view.setOnClickPendingIntent(R.id.answerButton, answerPendingIntent)
|
||||
view.setOnClickPendingIntent(R.id.rejectButton, rejectPendingIntent)
|
||||
cnb.setCustomBigContentView(view) */
|
||||
cnb.addAction(R.drawable.ic_stat, "Reply", replyPendingIntent)
|
||||
cnb.addAction(R.drawable.ic_stat, "Archive", archivePendingIntent)
|
||||
cnb.addAction(R.drawable.ic_stat, "Delete", deletePendingIntent)
|
||||
nm.notify(MESSAGE_NOTIFICATION_ID, cnb.build())
|
||||
}
|
||||
val intent = Intent("service event")
|
||||
intent.putExtra("event", "message")
|
||||
intent.putExtra("params", arrayListOf(uap, peer, s, timeStamp))
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
|
||||
}
|
||||
|
||||
private fun updateStatusNotification() {
|
||||
val contentView = RemoteViews(getPackageName(), R.layout.status_notification)
|
||||
for (i: Int in 0 .. 5) {
|
||||
@@ -321,9 +404,11 @@ class BaresipService: Service() {
|
||||
|
||||
private fun cleanStop() {
|
||||
HistoryActivity.saveHistory()
|
||||
MessagesActivity.saveMessages()
|
||||
MainActivity.uas.clear()
|
||||
MainActivity.images.clear()
|
||||
MainActivity.history.clear()
|
||||
MainActivity.messages.clear()
|
||||
baresipStop()
|
||||
BaresipService.IS_SERVICE_RUNNING = false
|
||||
unregisterReceiver(nr)
|
||||
@@ -339,8 +424,9 @@ class BaresipService: Service() {
|
||||
|
||||
var IS_SERVICE_RUNNING = false
|
||||
val STATUS_NOTIFICATION_ID = 101
|
||||
val DEFAULT_CHANNEL_ID = "com.tutpro.baresip.default"
|
||||
val CALL_NOTIFICATION_ID = 102
|
||||
val MESSAGE_NOTIFICATION_ID = 103
|
||||
val DEFAULT_CHANNEL_ID = "com.tutpro.baresip.default"
|
||||
val HIGH_CHANNEL_ID = "com.tutpro.baresip.high"
|
||||
var disconnected = false
|
||||
val RUN_FOREGROUNG = false
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.widget.RelativeLayout
|
||||
import android.widget.*
|
||||
import android.view.*
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
@@ -39,7 +40,8 @@ class MainActivity : AppCompatActivity() {
|
||||
internal lateinit var securityButton: ImageButton
|
||||
internal lateinit var callButton: ImageButton
|
||||
internal lateinit var holdButton: ImageButton
|
||||
internal lateinit var historyButton: ImageButton
|
||||
internal lateinit var messagesButton: ImageButton
|
||||
internal lateinit var callsButton: ImageButton
|
||||
internal lateinit var dtmf: EditText
|
||||
internal lateinit var uaAdapter: UaSpinnerAdapter
|
||||
internal lateinit var aorSpinner: Spinner
|
||||
@@ -70,7 +72,8 @@ class MainActivity : AppCompatActivity() {
|
||||
securityButton = findViewById(R.id.securityButton) as ImageButton
|
||||
callButton = findViewById(R.id.callButton) as ImageButton
|
||||
holdButton = findViewById(R.id.holdButton) as ImageButton
|
||||
historyButton = findViewById(R.id.historyButton) as ImageButton
|
||||
messagesButton = findViewById(R.id.messagesButton) as ImageButton
|
||||
callsButton = findViewById(R.id.callsButton) as ImageButton
|
||||
dtmf = findViewById(R.id.dtmf) as EditText
|
||||
|
||||
am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
@@ -83,8 +86,7 @@ class MainActivity : AppCompatActivity() {
|
||||
serviceEventReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
handleServiceEvent(intent.getStringExtra("event"),
|
||||
intent.getStringExtra("uap"),
|
||||
intent.getStringExtra("callp"))
|
||||
intent.getStringArrayListExtra("params"))
|
||||
}
|
||||
}
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(serviceEventReceiver,
|
||||
@@ -114,11 +116,6 @@ class MainActivity : AppCompatActivity() {
|
||||
callee.hint = "Callee"
|
||||
callButton.tag = "Call"
|
||||
callButton.setImageResource(R.drawable.call)
|
||||
if (History.aorHistory(history, aor) > 0) {
|
||||
historyButton.visibility = View.VISIBLE
|
||||
} else {
|
||||
historyButton.visibility = View.INVISIBLE
|
||||
}
|
||||
securityButton.visibility = View.INVISIBLE
|
||||
dtmf.visibility = View.INVISIBLE
|
||||
} else {
|
||||
@@ -147,8 +144,8 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
val view_count = layout.childCount
|
||||
// Log.d("Baresip", "View count is $view_count")
|
||||
if (view_count > 7)
|
||||
layout.removeViews(7, view_count - 7)
|
||||
if (view_count > 8)
|
||||
layout.removeViews(8, view_count - 8)
|
||||
for (c in Call.uaCalls(calls, ua, "in"))
|
||||
for (call_index in Call.uaCalls(calls, ua, "in").indices) {
|
||||
val startIndex = (call_index + 1) * 10
|
||||
@@ -294,8 +291,16 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
historyButton.visibility = View.INVISIBLE
|
||||
historyButton.setOnClickListener {
|
||||
messagesButton.setOnClickListener {
|
||||
val i = Intent(this@MainActivity, MessagesActivity::class.java)
|
||||
val b = Bundle()
|
||||
b.putString("aor", uas[aorSpinner.selectedItemPosition].account.aor)
|
||||
i.putExtras(b)
|
||||
startActivityForResult(i, MESSAGES_CODE)
|
||||
}
|
||||
|
||||
callsButton.visibility = View.VISIBLE
|
||||
callsButton.setOnClickListener {
|
||||
val i = Intent(this@MainActivity, HistoryActivity::class.java)
|
||||
val b = Bundle()
|
||||
b.putString("aor", uas[aorSpinner.selectedItemPosition].account.aor)
|
||||
@@ -313,16 +318,17 @@ class MainActivity : AppCompatActivity() {
|
||||
moveTaskToBack(true)
|
||||
}
|
||||
|
||||
private fun handleServiceEvent(event: String, uap: String, callp: String) {
|
||||
private fun handleServiceEvent(event: String, params: ArrayList<String>) {
|
||||
val uap = params[0]
|
||||
val ua = UserAgent.find(uas, uap)
|
||||
if (ua == null) {
|
||||
Log.w("Baresip", "handleServiceEvent '$event' did not find ua $uap")
|
||||
return
|
||||
}
|
||||
val ev = event.split(",")
|
||||
Log.d("Baresip", "Handling service event ${ev[0]} for $uap")
|
||||
val aor = ua.account.aor
|
||||
val acc = ua.account
|
||||
val ev = event.split(",")
|
||||
Log.d("Baresip", "Handling service event ${ev[0]} for $uap/$callp/$aor")
|
||||
for (account_index in uas.indices) {
|
||||
if (uas[account_index].account.aor == aor) {
|
||||
when (ev[0]) {
|
||||
@@ -334,6 +340,7 @@ class MainActivity : AppCompatActivity() {
|
||||
uaAdapter.notifyDataSetChanged()
|
||||
}
|
||||
"call incoming" -> {
|
||||
val callp = params[1]
|
||||
val peer_uri = Api.call_peeruri(callp)
|
||||
val new_call = Call(callp, ua, peer_uri, "in", "Answer", null)
|
||||
if (ONE_CALL_ONLY && (calls.size > 0)) {
|
||||
@@ -359,6 +366,7 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
"call established" -> {
|
||||
val callp = params[1]
|
||||
val call = Call.find(calls, callp)
|
||||
if (call == null) {
|
||||
Log.e("Baresip", "Established call $callp not found")
|
||||
@@ -424,6 +432,7 @@ class MainActivity : AppCompatActivity() {
|
||||
History.aorRemoveHistory(history, aor)
|
||||
}
|
||||
"call verify" -> {
|
||||
val callp = params[1]
|
||||
val call = Call.find(calls, callp)
|
||||
if (call == null) {
|
||||
Log.e("Baresip", "Call $callp to be verified is not found")
|
||||
@@ -478,6 +487,7 @@ class MainActivity : AppCompatActivity() {
|
||||
verifyDialog.create().show()
|
||||
}
|
||||
"call verified", "call secure" -> {
|
||||
val callp = params[1]
|
||||
val call = Call.find(calls, callp)
|
||||
if (call == null) {
|
||||
Log.e("Baresip", "Call $callp that is verified is not found")
|
||||
@@ -509,6 +519,7 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
"call closed" -> {
|
||||
val callp = params[1]
|
||||
val call = Call.find(calls, callp)
|
||||
if (call == null) {
|
||||
Log.d("Baresip", "Call $callp that is closed is not found")
|
||||
@@ -534,7 +545,7 @@ class MainActivity : AppCompatActivity() {
|
||||
addCallViews(ua, callsIn[i], (i + 1) * 10)
|
||||
}
|
||||
}
|
||||
historyButton.visibility = View.VISIBLE
|
||||
callsButton.visibility = View.VISIBLE
|
||||
}
|
||||
if (!call.hasHistory) {
|
||||
if (History.aorHistory(history, aor) > HISTORY_SIZE)
|
||||
@@ -558,7 +569,8 @@ class MainActivity : AppCompatActivity() {
|
||||
securityButton.visibility = View.INVISIBLE
|
||||
dtmf.removeTextChangedListener(call.dtmfWatcher)
|
||||
dtmf.visibility = View.INVISIBLE
|
||||
historyButton.visibility = View.VISIBLE
|
||||
messagesButton.visibility = View.VISIBLE
|
||||
callsButton.visibility = View.VISIBLE
|
||||
}
|
||||
calls.remove(call)
|
||||
if (!call.hasHistory) {
|
||||
@@ -570,6 +582,25 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
if (calls.size == 0) am.mode = AudioManager.MODE_NORMAL
|
||||
}
|
||||
"message" -> {
|
||||
val peer_uri = params[1]
|
||||
val msg = params[2]
|
||||
val time = params[3]
|
||||
val new_message = Message(aor, peer_uri, R.drawable.arrow_down_green, msg,
|
||||
time.toLong(), true)
|
||||
Log.d("Baresip", "Incoming message $aor/$peer_uri/$msg")
|
||||
messages.add(new_message)
|
||||
if (Utils.isVisible()) {
|
||||
if (ua != uas[aorSpinner.selectedItemPosition])
|
||||
aorSpinner.setSelection(account_index)
|
||||
val i = Intent(applicationContext, MessagesActivity::class.java)
|
||||
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
|
||||
val b = Bundle()
|
||||
b.putString("aor", ua.account.aor)
|
||||
i.putExtras(b)
|
||||
startActivity(i)
|
||||
}
|
||||
}
|
||||
else -> Log.w("Baresip", "Unknown event '${ev[0]}'")
|
||||
}
|
||||
break
|
||||
@@ -581,16 +612,52 @@ class MainActivity : AppCompatActivity() {
|
||||
setIntent(intent)
|
||||
val action = intent.getStringExtra("action")
|
||||
Log.d("Baresip", "Got onNewIntent action $action")
|
||||
if (action == null) return
|
||||
val callp = intent.getStringExtra("callp")
|
||||
when (action) {
|
||||
"answer" -> {
|
||||
answerCall = callp
|
||||
answerCall = intent.getStringExtra("callp")
|
||||
}
|
||||
"reject" -> {
|
||||
rejectCall = callp
|
||||
rejectCall = intent.getStringExtra("callp")
|
||||
moveTaskToBack(true)
|
||||
}
|
||||
"reply", "archive", "delete" -> {
|
||||
val uap = intent.getStringExtra("uap")
|
||||
val ua = UserAgent.find(MainActivity.uas, uap)
|
||||
if (ua == null) {
|
||||
Log.e("Baresip", "onNewIntent did not find ua $uap")
|
||||
return
|
||||
}
|
||||
val aor = ua.account.aor
|
||||
when (action) {
|
||||
"reply" -> {
|
||||
val i = Intent(this@MainActivity, MessagesActivity::class.java)
|
||||
val b = Bundle()
|
||||
if (ua != uas[aorSpinner.selectedItemPosition]) {
|
||||
for (account_index in uas.indices) {
|
||||
if (uas[account_index].account.aor == aor) {
|
||||
aorSpinner.setSelection(account_index)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
b.putString("aor", aor)
|
||||
b.putString("peer", intent.getStringExtra("peer"))
|
||||
i.putExtras(b)
|
||||
startActivityForResult(i, MESSAGES_CODE)
|
||||
}
|
||||
"archive" -> {
|
||||
MessagesActivity.archiveUaMessage(ua.account.aor,
|
||||
intent.getStringExtra("time").toLong())
|
||||
moveTaskToBack(true)
|
||||
}
|
||||
"delete" -> {
|
||||
MessagesActivity.deleteUaMessage(ua.account.aor,
|
||||
intent.getStringExtra("time").toLong())
|
||||
moveTaskToBack(true)
|
||||
}
|
||||
}
|
||||
nm.cancel(BaresipService.MESSAGE_NOTIFICATION_ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,13 +672,13 @@ class MainActivity : AppCompatActivity() {
|
||||
Log.d("Baresip", "Resumed")
|
||||
imm.hideSoftInputFromWindow(callee.windowToken, 0)
|
||||
visible = true
|
||||
if ((answerCall != "") && (layout.childCount > 7)) {
|
||||
if ((answerCall != "") && (layout.childCount > 8)) {
|
||||
answerCall = ""
|
||||
/* if multiple calls, right answer button needs to be searched */
|
||||
val answerButton = layout.findViewById(10 + 5) as ImageButton
|
||||
answerButton.performClick()
|
||||
}
|
||||
if ((rejectCall != "") && (layout.childCount > 7)) {
|
||||
if ((rejectCall != "") && (layout.childCount > 8)) {
|
||||
rejectCall = ""
|
||||
/* if multiple calls, right reject button needs to be searched */
|
||||
val rejectButton = layout.findViewById(10 + 6) as ImageButton
|
||||
@@ -996,6 +1063,7 @@ class MainActivity : AppCompatActivity() {
|
||||
internal var images = ArrayList<Int>()
|
||||
var history: ArrayList<History> = ArrayList()
|
||||
internal var calls = ArrayList<Call>()
|
||||
internal var messages = ArrayList<Message>()
|
||||
var filesPath = ""
|
||||
var visible = true
|
||||
var answerCall = ""
|
||||
@@ -1008,9 +1076,12 @@ class MainActivity : AppCompatActivity() {
|
||||
const val ABOUT_CODE = 5
|
||||
const val ACCOUNT_CODE = 6
|
||||
const val CONTACT_CODE = 7
|
||||
const val MESSAGES_CODE = 8
|
||||
const val MESSAGE_CODE = 9
|
||||
|
||||
const val RECORD_AUDIO_PERMISSION = 1
|
||||
const val HISTORY_SIZE = 100
|
||||
const val MESSAGE_HISTORY_SIZE = 100
|
||||
const val ONE_CALL_ONLY = true
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.tutpro.baresip
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class Message(val aor: String, val peerURI: String, val direction: Int, val message: String,
|
||||
val timeStamp: Long, var new: Boolean): Serializable {
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.tutpro.baresip
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.*
|
||||
|
||||
class MessageActivity : AppCompatActivity() {
|
||||
|
||||
internal lateinit var receiver: AutoCompleteTextView
|
||||
internal lateinit var message: EditText
|
||||
internal lateinit var sendButton: ImageButton
|
||||
internal lateinit var imm: InputMethodManager
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.activity_message)
|
||||
|
||||
val aor = intent.extras.getString("aor")
|
||||
val peerURI = intent.extras.getString("peer")
|
||||
|
||||
val ua = Account.findUa(aor)
|
||||
if (ua == null) {
|
||||
Log.e("Baresip", "MessageActivity did not find ua of $aor")
|
||||
val i = Intent()
|
||||
setResult(Activity.RESULT_CANCELED, i)
|
||||
finish()
|
||||
}
|
||||
|
||||
val title = findViewById(R.id.messageToTitle) as TextView
|
||||
message = findViewById(R.id.text) as EditText
|
||||
receiver = findViewById(R.id.receiver) as AutoCompleteTextView
|
||||
|
||||
imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
|
||||
if (peerURI == "") {
|
||||
title.text = "Message to ..."
|
||||
receiver.threshold = 2
|
||||
receiver.setAdapter(ArrayAdapter(this, android.R.layout.select_dialog_item,
|
||||
ContactsActivity.contacts.map { Contact -> Contact.name }))
|
||||
receiver.requestFocus()
|
||||
} else {
|
||||
title.text = "Reply to ..."
|
||||
receiver.setText(ContactsActivity.contactName(peerURI), false)
|
||||
message.requestFocus()
|
||||
}
|
||||
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
|
||||
|
||||
sendButton = findViewById(R.id.sendButton) as ImageButton
|
||||
sendButton.setOnClickListener {
|
||||
val receiverText = receiver.text.toString()
|
||||
val msg = message.text.toString()
|
||||
if (receiverText.length > 0) {
|
||||
var uri = ContactsActivity.findContactURI(receiverText)
|
||||
if (!uri.startsWith("sip:")) uri = "sip:$uri"
|
||||
if (!uri.contains("@")) {
|
||||
val host = aor.substring(aor.indexOf("@") + 1)
|
||||
uri = "$uri@$host"
|
||||
}
|
||||
if (msg.length > 0) {
|
||||
imm.hideSoftInputFromWindow(receiver.getWindowToken(), 0)
|
||||
imm.hideSoftInputFromWindow(message.getWindowToken(), 0)
|
||||
val res = message_send(ua!!.uap, uri, msg)
|
||||
if (res != 0) {
|
||||
Toast.makeText(getApplicationContext(), "Sending of message failed!",
|
||||
Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
val new_message = Message(aor, uri, R.drawable.arrow_up_green, msg,
|
||||
System.currentTimeMillis(), false)
|
||||
MainActivity.messages.add(new_message)
|
||||
MessagesActivity.uaMessages.add(0, new_message)
|
||||
val i = Intent()
|
||||
setResult(Activity.RESULT_OK, i)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
imm.hideSoftInputFromWindow(receiver.getWindowToken(), 0)
|
||||
imm.hideSoftInputFromWindow(message.getWindowToken(), 0)
|
||||
val i = Intent()
|
||||
setResult(Activity.RESULT_CANCELED, i)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
external fun message_send(uap: String, peer_uri: String, message: String) : Int
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.tutpro.baresip
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.text.format.DateUtils.isToday
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class MessageListAdapter(private val cxt: Context, private val rows: ArrayList<Message>) :
|
||||
ArrayAdapter<Message>(cxt, R.layout.message, rows) {
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
val message = rows[position]
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
val messageView = inflater.inflate(R.layout.message, parent, false)
|
||||
val directionView = messageView.findViewById(R.id.direction) as ImageView
|
||||
directionView.setImageResource(message.direction)
|
||||
val peerView = messageView.findViewById(R.id.peer) as TextView
|
||||
peerView.text = ContactsActivity.contactName(message.peerURI)
|
||||
val timeView = messageView.findViewById(R.id.time) as TextView
|
||||
val time: String
|
||||
val cal = GregorianCalendar()
|
||||
cal.timeInMillis = message.timeStamp
|
||||
if (isToday(message.timeStamp)) {
|
||||
val fmt = SimpleDateFormat("HH:mm")
|
||||
time = fmt.format(cal.time)
|
||||
} else {
|
||||
val fmt = SimpleDateFormat("dd.MM")
|
||||
time = fmt.format(cal.time)
|
||||
}
|
||||
timeView.text = time
|
||||
val textView = messageView.findViewById(R.id.text) as TextView
|
||||
textView.text = message.message
|
||||
if (message.new) {
|
||||
textView.setTypeface(null, Typeface.BOLD)
|
||||
message.new = false
|
||||
}
|
||||
return messageView
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.tutpro.baresip
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ListView
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.ObjectOutputStream
|
||||
import java.util.*
|
||||
|
||||
class MessagesActivity: AppCompatActivity() {
|
||||
|
||||
internal lateinit var aor: String
|
||||
internal lateinit var mlAdapter: MessageListAdapter
|
||||
internal lateinit var plusButton: ImageButton
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_messages)
|
||||
|
||||
val listView = findViewById(R.id.message) as ListView
|
||||
plusButton = findViewById(R.id.plusButton) as ImageButton
|
||||
|
||||
aor = intent.extras.getString("aor")
|
||||
uaMessages = uaMessages(aor)
|
||||
|
||||
mlAdapter = MessageListAdapter(this, uaMessages)
|
||||
listView.adapter = mlAdapter
|
||||
listView.isLongClickable = true
|
||||
|
||||
listView.onItemClickListener = AdapterView.OnItemClickListener { _, _, pos, _ ->
|
||||
val i = Intent(this@MessagesActivity, MessageActivity::class.java)
|
||||
val b = Bundle()
|
||||
b.putString("aor", aor)
|
||||
b.putString("peer", uaMessages[pos].peerURI)
|
||||
i.putExtras(b)
|
||||
startActivityForResult(i, MainActivity.MESSAGE_CODE)
|
||||
}
|
||||
|
||||
listView.onItemLongClickListener = AdapterView.OnItemLongClickListener { _, _, pos, _ ->
|
||||
val dialogClickListener = DialogInterface.OnClickListener { _, which ->
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_NEGATIVE -> {
|
||||
MainActivity.messages.remove(uaMessages[pos])
|
||||
uaMessages.removeAt(pos)
|
||||
if (uaMessages.size == 0) {
|
||||
val i = Intent()
|
||||
setResult(Activity.RESULT_CANCELED, i)
|
||||
finish()
|
||||
}
|
||||
mlAdapter.notifyDataSetChanged()
|
||||
}
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val builder = AlertDialog.Builder(this@MessagesActivity,
|
||||
R.style.Theme_AppCompat)
|
||||
builder.setMessage("Delete message from " +
|
||||
ContactsActivity.contactName(uaMessages[pos].peerURI) + "?")
|
||||
.setPositiveButton("Cancel", dialogClickListener)
|
||||
.setNegativeButton("Delete", dialogClickListener)
|
||||
.show()
|
||||
true
|
||||
}
|
||||
|
||||
plusButton.setOnClickListener {
|
||||
val i = Intent(this@MessagesActivity, MessageActivity::class.java)
|
||||
val b = Bundle()
|
||||
b.putString("aor", aor)
|
||||
b.putString("peer", "")
|
||||
i.putExtras(b)
|
||||
startActivityForResult(i, MainActivity.MESSAGE_CODE)
|
||||
}
|
||||
|
||||
val peer = intent.extras.getString("peer")
|
||||
if (peer != null) {
|
||||
val i = Intent(this@MessagesActivity, MessageActivity::class.java)
|
||||
val b = Bundle()
|
||||
b.putString("aor", aor)
|
||||
b.putString("peer", peer)
|
||||
i.putExtras(b)
|
||||
startActivityForResult(i, MainActivity.MESSAGE_CODE)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
Log.d("Baresip", "Back array was pressed at Messages")
|
||||
val i = Intent()
|
||||
setResult(Activity.RESULT_CANCELED, i)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
when (requestCode) {
|
||||
MainActivity.MESSAGE_CODE -> {
|
||||
if (resultCode == RESULT_OK) {
|
||||
mlAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun uaMessages(aor: String) : ArrayList<Message> {
|
||||
val res = ArrayList<Message>()
|
||||
for (m in MainActivity.messages.reversed()) {
|
||||
if (m.aor == aor) {
|
||||
res.add(m)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
var uaMessages = ArrayList<Message>()
|
||||
|
||||
fun archiveUaMessage(aor: String, time: Long) {
|
||||
for (i in MainActivity.messages.indices.reversed())
|
||||
if ((MainActivity.messages[i].aor == aor) &&
|
||||
(MainActivity.messages[i].timeStamp == time)) {
|
||||
MainActivity.messages[i].new = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteUaMessage(aor: String, time: Long) {
|
||||
for (i in MainActivity.messages.indices.reversed())
|
||||
if ((MainActivity.messages[i].aor == aor) &&
|
||||
(MainActivity.messages[i].timeStamp == time)) {
|
||||
MainActivity.messages.removeAt(i)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fun saveMessages() {
|
||||
val file = File(MainActivity.filesPath, "messages")
|
||||
try {
|
||||
val fos = FileOutputStream(file)
|
||||
val oos = ObjectOutputStream(fos)
|
||||
oos.writeObject(MainActivity.messages)
|
||||
oos.close()
|
||||
fos.close()
|
||||
} catch (e: IOException) {
|
||||
Log.w("Baresip", "OutputStream exception: " + e.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ class RunOnStartup : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if ((intent.action == Intent.ACTION_BOOT_COMPLETED) or
|
||||
(intent.action == "com.tutpro.baresip.Restart")) {
|
||||
Log.d("Baresip", "Start baresip upon boot completed or restart")
|
||||
Log.d("Baresip", "Start baresip upon boot completed or restart")
|
||||
val i = Intent(context, MainActivity::class.java)
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
val b = Bundle()
|
||||
|
||||
Reference in New Issue
Block a user