messaging activity and listadapter stubs

messaging
Georg Lukas 2011-05-28 22:23:02 +02:00
rodzic bb12fefc4d
commit a8dd25f3bb
7 zmienionych plików z 283 dodań i 0 usunięć

Wyświetl plik

@ -33,6 +33,9 @@
<activity android:name=".StationActivity" android:label="@string/app_sta"
android:configChanges="orientation|keyboardHidden"
/>
<activity android:name=".MessageActivity" android:label="@string/app_sta"
android:configChanges="orientation|keyboardHidden"
/>
<activity android:name=".PrefsAct" android:label="@string/app_prefs" />
<activity android:name=".BackendPrefs" android:label="@string/app_prefs" />
<activity android:name=".MapAct" android:label="@string/app_map"

Wyświetl plik

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/message_act"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:descendantFocusability="blocksDescendants"
/>
<LinearLayout
android:id="@+id/buttonlayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<EditText android:id="@+id/msginput"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_weight="1"
android:inputType="textShortMessage"
/>
<Button android:id="@+id/msgsend"
android:layout_width="60sp"
android:layout_height="wrap_content"
android:text="@android:string/ok"
android:enabled="false"
/>
</LinearLayout>
</LinearLayout>

Wyświetl plik

@ -1,5 +1,6 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/details" android:title="@string/app_sta" />
<item android:id="@+id/message" android:title="Message" />
<item android:id="@+id/mapbutton" android:title="@string/sta_map" />
<item android:id="@+id/aprsfibutton" android:title="@string/sta_aprsfi" />
<item android:id="@+id/qrzcombutton" android:title="@string/sta_qrzcom" />

Wyświetl plik

@ -0,0 +1,112 @@
package org.aprsdroid.app
import _root_.android.app.ListActivity
import _root_.android.content._
import _root_.android.database.Cursor
import _root_.android.net.Uri
import _root_.android.os.{Bundle, Handler}
import _root_.android.text.{Editable, TextWatcher}
import _root_.android.util.Log
import _root_.android.view.{Menu, MenuItem, View, Window}
import _root_.android.view.View.OnClickListener
import _root_.android.widget.{Button, EditText, ListView}
class MessageActivity extends LoadingListActivity
with OnClickListener with TextWatcher {
val TAG = "APRSdroid.Message"
lazy val targetcall = getIntent().getStringExtra("call")
lazy val storage = StorageDatabase.open(this)
lazy val mycall = prefs.getCallSsid()
lazy val pla = new MessageListAdapter(this, prefs, mycall, targetcall)
lazy val locReceiver = new LocationReceiver2[Cursor](load_cursor, replace_cursor, cancel_cursor)
lazy val msginput = findView[EditText](R.id.msginput)
lazy val msgsend = findView[Button](R.id.msgsend)
override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
setContentView(R.layout.message_act)
getListView().setOnCreateContextMenuListener(this);
onStartLoading()
setListAdapter(pla)
registerReceiver(locReceiver, new IntentFilter(AprsService.UPDATE))
locReceiver.startTask(null)
msginput.addTextChangedListener(this)
msgsend.setOnClickListener(this)
setTitle(getString(R.string.app_sta) + ": " + targetcall)
}
override def onDestroy() {
super.onDestroy()
pla.onDestroy()
unregisterReceiver(locReceiver)
}
override def onCreateOptionsMenu(menu : Menu) : Boolean = {
getMenuInflater().inflate(R.menu.options, menu);
true
}
override def onListItemClick(l : ListView, v : View, position : Int, id : Long) {
//super.onListItemClick(l, v, position, id)
val c = getListView().getItemAtPosition(position).asInstanceOf[Cursor]
val call = c.getString(StorageDatabase.Position.COLUMN_CALL)
Log.d("MessageActivity", "onListItemClick: %s".format(call))
if (targetcall == call) {
// click on own callssid
trackOnMap(call)
} else {
openDetails(call)
finish()
}
}
// TextWatcher for msginput
override def afterTextChanged(s : Editable) {
msgsend.setEnabled(msginput.getText().length() > 0)
}
override def beforeTextChanged(s : CharSequence, start : Int, before : Int, count : Int) {
}
override def onTextChanged(s : CharSequence, start : Int, before : Int, count : Int) {
}
def sendMessage() {
val msg = msginput.getText().toString()
if (msg.length() == 0)
return
Log.d("MessageActivity", "sending " + msg)
msginput.setText(null)
}
// button actions
override def onClick(view : View) {
Log.d(TAG, "onClick: " + view.getId)
view.getId match {
case R.id.msgsend =>
sendMessage()
true
case _ => false
}
}
def load_cursor(i : Intent) = {
val c = storage.getStaPosts(targetcall, "100")
c.getCount()
c
}
def replace_cursor(c : Cursor) {
// do not call onStopLoading, PositionListAdapter takes much longer
//onStopLoading()
}
def cancel_cursor(c : Cursor) {
c.close()
}
}

Wyświetl plik

