- new implementation of messaging

- fixed possible crash when messages arrive before accounts are created
- other minor fixes and improvements
This commit is contained in:
Juha Heinanen
2018-11-18 09:37:22 +02:00
parent ec12536fd9
commit 49d9d8c311
25 changed files with 457 additions and 358 deletions

View File

@ -7,8 +7,8 @@ android {
applicationId = 'com.tutpro.baresip'
minSdkVersion 21
targetSdkVersion 27
versionCode = 32
versionName = '3.2.3'
versionCode = 33
versionName = '4.0.0'
externalNativeBuild {
cmake {
cFlags '-DHAVE_INTTYPES_H'

View File

@ -47,76 +47,49 @@
android:name=".AccountsActivity"
android:label="Accounts"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.tutpro.baresip.MainActivity" />
</activity>
<activity
android:name=".AccountActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="Account"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.tutpro.baresip.MainActivity" />
android:parentActivityName=".AccountsActivity">
</activity>
<activity
android:name=".ContactsActivity"
android:label="Contacts"
android:parentActivityName=".MainActivity"
android:windowSoftInputMode="adjustPan">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.tutpro.baresip.MainActivity" />
android:windowSoftInputMode="adjustPan"
android:parentActivityName=".MainActivity" >
</activity>
<activity
android:name=".ContactActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="Contact"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.tutpro.baresip.MainActivity" />
android:parentActivityName=".ContactsActivity" >
</activity>
<activity
android:name=".EditConfigActivity"
android:label="Edit Config"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.tutpro.baresip.MainActivity" />
android:parentActivityName=".MainActivity" >
</activity>
<activity
android:name=".CallsActivity"
android:label="Call History"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.tutpro.baresip.MainActivity" />
android:parentActivityName=".MainActivity" >
</activity>
<activity
android:name=".MessagesActivity"
android:label="Message History"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.tutpro.baresip.MainActivity" />
android:name=".ChatsActivity"
android:label="Chat History"
android:parentActivityName=".MainActivity" >
</activity>
<activity
android:name=".MessageActivity"
android:label="Message or Call"
android:parentActivityName=".MessagesActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.tutpro.baresip.MainActivity" />
android:name=".ChatActivity"
android:label="Messages of a Chat"
android:parentActivityName=".ChatsActivity" >
</activity>
<activity
android:name=".AboutActivity"
android:label="About"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.tutpro.baresip.MainActivity" />
</activity>
<service

View File

@ -1033,7 +1033,7 @@ Java_com_tutpro_baresip_MainActivity_call_1send_1digit(JNIEnv *env, jobject thiz
}
JNIEXPORT jint JNICALL
Java_com_tutpro_baresip_MessageActivity_message_1send(JNIEnv *env, jobject thiz, jstring javaUA,
Java_com_tutpro_baresip_ChatActivity_message_1send(JNIEnv *env, jobject thiz, jstring javaUA,
jstring javaPeer, jstring javaMsg,
jstring javaTime) {
struct ua *ua;

View File

@ -77,18 +77,12 @@ class AccountsActivity : AppCompatActivity() {
companion object {
var accounts = ArrayList<AccountRow>()
var posAtAccounts = ArrayList<Int>()
fun generateAccounts() {
accounts.clear()
posAtAccounts.clear()
var i = 0;
for (ua in MainActivity.uas) {
for (ua in MainActivity.uas)
accounts.add(AccountRow(ua.account.aor.replace("sip:", ""),
R.drawable.action_remove))
posAtAccounts.add(i)
i++
}
}
fun saveAccounts() {

View File

@ -40,7 +40,7 @@ class CallsActivity : AppCompatActivity() {
val adapter = CallListAdapter(this, uaHistory)
listview.adapter = adapter
listview.onItemClickListener = AdapterView.OnItemClickListener { _, _, pos, _ ->
val i = Intent(this@CallsActivity, MessageActivity::class.java)
val i = Intent(this@CallsActivity, ChatActivity::class.java)
val b = Bundle()
b.putString("aor", aor)
b.putString("peer", uaHistory[pos].peerURI)

View File

@ -0,0 +1,205 @@
package com.tutpro.baresip
import android.app.Activity
import android.content.*
import android.os.Bundle
import android.support.v4.content.LocalBroadcastManager
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.*
class ChatActivity : AppCompatActivity() {
internal lateinit var chatMessages: ArrayList<Message>
internal lateinit var mlAdapter: MessageListAdapter
internal lateinit var newMessage: EditText
internal lateinit var sendButton: ImageButton
internal lateinit var imm: InputMethodManager
internal lateinit var aor: String
internal lateinit var peerUri: String
internal lateinit var ua: UserAgent
internal lateinit var messageResponseReceiver: BroadcastReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
aor = intent.extras.getString("aor")
peerUri = intent.extras.getString("peer")
val reply = intent.extras.getBoolean("reply")
val userAgent = Account.findUa(aor)
if (userAgent == null) {
Log.e("Baresip", "MessageActivity did not find ua of $aor")
val i = Intent()
setResult(Activity.RESULT_CANCELED, i)
finish()
} else {
ua = userAgent
}
imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
this@ChatActivity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
var chatPeer = ContactsActivity.contactName(peerUri)
if (chatPeer.startsWith("sip:")) {
if (Utils.checkTelNo(Utils.uriUserPart(peerUri)))
chatPeer = Utils.uriUserPart(peerUri)
else
chatPeer = chatPeer.substring(4)
}
setTitle("Chat with $chatPeer")
chatMessages = uaPeerMessages(aor, peerUri)
val listView = findViewById(R.id.messages) as ListView
mlAdapter = MessageListAdapter(this, chatMessages)
listView.adapter = mlAdapter
listView.isLongClickable = true
val footerView = View(applicationContext)
listView.addFooterView(footerView)
listView.smoothScrollToPosition(mlAdapter.count)
listView.onItemLongClickListener = AdapterView.OnItemLongClickListener { _, _, pos, _ ->
val dialogClickListener = DialogInterface.OnClickListener { _, which ->
when (which) {
DialogInterface.BUTTON_NEUTRAL -> {
val i = Intent(this, ContactActivity::class.java)
val b = Bundle()
b.putBoolean("new", true)
b.putString("uri", peerUri)
i.putExtras(b)
startActivityForResult(i, MainActivity.CONTACT_CODE)
}
DialogInterface.BUTTON_NEGATIVE -> {
MainActivity.messages.remove(chatMessages[pos])
chatMessages.removeAt(pos)
mlAdapter.notifyDataSetChanged()
if (chatMessages.size == 0) {
listView.removeFooterView(footerView)
}
}
DialogInterface.BUTTON_POSITIVE -> {
}
}
}
val builder = AlertDialog.Builder(this@ChatActivity, R.style.Theme_AppCompat)
if (chatPeer.contains("@") || Utils.checkTelNo(chatPeer))
builder.setMessage("Do you want to delete message or add peer $chatPeer to contacts?")
.setPositiveButton("Cancel", dialogClickListener)
.setNegativeButton("Delete Message", dialogClickListener)
.setNeutralButton("Add Contact", dialogClickListener)
.show()
else
builder.setMessage("Do you want to delete message?")
.setPositiveButton("Cancel", dialogClickListener)
.setNegativeButton("Delete Message", dialogClickListener)
.show()
true
}
newMessage = findViewById(R.id.text) as EditText
if (reply) newMessage.requestFocus()
sendButton = findViewById(R.id.sendButton) as ImageButton
sendButton.setOnClickListener {
val msgText = newMessage.text.toString()
if (msgText.length > 0) {
imm.hideSoftInputFromWindow(newMessage.windowToken, 0)
val time = System.currentTimeMillis()
val msg = Message(aor, peerUri, R.drawable.arrow_up_yellow, msgText, time,true)
MainActivity.messages.add(msg)
chatMessages.add(msg)
mlAdapter.notifyDataSetChanged()
if (message_send(ua!!.uap, peerUri, msgText, time.toString()) != 0)
Toast.makeText(getApplicationContext(), "Sending of message failed!",
Toast.LENGTH_SHORT).show()
else
newMessage.text.clear()
}
}
messageResponseReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
handleMessageResponse(intent.getIntExtra("response code", 0),
intent.getStringExtra("time"))
}
}
LocalBroadcastManager.getInstance(this).registerReceiver(messageResponseReceiver,
IntentFilter("message response"))
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.call_icon, menu)
return true
}
override fun onPause() {
ChatsActivity.saveMessages()
super.onPause()
}
override fun onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(messageResponseReceiver)
super.onDestroy()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
for (m in chatMessages) if (m.new) m.new = false
imm.hideSoftInputFromWindow(newMessage.windowToken, 0)
val i = Intent()
setResult(Activity.RESULT_OK, i)
}
R.id.callIcon -> {
val intent = Intent(this, MainActivity::class.java)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.putExtra("action", "call")
intent.putExtra("uap", ua.uap)
intent.putExtra("peer", ContactsActivity.contactName(peerUri))
startActivity(intent)
}
}
finish()
return true
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
if ((requestCode == MainActivity.CONTACT_CODE) && (resultCode == Activity.RESULT_OK)) {
setTitle("Chat with ${data.getStringExtra("name")}")
}
}
private fun uaPeerMessages(aor: String, peerUri: String): ArrayList<Message> {
val res = ArrayList<Message>()
for (m in MainActivity.messages)
if ((m.aor == aor) && (m.peerUri == peerUri)) res.add(m)
return res
}
private fun handleMessageResponse(responseCode: Int, time: String) {
val timeStamp = time.toLong()
for (m in chatMessages.reversed())
if (m.timeStamp == timeStamp) {
if (responseCode < 300)
m.direction = R.drawable.arrow_up_green
else
m.direction = R.drawable.arrow_up_red
mlAdapter.notifyDataSetChanged()
return
}
}
external fun message_send(uap: String, peer_uri: String, message: String, time: String): Int
}

View File

@ -0,0 +1,53 @@
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 ChatListAdapter(private val cxt: Context, private var 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
val contactName = ContactsActivity.contactName(message.peerUri)
if (contactName.startsWith("sip:") &&
(Utils.uriHostPart(message.peerUri) == Utils.uriHostPart(message.aor)))
peerView.text = Utils.uriUserPart(message.peerUri)
else
peerView.text = contactName
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
}
}

View File

@ -3,14 +3,11 @@ package com.tutpro.baresip
import android.app.Activity
import android.content.*
import android.os.Bundle
import android.support.v4.content.LocalBroadcastManager
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 android.widget.*
import java.io.File
import java.io.FileInputStream
@ -20,32 +17,34 @@ import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.util.*
class MessagesActivity: AppCompatActivity() {
class ChatsActivity: AppCompatActivity() {
internal lateinit var uaMessages: ArrayList<Message>
internal lateinit var aor: String
internal lateinit var mlAdapter: MessageListAdapter
internal lateinit var listView: ListView
internal lateinit var clAdapter: ChatListAdapter
internal lateinit var peerUri: AutoCompleteTextView
internal lateinit var plusButton: ImageButton
internal lateinit var serviceEventReceiver: BroadcastReceiver
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_messages)
setContentView(R.layout.activity_chats)
val listView = findViewById(R.id.messages) as ListView
listView = findViewById(R.id.chats) as ListView
plusButton = findViewById(R.id.plusButton) as ImageButton
aor = intent.extras.getString("aor")
uaMessages = uaMessages(aor)
mlAdapter = MessageListAdapter(this, uaMessages)
listView.adapter = mlAdapter
clAdapter = ChatListAdapter(this, uaMessages)
listView.adapter = clAdapter
listView.isLongClickable = true
listView.onItemClickListener = AdapterView.OnItemClickListener { _, _, pos, _ ->
val i = Intent(this@MessagesActivity, MessageActivity::class.java)
val i = Intent(this, ChatActivity::class.java)
val b = Bundle()
b.putString("aor", aor)
b.putString("peer", uaMessages[pos].peerURI)
b.putString("peer", uaMessages[pos].peerUri)
i.putExtras(b)
startActivityForResult(i, MainActivity.MESSAGE_CODE)
}
@ -57,55 +56,77 @@ class MessagesActivity: AppCompatActivity() {
val i = Intent(this, ContactActivity::class.java)
val b = Bundle()
b.putBoolean("new", true)
b.putString("uri", uaMessages[pos].peerURI)
b.putString("uri", uaMessages[pos].peerUri)
i.putExtras(b)
startActivityForResult(i, MainActivity.CONTACT_CODE)
}
DialogInterface.BUTTON_NEGATIVE -> {
MainActivity.messages.remove(uaMessages[pos])
saveMessages()
uaMessages.removeAt(pos)
if (uaMessages.size == 0) {
val i = Intent()
setResult(Activity.RESULT_CANCELED, i)
finish()
}
mlAdapter.notifyDataSetChanged()
val peerUri = uaMessages[pos].peerUri
val msgs = ArrayList<Message>()
for (m in MainActivity.messages)
if ((m.aor != aor) || (m.peerUri != peerUri))
msgs.add(m)
else
clAdapter.remove(m)
clAdapter.notifyDataSetChanged()
MainActivity.messages = msgs
uaMessages = uaMessages(aor)
}
DialogInterface.BUTTON_POSITIVE -> {
}
}
}
val builder = AlertDialog.Builder(this@MessagesActivity,
R.style.Theme_AppCompat)
if (ContactsActivity.contactName(uaMessages[pos].peerURI).startsWith("sip:"))
builder.setMessage("Do you want to add ${uaMessages[pos].peerURI} to contacs or " +
"delete message from history?")
val builder = AlertDialog.Builder(this@ChatsActivity, R.style.Theme_AppCompat)
val peer = ContactsActivity.contactName(uaMessages[pos].peerUri)
if (peer.startsWith("sip:"))
builder.setMessage("Do you want to delete chat with $peer or add peer to contacts?")
.setPositiveButton("Cancel", dialogClickListener)
.setNegativeButton("Delete Message", dialogClickListener)
.setNegativeButton("Delete Chat", dialogClickListener)
.setNeutralButton("Add Contact", dialogClickListener)
.show()
else
builder.setMessage("Do you want to delete message from history?")
builder.setMessage("Do you want to delete chat with $peer?")
.setPositiveButton("Cancel", dialogClickListener)
.setNegativeButton("Delete Message", dialogClickListener)
.setNegativeButton("Delete Chat", dialogClickListener)
.show()
true
}
peerUri = findViewById(R.id.peerUri) as AutoCompleteTextView
peerUri.threshold = 2
peerUri.setAdapter(ArrayAdapter(this, android.R.layout.select_dialog_item,
ContactsActivity.contacts.map{Contact -> Contact.name}))
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 uriText = peerUri.text.toString().trim()
if (uriText.length > 0) {
var uri = ContactsActivity.findContactURI(uriText)
if (!uri.startsWith("sip:")) {
uri = "sip:$uri"
if (!uri.contains("@")) {
val host = aor.substring(aor.indexOf("@") + 1)
uri = "$uri@$host"
}
}
if (!Utils.checkSipUri(uri)) {
Utils.alertView(this, "Notice", "Invalid SIP URI '$uri'")
} else {
peerUri.text.clear()
peerUri.isCursorVisible = false
val i = Intent(this@ChatsActivity, ChatActivity::class.java)
val b = Bundle()
b.putString("aor", aor)
b.putString("peer", uri)
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)
if (peer != "") {
val i = Intent(this, ChatActivity::class.java)
val b = Bundle()
b.putString("aor", aor)
b.putString("peer", peer)
@ -113,22 +134,17 @@ class MessagesActivity: AppCompatActivity() {
startActivityForResult(i, MainActivity.MESSAGE_CODE)
}
serviceEventReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
handleMessageResponse(intent.getIntExtra("response code", 0),
intent.getStringExtra("time"))
}
}
LocalBroadcastManager.getInstance(this).registerReceiver(serviceEventReceiver,
IntentFilter("message response"))
}
override fun onPause() {
saveMessages()
super.onPause()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
Log.d("Baresip", "Back array was pressed at Messages")
saveMessages()
Log.d("Baresip", "Back array was pressed at Chats")
val i = Intent()
setResult(Activity.RESULT_CANCELED, i)
finish()
@ -138,46 +154,32 @@ class MessagesActivity: AppCompatActivity() {
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
Log.d("Baresip", "onActivityResult at Messages")
when (requestCode) {
MainActivity.MESSAGE_CODE -> {
if (resultCode == RESULT_OK) {
mlAdapter.notifyDataSetChanged()
}
}
Log.d("Baresip", "onActivityResult $requestCode $resultCode")
if ((requestCode == MainActivity.MESSAGE_CODE) && (resultCode == Activity.RESULT_OK)) {
clAdapter.clear()
uaMessages = uaMessages(aor)
clAdapter = ChatListAdapter(this, uaMessages)
listView.adapter = clAdapter
}
}
private fun handleMessageResponse(responseCode: Int, time: String) {
if (responseCode < 300)
updateMessageDirection(time.toLong(), R.drawable.arrow_up_green)
else
updateMessageDirection(time.toLong(), R.drawable.arrow_up_red)
mlAdapter.notifyDataSetChanged()
}
fun updateMessageDirection(timeStamp: Long, direction: Int) {
for (m in uaMessages.reversed())
if (m.timeStamp == timeStamp) {
m.direction = direction
return
}
}
private fun uaMessages(aor: String) : ArrayList<Message> {
val res = ArrayList<Message>()
for (m in MainActivity.messages.reversed()) {
if (m.aor == aor) {
res.add(m)
}
if (m.aor != aor) continue
var found = false
for (r in res)
if (r.peerUri == m.peerUri) {
found = true
break
}
if (!found) 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) &&
@ -198,18 +200,6 @@ class MessagesActivity: AppCompatActivity() {
}
}
fun addMessage(message: Message) {
if ((MainActivity.messages.filter{it.aor == message.aor}).size >=
MainActivity.MESSAGE_HISTORY_SIZE)
for (i in MainActivity.messages.indices)
if (MainActivity.messages[i].aor == message.aor) {
MainActivity.messages.removeAt(i)
break
}
MainActivity.messages.add(message)
saveMessages()
}
fun saveMessages() {
val file = File(MainActivity.filesPath, "messages")
try {

View File

@ -1,5 +1,6 @@
package com.tutpro.baresip
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
@ -87,14 +88,15 @@ class ContactActivity : AppCompatActivity() {
ContactsActivity.contacts.sortBy { Contact -> Contact.name }
ContactsActivity.saveContacts()
setResult(RESULT_OK, i)
i.putExtra("name", newName)
setResult(Activity.RESULT_OK, i)
finish()
return true
} else if (item.itemId == android.R.id.home) {
Log.d("Baresip", "Back array was pressed at Contact")
setResult(RESULT_CANCELED, i)
setResult(Activity.RESULT_CANCELED, i)
finish()
return true

View File

@ -31,7 +31,7 @@ class ContactListAdapter(private val cxt: Context, private val rows: ArrayList<C
nameView.setPadding(6, 6, 0, 6)
if (aor != "") {
nameView.setOnClickListener {_ ->
val i = Intent(cxt, MessageActivity::class.java)
val i = Intent(cxt, ChatActivity::class.java)
val b = Bundle()
b.putString("aor", aor)
b.putString("peer", ContactsActivity.contacts[position].uri)

View File

@ -324,12 +324,13 @@ class MainActivity : AppCompatActivity() {
startActivityForResult(i, CONTACTS_CODE)
}
MessagesActivity.restoreMessages(applicationContext.filesDir.path)
ChatsActivity.restoreMessages(applicationContext.filesDir.path)
messagesButton.setOnClickListener {
if (aorSpinner.selectedItemPosition >= 0) {
val i = Intent(this@MainActivity, MessagesActivity::class.java)
val i = Intent(this@MainActivity, ChatsActivity::class.java)
val b = Bundle()
b.putString("aor", uas[aorSpinner.selectedItemPosition].account.aor)
b.putString("peer", "")
i.putExtras(b)
startActivityForResult(i, MESSAGES_CODE)
}
@ -642,20 +643,22 @@ class MainActivity : AppCompatActivity() {
}
}
"message" -> {
val peer_uri = params[1]
val msg = params[2]
val peerUri = params[1]
val msgText = params[2]
val time = params[3]
val new_message = Message(aor, peer_uri, R.drawable.arrow_down_green, msg,
val newMsg = Message(aor, peerUri, R.drawable.arrow_down_green, msgText,
time.toLong(), true)
Log.d("Baresip", "Incoming message $aor/$peer_uri/$msg")
MessagesActivity.addMessage(new_message)
Log.d("Baresip", "Incoming message $aor/$peerUri/$msgText")
messages.add(newMsg)
ChatsActivity.saveMessages()
if (Utils.isVisible()) {
if (ua != uas[aorSpinner.selectedItemPosition])
aorSpinner.setSelection(account_index)
val i = Intent(applicationContext, MessagesActivity::class.java)
val i = Intent(applicationContext, ChatsActivity::class.java)
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val b = Bundle()
b.putString("aor", ua.account.aor)
b.putString("peer", peerUri)
i.putExtras(b)
startActivity(i)
}
@ -670,7 +673,8 @@ class MainActivity : AppCompatActivity() {
break
}
}
if (ua == uas[aorSpinner.selectedItemPosition])
if ((aorSpinner.selectedItemPosition >= 0) &&
(ua == uas[aorSpinner.selectedItemPosition]))
if (acc.vmNew > 0)
voicemailButton.setImageResource(R.drawable.voicemail_new)
else
@ -735,7 +739,7 @@ class MainActivity : AppCompatActivity() {
val aor = ua.account.aor
when (action) {
"reply" -> {
val i = Intent(this@MainActivity, MessagesActivity::class.java)
val i = Intent(this@MainActivity, ChatActivity::class.java)
val b = Bundle()
if (ua != uas[aorSpinner.selectedItemPosition]) {
for (account_index in uas.indices) {
@ -749,15 +753,15 @@ class MainActivity : AppCompatActivity() {
b.putString("peer", intent.getStringExtra("peer"))
b.putBoolean("reply", true)
i.putExtras(b)
startActivityForResult(i, MESSAGES_CODE)
startActivityForResult(i, MESSAGE_CODE)
}
"archive" -> {
MessagesActivity.archiveUaMessage(ua.account.aor,
ChatsActivity.archiveUaMessage(ua.account.aor,
intent.getStringExtra("time").toLong())
moveTaskToBack(true)
}
"delete" -> {
MessagesActivity.deleteUaMessage(ua.account.aor,
ChatsActivity.deleteUaMessage(ua.account.aor,
intent.getStringExtra("time").toLong())
moveTaskToBack(true)
}

View File

@ -2,6 +2,6 @@ package com.tutpro.baresip
import java.io.Serializable
class Message(val aor: String, val peerURI: String, var direction: Int, val message: String,
class Message(val aor: String, val peerUri: String, var direction: Int, val message: String,
val timeStamp: Long, var new: Boolean): Serializable {
}

View File

@ -1,116 +0,0 @@
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 callButton: 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")
Log.d("Baresip", "peerURI is $peerURI")
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
title.text = "Message or call to ..."
if (peerURI == "") {
receiver.threshold = 2
receiver.setAdapter(ArrayAdapter(this, android.R.layout.select_dialog_item,
ContactsActivity.contacts.map { Contact -> Contact.name }))
receiver.requestFocus()
} else {
receiver.setText(ContactsActivity.contactName(peerURI), false)
message.requestFocus()
}
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 time = System.currentTimeMillis()
val res = message_send(ua!!.uap, uri, msg, time.toString())
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_yellow, msg, time,
false)
MessagesActivity.addMessage(new_message)
MessagesActivity.uaMessages.add(0, new_message)
val i = Intent()
setResult(Activity.RESULT_OK, i)
finish()
}
}
}
}
callButton = findViewById(R.id.callButton) as ImageButton
callButton.setOnClickListener {
imm.hideSoftInputFromWindow(receiver.getWindowToken(), 0)
imm.hideSoftInputFromWindow(message.getWindowToken(), 0)
val callIntent = Intent(this, MainActivity::class.java)
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
callIntent.putExtra("action", "call")
callIntent.putExtra("uap", ua!!.uap)
callIntent.putExtra("peer", ContactsActivity.contactName(peerURI))
startActivity(callIntent)
}
}
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, time: String) : Int
}

View File

@ -22,13 +22,6 @@ class MessageListAdapter(private val cxt: Context, private val rows: ArrayList<M
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
val contactName = ContactsActivity.contactName(message.peerURI)
if (contactName.startsWith("sip:") &&
(Utils.uriHostPart(message.peerURI) == Utils.uriHostPart(message.aor)))
peerView.text = Utils.uriUserPart(message.peerURI)
else
peerView.text = contactName
val timeView = messageView.findViewById(R.id.time) as TextView
val time: String
val cal = GregorianCalendar()
@ -43,10 +36,7 @@ class MessageListAdapter(private val cxt: Context, private val rows: ArrayList<M
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
}
if (message.new) textView.setTypeface(null, Typeface.BOLD)
return messageView
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -88,7 +88,7 @@
android:layout_height="wrap_content"
android:hint="SIP URI of Proxy Server"
android:textSize="18sp"
android:inputType="textUri"
android:inputType="textEmailAddress"
android:layout_width="fill_parent">
</EditText>
@ -97,7 +97,7 @@
android:layout_height="wrap_content"
android:hint="SIP URI of another Proxy Server"
android:textSize="18sp"
android:inputType="textUri"
android:inputType="textEmailAddress"
android:layout_width="fill_parent">
</EditText>

View File

@ -27,6 +27,7 @@
android:textSize="20sp"
android:layout_alignParentStart="true"
android:layout_marginStart="0dp"
android:layout_toLeftOf="@+id/addAccount"
android:inputType="textEmailAddress"
android:hint="SIP URI user@domain" >
</EditText>

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ChatActivity" >
<ListView
android:id="@+id/messages"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:transcriptMode="alwaysScroll"
android:layout_above="@id/text">
</ListView>
<EditText
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:inputType="textMultiLine"
android:scrollHorizontally="false"
android:importantForAutofill="no"
android:layout_alignParentBottom="true"
android:layout_marginTop="10dp"
android:layout_toStartOf="@id/sendButton"
android:hint="New message" >
</EditText>
<ImageButton
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/send"
android:background="@null"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginTop="10dp"
android:layout_marginBottom="2dp" >
</ImageButton>
</RelativeLayout>

View File

@ -7,12 +7,27 @@
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MessagesActivity">
tools:context=".ChatsActivity" >
<ListView
android:id="@+id/messages"
android:id="@+id/chats"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
android:layout_height="fill_parent" >
</ListView>
<AutoCompleteTextView
android:id="@+id/peerUri"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="18sp"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="0dp"
android:layout_toStartOf="@+id/plusButton"
android:inputType="textEmailAddress"
android:hint="Chat Peer" >
</AutoCompleteTextView>
<ImageButton
android:id="@+id/plusButton"
@ -25,5 +40,3 @@
</ImageButton>
</RelativeLayout>

View File

@ -1,68 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:orientation="vertical"
tools:context="com.tutpro.baresip.MessageActivity" >
<TextView
android:id="@+id/messageToTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="@android:color/black"
android:text="Message to ..." >
</TextView>
<AutoCompleteTextView
android:id="@+id/receiver"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:textSize="20sp"
android:hint="Contact name or SIP URI" >
<requestFocus />
</AutoCompleteTextView>
<EditText
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:inputType="textMultiLine"
android:scrollHorizontally="false"
android:hint="Message">
</EditText>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<ImageButton
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/send"
android:background="@null" >
</ImageButton>
<ImageButton
android:id="@+id/callButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:src="@drawable/call"
android:background="@null" >
</ImageButton>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/callIcon"
android:title=""
app:showAsAction="always"
android:icon="@drawable/ic_action_call"
/>
</menu>