From e2ee8522364fdf655545680242050605b18fed5d Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Tue, 13 Mar 2018 16:55:45 +1300 Subject: [PATCH] improved call history fixed some bugs --- .../main/java/com/tutpro/baresip/History.java | 20 ++- .../com/tutpro/baresip/HistoryActivity.java | 117 ++++++++++++++---- .../tutpro/baresip/HistoryListAdapter.java | 38 ++++++ .../java/com/tutpro/baresip/HistoryRow.java | 19 +++ .../java/com/tutpro/baresip/MainActivity.java | 72 +++++++++-- .../main/java/com/tutpro/baresip/Utils.java | 2 +- .../main/res/drawable/arrow_down_green.png | Bin 0 -> 521 bytes app/src/main/res/drawable/arrow_down_red.png | Bin 0 -> 525 bytes app/src/main/res/drawable/arrow_up_green.png | Bin 0 -> 520 bytes app/src/main/res/drawable/arrow_up_red.png | Bin 0 -> 521 bytes 10 files changed, 225 insertions(+), 43 deletions(-) create mode 100644 app/src/main/java/com/tutpro/baresip/HistoryListAdapter.java create mode 100644 app/src/main/java/com/tutpro/baresip/HistoryRow.java create mode 100644 app/src/main/res/drawable/arrow_down_green.png create mode 100644 app/src/main/res/drawable/arrow_down_red.png create mode 100644 app/src/main/res/drawable/arrow_up_green.png create mode 100644 app/src/main/res/drawable/arrow_up_red.png diff --git a/app/src/main/java/com/tutpro/baresip/History.java b/app/src/main/java/com/tutpro/baresip/History.java index 929134e4..111126f9 100644 --- a/app/src/main/java/com/tutpro/baresip/History.java +++ b/app/src/main/java/com/tutpro/baresip/History.java @@ -7,18 +7,26 @@ public class History implements Serializable { private static final long serialVersionUID = -299482035708790407L; - private String aor, peer_uri, direction; + private String ua, call, aor, peer_uri, direction; private GregorianCalendar time; + private Boolean connected; - public History(String aor, String peer_uri, String direction) { - this.aor = aor; - this.peer_uri = peer_uri; - this.direction = direction; - this.time = new GregorianCalendar(); + public History(String ua, String call, String aor, String peer_uri, String direction, + Boolean connected) { + this.ua = ua; + this.call = call; + this.aor = aor; + this.peer_uri = peer_uri; + this.direction = direction; + this.time = new GregorianCalendar(); + this.connected = connected; } + public String getUA() { return ua; } + public String getCall() { return call; } public String getAoR() { return aor; } public String getPeerURI() { return peer_uri; } public String getDirection() { return direction; } public GregorianCalendar getTime() { return time; } + public Boolean getConnected() { return connected; } } diff --git a/app/src/main/java/com/tutpro/baresip/HistoryActivity.java b/app/src/main/java/com/tutpro/baresip/HistoryActivity.java index e1b490b2..321342fa 100644 --- a/app/src/main/java/com/tutpro/baresip/HistoryActivity.java +++ b/app/src/main/java/com/tutpro/baresip/HistoryActivity.java @@ -1,24 +1,25 @@ package com.tutpro.baresip; +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.view.View; import android.widget.AdapterView; -import android.widget.ArrayAdapter; import android.widget.ListView; -import android.widget.TextView; -import android.widget.AdapterView.OnItemClickListener; +import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; +import java.util.Calendar; +import java.util.GregorianCalendar; public class HistoryActivity extends AppCompatActivity { - static ArrayList history = new ArrayList<>(); + ArrayList uaHistory = new ArrayList<>(); + ArrayList posAtHistory = new ArrayList<>(); @Override public void onCreate(Bundle savedInstanceState) { @@ -27,27 +28,56 @@ public class HistoryActivity extends AppCompatActivity { final ListView listview = (ListView) findViewById(R.id.history); - ArrayList history = new ArrayList<>(); - for (Integer i = MainActivity.History.size() - 1; i >= 0; i--) { - History h = MainActivity.History.get(i); - if (h.getAoR().equals(MainActivity.ua_aor(MainActivity.ua_current()))) { - if (!history.contains(h.getPeerURI())) history.add(h.getPeerURI()); - } - } + generate_ua_history(); - ArrayAdapter adapter = new ArrayAdapter<>(this, - android.R.layout.simple_list_item_1, history); + final HistoryListAdapter adapter = new HistoryListAdapter(this, uaHistory); listview.setAdapter(adapter); + listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, final View view, int position, long id) { + HistoryRow row = uaHistory.get(position); + Intent i = new Intent(); + i.putExtra("peer_uri", row.getPeerURI()); + setResult(RESULT_OK, i); + finish(); + } + }); - listview.setOnItemClickListener(new OnItemClickListener() { - public void onItemClick(AdapterView parent, View view, - int position, long id) { - Intent i = new Intent(); - i.putExtra("peer_uri", ((TextView) view).getText()); - setResult(RESULT_OK, i); - finish(); - } - }); + listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, final int pos, long id) { + DialogInterface.OnClickListener dialogClickListener = + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which){ + case DialogInterface.BUTTON_POSITIVE: + MainActivity.History.remove((posAtHistory.get(pos)).intValue()); + generate_ua_history(); + if (uaHistory.size() == 0) { + Intent i = new Intent(); + setResult(RESULT_CANCELED, i); + finish(); + } + adapter.notifyDataSetChanged(); + break; + case DialogInterface.BUTTON_NEGATIVE: + break; + } + } + }; + AlertDialog.Builder builder = + new AlertDialog.Builder(HistoryActivity.this, + R.style.Theme_AppCompat); + builder.setMessage("Do you want to delete " + + MainActivity.History.get(pos).getPeerURI() + "?") + .setPositiveButton("Yes", dialogClickListener) + .setNegativeButton("No", dialogClickListener).show(); + return true; + } + }); + + listview.setLongClickable(true); } @Override @@ -63,4 +93,43 @@ public class HistoryActivity extends AppCompatActivity { return true; } + private void generate_ua_history() { + uaHistory.clear(); + posAtHistory.clear(); + for (Integer i = MainActivity.History.size() - 1; i >= 0; i--) { + History h = MainActivity.History.get(i); + if (h.getAoR().equals(MainActivity.ua_aor(MainActivity.ua_current()))) { + String time; + if (isToday(h.getTime())) { + SimpleDateFormat fmt = new SimpleDateFormat("HH:mm"); + time = fmt.format(h.getTime().getTime()); + } else { + SimpleDateFormat fmt = new SimpleDateFormat("MMM dd"); + time = fmt.format(h.getTime().getTime()); + } + if (h.getDirection().equals("in")) { + if (h.getConnected()) { + uaHistory.add(new HistoryRow(h.getPeerURI(), R.drawable.arrow_down_green, time)); + } else { + uaHistory.add(new HistoryRow(h.getPeerURI(), R.drawable.arrow_down_red, time)); + } + } else { + if (h.getConnected()) { + uaHistory.add(new HistoryRow(h.getPeerURI(), R.drawable.arrow_up_green, time)); + } else { + uaHistory.add(new HistoryRow(h.getPeerURI(), R.drawable.arrow_up_red, time)); + } + } + posAtHistory.add(i); + } + } + } + + private Boolean isToday(GregorianCalendar time) { + GregorianCalendar now = new GregorianCalendar(); + return now.get(Calendar.YEAR) == time.get(Calendar.YEAR) && + now.get(Calendar.MONTH) == time.get(Calendar.MONTH) && + now.get(Calendar.DAY_OF_MONTH) == time.get(Calendar.DAY_OF_MONTH); + } + } diff --git a/app/src/main/java/com/tutpro/baresip/HistoryListAdapter.java b/app/src/main/java/com/tutpro/baresip/HistoryListAdapter.java new file mode 100644 index 00000000..4940addf --- /dev/null +++ b/app/src/main/java/com/tutpro/baresip/HistoryListAdapter.java @@ -0,0 +1,38 @@ +package com.tutpro.baresip; + +import android.content.Context; +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.util.ArrayList; + +public class HistoryListAdapter extends ArrayAdapter { + + private Context context; + private ArrayList rows; + + public HistoryListAdapter(Context context, ArrayList rows) { + super(context, R.layout.history_row, rows); + this.context = context; + this.rows = rows; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + HistoryRow row = rows.get(position); + LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View rowView = inflater.inflate(R.layout.history_row, parent, false); + ImageView directionView = (ImageView) rowView.findViewById(R.id.direction); + directionView.setImageResource(row.getDirection()); + TextView peerURIView = (TextView) rowView.findViewById(R.id.peer_uri); + peerURIView.setText(row.getPeerURI()); + TextView timeView = (TextView) rowView.findViewById(R.id.time); + timeView.setText(row.getTime()); + return rowView; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/tutpro/baresip/HistoryRow.java b/app/src/main/java/com/tutpro/baresip/HistoryRow.java new file mode 100644 index 00000000..a18daed4 --- /dev/null +++ b/app/src/main/java/com/tutpro/baresip/HistoryRow.java @@ -0,0 +1,19 @@ +package com.tutpro.baresip; + +public class HistoryRow { + + private String peer_uri; + private Integer direction; + private String time; + + public HistoryRow(String peer_uri, Integer direction, String time) { + this.peer_uri = peer_uri; + this.direction = direction; + this.time = time; + } + + public String getPeerURI() { return peer_uri; } + public Integer getDirection() { return direction; } + public String getTime() { return time; } + +} diff --git a/app/src/main/java/com/tutpro/baresip/MainActivity.java b/app/src/main/java/com/tutpro/baresip/MainActivity.java index fea19384..a3b4108f 100644 --- a/app/src/main/java/com/tutpro/baresip/MainActivity.java +++ b/app/src/main/java/com/tutpro/baresip/MainActivity.java @@ -18,7 +18,6 @@ import android.widget.AutoCompleteTextView; import android.view.*; import android.util.Log; import android.content.Context; -import android.text.format.Time; import java.util.*; import java.io.*; @@ -38,7 +37,7 @@ public class MainActivity extends AppCompatActivity { static ArrayAdapter CalleeAdapter = null; static ArrayList In = new ArrayList<>(); static ArrayList Out = new ArrayList<>(); - static ArrayList History = new ArrayList(); + static ArrayList History = new ArrayList<>(); static String CurrentUA = null; private static final int RECORD_AUDIO_PERMISSION = 1; @@ -80,7 +79,7 @@ public class MainActivity extends AppCompatActivity { } else { callee.setText(out.get(0).getPeerURI()); callButton.setText(out.get(0).getStatus()); - if (out.get(0).getStatus() == "Hangup") { + if (out.get(0).getStatus().equals("Hangup")) { if (out.get(0).getHold()) { holdButton.setText("Unhold"); } else { @@ -113,8 +112,7 @@ public class MainActivity extends AppCompatActivity { "error.wav", "message.wav", "notfound.wav", "ring.wav", "ringback.wav"}; final String path = mainActivityContext.getFilesDir().getPath(); Log.d("Baresip", "path is: " + path); - File file; - file = new File(path); + File file = new File(path); if (!file.exists()) { Log.d("Baresip", "Creating baresip directory"); try { @@ -128,12 +126,24 @@ public class MainActivity extends AppCompatActivity { file = new File(path + "/" + a); if (!file.exists()) { Log.d("Baresip", "Copying asset " + a); - copyAsset(a, path + "/" + a); + copyAssetToFile(a, path + "/" + a); } else { Log.d("Baresip", "Asset " + a + " already copied"); } } + file = new File(path, "history"); + try { + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis); + History = (ArrayList)ois.readObject(); + Log.d("Baresip", "Restored History"); + ois.close(); + fis.close(); + } catch (Exception e) { + Log.w("Baresip", "InputStream exception: - " + e.toString()); + } + if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { Log.d("Baresip", "Baresip does not have RECORD_AUDIO permission"); @@ -266,10 +276,23 @@ public class MainActivity extends AppCompatActivity { case R.id.quit: if (running) { Log.d("Baresip", "Stopping"); - baresipStop(); + final String path = mainActivityContext.getFilesDir().getPath(); + File file = new File(path,"history"); + try { + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(History); + oos.close(); + fos.close(); + } catch (IOException e) { + Log.w("Baresip", "OutputStream exception: " + e.toString()); + e.printStackTrace(); + } + History.clear(); Accounts.clear(); AoRs.clear(); Images.clear(); + baresipStop(); running = false; } finish(); @@ -315,6 +338,9 @@ public class MainActivity extends AppCompatActivity { } if(resultCode == RESULT_CANCELED) { Log.d("Baresip", "History canceled"); + if (!aorHasHistory(History, ua_aor(ua_current()))) { + holdButton.setVisibility(View.INVISIBLE); + } } } if ((requestCode == EDIT_CONTACTS_CODE) || (requestCode == ABOUT_CODE)) { @@ -352,13 +378,13 @@ public class MainActivity extends AppCompatActivity { Log.i("Baresip", "Adding outgoing call " + CurrentUA + "/" + call + "/" + uri); Out.add(new Call(CurrentUA, call, uri, "Cancel")); - History.add(new History(ua_aor(CurrentUA), uri, "out")); + // History.add(new History(ua_aor(CurrentUA), uri, "out")); callButton.setText("Cancel"); holdButton.setVisibility(View.INVISIBLE); } } - private void copyAsset(String asset, String path) { + private void copyAssetToFile(String asset, String path) { try { AssetManager assetManager = getAssets(); InputStream is = assetManager.open(asset); @@ -457,7 +483,7 @@ public class MainActivity extends AppCompatActivity { layout.addView(answer_button); Button reject_button = new Button(mainActivityContext); - if (call.getStatus() == "Answer") { + if (call.getStatus().equals("Answer")) { reject_button.setText("Reject"); } else { if (call.getHold()) { @@ -523,11 +549,20 @@ public class MainActivity extends AppCompatActivity { return false; } + private Boolean callHasHistory(ArrayList history, String ua, String call) { + for (History h : history) { + if (h.getUA().equals(ua) && h.getCall().equals(call)) return true; + } + return false; + } + private void updateStatus(String event, final String ua, final String call) { String aor = ua_aor(ua); int call_index; + Log.d("Baresip", "Handling event " + event + " for " + ua + "/" + call + "/" + aor); + for (int account_index = 0; account_index < Accounts.size(); account_index++) { if (Accounts.get(account_index).getAoR().equals(aor)) { Log.d("Baresip", "Found AoR at index " + account_index); @@ -579,7 +614,12 @@ public class MainActivity extends AppCompatActivity { } }); } + History.add(new History(ua, call, aor, call_peeruri(call), + "out", true)); break; + } else { + History.add(new History(ua, call, aor, call_peeruri(call), + "in", true)); } Log.e("Baresip", "Unknown call " + ua + "/" + call + " established"); @@ -590,7 +630,7 @@ public class MainActivity extends AppCompatActivity { peer_uri); final Call new_call = new Call(ua, call, peer_uri, "Answer"); In.add(new_call); - History.add(new History(aor, peer_uri, "in")); + // History.add(new History(aor, call_peeruri(call), "in")); Log.d("Baresip", "Current UA is " + CurrentUA); if (ua.equals(CurrentUA)) { runOnUiThread(new Runnable() { @@ -631,12 +671,16 @@ public class MainActivity extends AppCompatActivity { } }); } + if (!callHasHistory(History, ua, call)) { + History.add(new History(ua, call, aor, call_peeruri(call), + "in", false)); + } break; } call_index = callIndex(Out, ua, call); Log.d("Baresip", "Outgoing call index is " + call_index); if (call_index != -1) { - Log.d("Baresip", "Removing called call " + ua + "/" + + Log.d("Baresip", "Removing outgoing call " + ua + "/" + call + "/" + Out.get(call_index).getPeerURI()); Out.remove(call_index); if (ua.equals(CurrentUA)) { @@ -652,6 +696,10 @@ public class MainActivity extends AppCompatActivity { } }); } + if (!callHasHistory(History, ua, call)) { + History.add(new History(ua, call, aor, call_peeruri(call), + "out", false)); + } break; } Log.e("Baresip", "Unknown call " + ua + "/" + call + diff --git a/app/src/main/java/com/tutpro/baresip/Utils.java b/app/src/main/java/com/tutpro/baresip/Utils.java index e590ed4b..a4fc6cec 100644 --- a/app/src/main/java/com/tutpro/baresip/Utils.java +++ b/app/src/main/java/com/tutpro/baresip/Utils.java @@ -4,7 +4,6 @@ import android.content.Context; import android.content.DialogInterface; import android.support.v7.app.AlertDialog; import android.util.Log; -import android.widget.Toast; import java.io.File; import java.io.FileInputStream; @@ -68,4 +67,5 @@ public class Utils { }); alertDialog.show(); } + } diff --git a/app/src/main/res/drawable/arrow_down_green.png b/app/src/main/res/drawable/arrow_down_green.png new file mode 100644 index 0000000000000000000000000000000000000000..a624261b85b0d335e4070dd699dc53ad03754627 GIT binary patch literal 521 zcmV+k0`~ohP)0P(n*KKMvQ?b8h%;uu~TTS zBcRU#=Pb#vg$=JPIJ0*^gcOYc=p6MAKpX%uGVJRPh`YY#gE2+VUI4RZ+;YdLNQ_<# z1W+1ch9qX)GpW?x!VNPf+!cwHq+Yuz#b(G}!v#4L<{UKTkgH0ls6?h+a>^r-SQKhn zR#8;a3~OBT#&@6en^X(Kt!wz;Vxm`7!Fl@~5hKB%ak;RK2>k}7##`++vEik+ZYNgM ztSKuxEAOaW=y}H+V@o6p8`;9T=U%vM$?pVI)qPbq>a+nvt?Y5Qg|ajJ@XS*sOKL*F z+xntmUD=qE@(SWs_U%*0H;+9rWl?>{mb5K(MZ>DH5hvsgx0yei_s|uK8h=}oT|c90 z)3SbmMvjF000000 LNkvXXu0mjf0F&sj literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/arrow_down_red.png b/app/src/main/res/drawable/arrow_down_red.png new file mode 100644 index 0000000000000000000000000000000000000000..bfba313d0bb6d1f69581830a42a4d8a1650ac339 GIT binary patch literal 525 zcmV+o0`mQdP)5Da6WQU?G40h&of zK~y-)jndCcR8bhl@z1?8-ZUp6qJ^76Mn`lZK~eMrYS%V$KnfyIg#Lv3BiglU6`>H$ z6xAYHv~Q7>#6Zge&4kK~AR5P+X>rex(jD{Nox}Tl-}gDsiDcAa;t|H6jRwCK`Hejn+dkU^g1q(pJ47FQ-`=(MwMzb&81U3jEJMK z(lXT&<#vd1o!8&^*w17=Jnklq_gu{NvRdT)evZV*VUY2BNFzc&g9+oEwcBa5FWzuF zw?ciLN{O=tj^=~sjyO)EjG7^l7B+bHoXa(S=U|o1FH}Z3J-|?Yn>Y$n8v*d0r%x!? z(x;K@to51329+^R7AVGlr)#C2edW<(rk2v99ROINu|{Qt69tC1i$AgOfGbPsGBN?d z&ek&3VUG1tYGRG~Ij+4+UHtRyGwV3XbrzcZxX<+44Do-fNKdiLckk36o4IWRTfO|- P00000NkvXXu0mjfk5=yl literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/arrow_up_green.png b/app/src/main/res/drawable/arrow_up_green.png new file mode 100644 index 0000000000000000000000000000000000000000..5538f0ee57aba9c4616d0257622988982c502a5c GIT binary patch literal 520 zcmV+j0{8uiP)aE!rxErS?dC6Y?ZUu6b0+ zbx#CMuS{Cj>Lp8inrq4?JhM+-0XL+|Zdua&S6bX;K4F`>8AGlqAz+tdhK%}Y&Z>4k zpk}+eIeT4Eh_@xQvD1h_H9ySyyaCw&oKkhwO9RFw(O8N_mXV>)Q3sv&%dAhGH|YS5 z+hN?iewP$ciKaq)<|G0VR2^~18ErE@XcnE+=dyYIE=pt8GEzZ^T`I&fLWEQtcECB` z%@hneuWC%_60Di_MMJipIau+WxX-ZL1tZ1^UR&_q9YITmRSzwiLVF#WVaaW4rsG-5 zJChz+?99OnkEIg(jahKlip)eb2ebqqwXB$O({EqB@xarqC-I(T14bn%%G_7c*gQyS zF5nNEU7g5@d_X$_k_gF({Hv_1by-~h>o=Y?tgIqI5WLmsCHo6efO1;*9&qRY0000< KMNUMnLSTY`Ki!xB literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/arrow_up_red.png b/app/src/main/res/drawable/arrow_up_red.png new file mode 100644 index 0000000000000000000000000000000000000000..10fc2bc671cbf8daa18afb5dd1e75eb28d9b569e GIT binary patch literal 521 zcmV+k0`~ohP)!3LE{p6q2R#&wbkHrJ7S`z& z0vc?cVqp)LYD(j1{C9;>ZC`{bc@Qm`Mqa zv2B8vySP|FHJIWs