@ -0,0 +1,112 @@
package org.aprsdroid.app
import _root_.android.app.Activity
import _root_.android.content._
import _root_.android.database.Cursor
import _root_.android.os.{AsyncTask, Bundle, Handler}
import _root_.android.text.format.DateUtils
import _root_.android.util.Log
import _root_.android.view.View
import _root_.android.widget.{SimpleCursorAdapter, TextView}
object MessageListAdapter {
import StorageDatabase.Position._
val LIST_FROM = Array(CALL, COMMENT, QRG)
val LIST_TO = Array(R.id.station_call, R.id.listmessage, R.id.station_qrg)
val SINGLE = 0
val NEIGHBORS = 1
val SSIDS = 2
}
class MessageListAdapter(context : Context, prefs : PrefsWrapper,
mycall : String, targetcall : String)
extends SimpleCursorAdapter(context, R.layout.stationview, null, MessageListAdapter.LIST_FROM, MessageListAdapter.LIST_TO) {
var my_lat = 0
var my_lon = 0
var reload_pending = 0
lazy val storage = StorageDatabase.open(context)
reload()
lazy val locReceiver = new LocationReceiver2(load_cursor,
replace_cursor, cancel_cursor)
context.registerReceiver(locReceiver, new IntentFilter(AprsService.UPDATE))
def getAgeColor(ts : Long) : Int = {
val DARK = Array(0xff, 0x60, 0x60, 0x40)
val BRIGHT = Array(0xff, 0xff, 0xff, 0xc0)
val MAX = 30*60*1000
val delta = (System.currentTimeMillis - ts).toInt
val factor = if (delta < MAX) delta else MAX
val mix = DARK zip BRIGHT map (t => { t._2 - (t._2 - t._1)*factor/MAX } )
mix.reduceLeft(_*256 + _)
}
// return compass bearing for a given value
private val LETTERS = Array("N", "NE", "E", "SE", "S", "SW", "W", "NW")
def getBearing(b : Double) = LETTERS(((b.toInt + 22 + 720) % 360) / 45)
override def bindView(view : View, context : Context, cursor : Cursor) {
import StorageDatabase.Position._
// TODO: multidimensional mapping
val distage = view.findViewById(R.id.station_distage).asInstanceOf[TextView]
val call = cursor.getString(COLUMN_CALL)
val ts = cursor.getLong(COLUMN_TS)
val age = DateUtils.getRelativeTimeSpanString(context, ts)
val lat = cursor.getInt(COLUMN_LAT)
val lon = cursor.getInt(COLUMN_LON)
val dist = Array[Float](0, 0)
if (call == mycall) {
view.setBackgroundColor(0x4020ff20)
} else if (call == targetcall) {
view.setBackgroundColor(0x402020ff)
} else
view.setBackgroundColor(0)
distage.setTextColor(getAgeColor(ts))
view.findViewById(R.id.station_call).asInstanceOf[TextView].setTextColor(getAgeColor(ts))
view.findViewById(R.id.station_qrg).asInstanceOf[TextView].setTextColor(getAgeColor(ts))
val MCD = 1000000.
android.location.Location.distanceBetween(my_lat/MCD, my_lon/MCD,
lat/MCD, lon/MCD, dist)
distage.setText("%1.1f km %s\n%s".format(dist(0)/1000., getBearing(dist(1)), age))
super.bindView(view, context, cursor)
}
def load_cursor(i : Intent) = {
import MessageListAdapter._
Benchmark("get my position") {
val cursor = storage.getStaPosition(mycall)
if (cursor.getCount() > 0) {
cursor.moveToFirst()
my_lat = cursor.getInt(StorageDatabase.Position.COLUMN_LAT)
my_lon = cursor.getInt(StorageDatabase.Position.COLUMN_LON)
}
cursor.close()
}
val c = storage.getAllSsids(targetcall)
Benchmark("getCount") { c.getCount() }
c
}
def replace_cursor(c : Cursor) {
changeCursor(c)
context.asInstanceOf[LoadingIndicator].onStopLoading()
}
def cancel_cursor(c : Cursor) {
c.close()
}
def reload() {
locReceiver.startTask(null)
}
def onDestroy() {
context.unregisterReceiver(locReceiver)
changeCursor(null)
}
}

Wyświetl plik

@ -88,9 +88,19 @@ object StorageDatabase {
val TABLE = "message"
val _ID = "_id"
val TS = "ts"
val NEXTTS = "nextts"
val CALL = "call"
val MSGID = "msgid"
val TYPE = "type"
val TEXT = "text"
lazy val TABLE_CREATE = """CREATE TABLE %s (%s INTEGER PRIMARY KEY AUTOINCREMENT,
%s LONG, %s LONG,
%s TEXT, %s TEXT,
%s INTEGER, %s TEXT)"""
.format(TABLE, _ID, TS, NEXTTS,
CALL, MSGID,
TYPE, TEXT)
lazy val COLUMNS = Array(_ID, TS, NEXTTS, CALL, MSGID, TYPE, TEXT)
}
var singleton : StorageDatabase = null

Wyświetl plik

@ -28,6 +28,10 @@ trait UIHelper extends Activity
startActivity(new Intent(this, classOf[StationActivity]).putExtra("call", call))
}
def openMessaging(call : String) {
startActivity(new Intent(this, classOf[MessageActivity]).putExtra("call", call))
}
def trackOnMap(call : String) {
val text = getString(R.string.map_track_call, call)
Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
@ -260,6 +264,9 @@ trait UIHelper extends Activity
case R.id.details =>
openDetails(targetcall)
true
case R.id.message =>
openMessaging(targetcall)
true
case R.id.mapbutton =>
trackOnMap(targetcall)
true