Add new icons for osmo plugin and enable ui

This commit is contained in:
vshcherb 2014-05-24 02:04:04 +02:00
parent 1d0fbad437
commit 430e21cea0
17 changed files with 306 additions and 59 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 B

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right" >
<Switch
android:id="@+id/check_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:gravity="center_vertical"
android:visibility="gone" />
</LinearLayout>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<Switch android:id="@+id/enable_tracker" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:focusable="false" android:text="@string/osmo_enable_tracker"/>
</LinearLayout>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right" >
<CheckBox
android:id="@+id/check_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:gravity="center_vertical"
android:visibility="gone" />
</LinearLayout>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="?attr/expandable_category_color"
android:paddingBottom="5dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingTop="5dp" >
<ImageView
android:id="@+id/explist_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingLeft="6dp"
android:src="@drawable/expandable_category_unpushed" />
<TextView
android:id="@+id/category_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="0dp"
android:autoLink="web"
android:gravity="center_vertical"
android:textSize="18sp">
</TextView>
<include layout="@layout/check_item"/>
</LinearLayout>

View file

@ -7,15 +7,11 @@
android:paddingRight="4dp"
android:paddingTop="5dp">
<!-- <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content">
<CheckBox android:id="@+id/check_item" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:focusable="false" android:visibility="gone"/>
</LinearLayout> -->
<ImageView android:id="@+id/osmo_user_icon" android:layout_width="26dp" android:layout_height="26dp" android:paddingRight="2dp" android:paddingTop="2dp"
/>
<TextView android:id="@+id/osmo_label" android:layout_width="wrap_content" android:layout_marginLeft="10dp"
android:layout_height="wrap_content" style="@style/ListText"/>
<include layout="@layout/check_item"/>
</LinearLayout>

View file

@ -5,8 +5,7 @@
android:orientation="vertical"
>
<include layout="@layout/osmo_groups_list_header"/>
<ExpandableListView
android:id="@android:id/list"
android:layout_width="fill_parent"

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<CheckBox android:id="@+id/enable_tracker" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:focusable="false" android:text="@string/osmo_enable_tracker"/>
</LinearLayout>

View file

@ -9,6 +9,9 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
-->
<string name="osmo_activity">Osm Monitoring</string>
<string name="osmo_enable_tracker">Send my locations</string>
<string name="osmo_control">OsMo quick access</string>
<string name="hours_ago">hours ago</string>
<string name="minutes_ago">min ago</string>
<string name="seconds_ago">sec ago</string>
@ -33,6 +36,7 @@
<string name="tip_recent_changes_1_8_alpha">Changes in 1.8:
* Calculate route between route points of GPX track
* Changed layout of countries for downloads (support local names search)
* Supports GPX/KML import (convert from KML to GPX)
</string>
<string name="use_points_as_intermediates">Calculate route between points</string>
<string name="osmo_mode_restart">Restart OsMo session</string>

View file

@ -309,16 +309,33 @@ public class OsMoGroups implements OsMoReactor {
}
public void joinGroup(String groupId) {
service.pushCommand("JOIN_GROUP|"+groupId);
service.pushCommand("GROUP_JOIN:"+groupId);
}
public void createGroup(String groupName) {
service.pushCommand("CREATE_GROUP|{\"group_name\":\"" + groupName + "\"}");
public void connectGroup(String groupId) {
service.pushCommand("GROUP_CONNECT:"+groupId);
}
public void disconnectGroup(String groupId) {
service.pushCommand("GROUP_DISCONNECT:"+groupId);
}
public void createGroup(String groupName, long expireTime, String description, String policy) {
JSONObject obj = new JSONObject();
try {
obj.put("name", groupName);
obj.put("expireTime", expireTime);
obj.put("description", description);
obj.put("policy", policy);
service.pushCommand("AGROUP_CREATE|" + obj.toString());
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
public void leaveGroup(OsMoGroup group) {
service.pushCommand("LEAVE_GROUP|"+group.groupId);
service.pushCommand("GROUP_LEAVE:"+group.groupId);
}

View file

@ -7,6 +7,7 @@ import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@ -50,13 +51,17 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
import com.actionbarsherlock.view.ActionMode.Callback;
/**
*
@ -65,7 +70,7 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
OsmAndLocationListener, OsmoTrackerListener {
public static final int CONNECT_TO_DEVICE = 1;
public static final int DELETE_ID = 2;
protected static final int DELETE_ACTION_ID = 2;
public static final int CREATE_GROUP = 3;
public static final int JOIN_GROUP = 4;
private static final int LIST_REFRESH_MSG_ID = OsmAndConstants.UI_HANDLER_SEARCH + 30;
@ -82,6 +87,9 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
private Path directionPath = new Path();
private Location lastLocation;
private float lastCompass;
private ActionMode actionMode;
private boolean selectionMode;
private Set<OsMoUser> selectedObjects = new HashSet<OsMoGroups.OsMoUser>();
@Override
public void onCreate(Bundle icicle) {
@ -90,18 +98,31 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
getSherlock().setUiOptions(ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW);
super.onCreate(icicle);
setContentView(R.layout.favourites_list);
getSupportActionBar().setTitle(R.string.favourites_activity);
setContentView(R.layout.osmo_groups_list);
getSupportActionBar().setTitle(R.string.osmo_activity);
setSupportProgressBarIndeterminateVisibility(false);
// getSupportActionBar().setIcon(R.drawable.tab_search_favorites_icon);
osMoPlugin = OsmandPlugin.getEnabledPlugin(OsMoPlugin.class);
adapter = new OsMoGroupsAdapter(osMoPlugin.getGroups(), osMoPlugin.getTracker());
getExpandableListView().setAdapter(adapter);
app = (OsmandApplication) getApplication();
uiHandler = new Handler();
directionPath = createDirectionPath();
CompoundButton trackr = (CompoundButton) findViewById(R.id.enable_tracker);
trackr.setChecked(osMoPlugin.getTracker().isEnabledTracker());
trackr.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
osMoPlugin.getTracker().enableTracker();
} else {
osMoPlugin.getTracker().disableTracker();
}
}
});
}
private Path createDirectionPath() {
@ -151,18 +172,44 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
app.getLocationProvider().removeLocationListener(this);
osMoPlugin.getTracker().setTrackerListener(null);
}
private void enterSelectionMode() {
actionMode = startActionMode(new Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
selectionMode = true;
createMenuItem(menu, DELETE_ACTION_ID, R.string.default_buttons_delete, R.drawable.ic_action_delete_light, R.drawable.ic_action_delete_dark,
MenuItem.SHOW_AS_ACTION_IF_ROOM);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
selectionMode = false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if(item.getItemId() == DELETE_ACTION_ID) {
}
return true;
}
});
}
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
// if(selectionMode){
// CheckBox ch = (CheckBox) v.findViewById(R.id.check_item);
// FavouritePoint model = adapter.getChild(groupPosition, childPosition);
// ch.setChecked(!ch.isChecked());
// if(ch.isChecked()){
// favoritesToDelete.add(model);
// } else {
// favoritesToDelete.remove(model);
// }
if (!selectionMode) {
enterSelectionMode();
}
OsMoUser user = adapter.getChild(groupPosition, childPosition);
selectedObjects.add(user);
return true;
}
@ -174,12 +221,6 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
} else if (item.getItemId() == JOIN_GROUP) {
// shareFavourites();
return true;
} else if (item.getItemId() == DELETE_ID) {
// enterDeleteMode();
return true;
} else if (item.getItemId() == CREATE_GROUP) {
// deleteFavoritesAction();
return true;
} else {
return super.onOptionsItemSelected(item);
}
@ -210,12 +251,6 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
R.drawable.ic_action_marker_dark, MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
createMenuItem(menu, JOIN_GROUP, R.string.osmo_join_group, R.drawable.ic_action_markers_light,
R.drawable.ic_action_markers_dark, MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
// createMenuItem(menu, IMPORT_ID, R.string.import_fav, R.drawable.ic_action_grefresh_light,
// R.drawable.ic_action_grefresh_dark,
// MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
// createMenuItem(menu, DELETE_ID, R.string.default_buttons_delete, R.drawable.ic_action_delete_light,
// R.drawable.ic_action_delete_dark,
// MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT) ;
return super.onCreateOptionsMenu(menu);
}
@ -337,33 +372,22 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
View row = convertView;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.expandable_list_item_category, parent, false);
row = inflater.inflate(R.layout.osmo_group_item, parent, false);
fixBackgroundRepeat(row);
}
adjustIndicator(groupPosition, isExpanded, row);
TextView label = (TextView) row.findViewById(R.id.category_name);
final OsMoGroup model = getGroup(groupPosition);
label.setText(model.getVisibleName(OsMoGroupsActivity.this));
final CheckBox ch = (CheckBox) row.findViewById(R.id.check_item);
ch.setVisibility(View.INVISIBLE);
// ch.setChecked(groupsToDelete.contains(model));
//
// ch.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// if (ch.isChecked()) {
// groupsToDelete.add(model);
// List<FavouritePoint> fvs = helper.getFavoriteGroups().get(model);
// if (fvs != null) {
// favoritesToDelete.addAll(fvs);
// }
// adapter.notifyDataSetInvalidated();
// } else {
// groupsToDelete.remove(model);
// }
// }
// });
final CompoundButton ch = (CompoundButton) row.findViewById(R.id.check_item);
ch.setVisibility(View.VISIBLE);
ch.setChecked(model.active);
ch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
osMoPlugin.getGroups().joinGroup(model.groupId);
}
});
return row;
}
@ -378,6 +402,9 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
TextView label = (TextView) row.findViewById(R.id.osmo_label);
ImageView icon = (ImageView) row.findViewById(R.id.osmo_user_icon);
final CompoundButton ch = (CompoundButton) row.findViewById(R.id.check_item);
ch.setVisibility(View.VISIBLE);
final OsMoUser model = (OsMoUser) getChild(groupPosition, childPosition);
row.setTag(model);

View file

@ -3,19 +3,27 @@ package net.osmand.plus.osmo;
import net.osmand.Location;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.SettingsActivity;
import net.osmand.plus.views.MapInfoLayer;
import net.osmand.plus.views.MonitoringInfoControl;
import net.osmand.plus.views.MonitoringInfoControl.MonitoringInfoControlServices;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.mapwidgets.BaseMapWidget;
import net.osmand.plus.views.mapwidgets.TextInfoWidget;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
import android.view.View;
public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlServices {
@ -24,6 +32,7 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
private OsMoService service;
private OsMoTracker tracker;
private OsMoGroups groups;
private BaseMapWidget osmoControl;
public OsMoPlugin(final OsmandApplication app) {
service = new OsMoService(app);
@ -33,6 +42,7 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
}
groups = new OsMoGroups(service, tracker, app.getSettings());
this.app = app;
ApplicationMode.regWidget("osmo_control", (ApplicationMode[])null);
}
@Override
@ -72,6 +82,76 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
if (lock != null && !lock.getMonitorActions().contains(this)) {
lock.addMonitorActions(this);
}
}
@Override
public void registerLayers(MapActivity activity) {
super.registerLayers(activity);
MapInfoLayer layer = activity.getMapLayers().getMapInfoLayer();
osmoControl = createOsMoControl(activity, layer.getPaintText(), layer.getPaintSubText());
layer.getMapInfoControls().registerSideWidget(osmoControl,
R.drawable.mon_osmo_conn_big, R.string.osmo_control, "osmo_control", false, 18);
layer.recreateControls();
}
/**
* creates (if it wasn't created previously) the control to be added on a MapInfoLayer that shows a monitoring state (recorded/stopped)
*/
private BaseMapWidget createOsMoControl(final MapActivity map, Paint paintText, Paint paintSubText) {
final Drawable srcSmall = map.getResources().getDrawable(R.drawable.mon_osmo_conn_small);
final Drawable srcSignalSmall = map.getResources().getDrawable(R.drawable.mon_osmo_conn_signal_small);
final Drawable srcBig = map.getResources().getDrawable(R.drawable.mon_osmo_conn_big);
final Drawable srcSignalBig = map.getResources().getDrawable(R.drawable.mon_osmo_conn_signal_big);
final Drawable srcinactive = map.getResources().getDrawable(R.drawable.monitoring_rec_inactive);
final TextInfoWidget osmoControl = new TextInfoWidget(map, 0, paintText, paintSubText) {
long lastUpdateTime;
@Override
public boolean updateInfo(DrawSettings drawSettings) {
boolean visible = true;
String txt = "";
String subtxt = "OsMo";
Drawable small = srcinactive;
Drawable big = srcinactive;
if (service.isActive()) {
small = tracker.isEnabledTracker() ? srcSignalSmall : srcSmall;
big = tracker.isEnabledTracker() ? srcSignalBig : srcBig;
long last = service.getLastCommandTime();
if (last != lastUpdateTime) {
lastUpdateTime = last;
blink(big, small);
}
}
setText(txt, subtxt);
setImageDrawable(small);
updateVisibility(visible);
return true;
}
private void blink(Drawable bigger, final Drawable smaller ) {
setImageDrawable(bigger);
invalidate();
postDelayed(new Runnable() {
@Override
public void run() {
setImageDrawable(smaller);
invalidate();
}
}, 500);
}
};
osmoControl.updateInfo(null);
osmoControl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(map, OsMoGroupsActivity.class);
map.startActivity(intent);
}
});
return osmoControl;
}
@Override
@ -127,7 +207,7 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
@Override
public void registerOptionsMenuItems(final MapActivity mapActivity, ContextMenuAdapter helper) {
helper.item(R.string.osmo_groups).icons(R.drawable.ic_action_eye_dark, R.drawable.ic_action_eye_light)
helper.item(R.string.osmo_groups).icons(R.drawable.ic_action_eye_dark, R.drawable.ic_action_eye_light).position(4)
.listen(new OnContextMenuClick() {
@Override
public void onContextMenuClick(int itemId, int pos, boolean isChecked, DialogInterface dialog) {

View file

@ -48,6 +48,17 @@ public class OsMoService implements OsMoSender {
return thread != null && thread.isConnected();
}
public boolean isActive() {
return thread != null && thread.isActive();
}
public long getLastCommandTime() {
if(isConnected()) {
return thread.getLastCommandTime();
}
return 0;
}
public long getConnectionTime() {
return thread == null || !thread.isConnected() ? System.currentTimeMillis() : thread.getConnectionTime();
}

View file

@ -29,9 +29,12 @@ public class OsMoThread {
// private static String TRACKER_SERVER = "srv.osmo.mobi";
// private static int TRACKER_PORT = 3245;
private static final String PING_CMD = "P";
protected final static Log log = PlatformUtil.getLog(OsMoThread.class);
private static final long HEARTBEAT_DELAY = 100;
private static final long HEARTBEAT_FAILED_DELAY = 10000;
private static final long TIMEOUT_TO_RECONNECT = 10 * 60 * 1000;
private static final long TIMEOUT_TO_PING = 2 * 60 * 1000;
private static final long LIMIT_OF_FAILURES_RECONNECT = 10;
private static final long SELECT_TIMEOUT = 500;
private static int HEARTBEAT_MSG = 3;
@ -51,6 +54,8 @@ public class OsMoThread {
private SessionInfo sessionInfo = null;
private SocketChannel activeChannel;
private long connectionTime;
private long lastSendCommand = 0;
private long pingSent = 0;
private ByteBuffer pendingSendCommand;
private String readCommand = "";
private ByteBuffer pendingReadCommand = ByteBuffer.allocate(2048);
@ -80,6 +85,8 @@ public class OsMoThread {
}
authorized = 0;
reconnect = false;
failures = 0;
lastSendCommand = 0;
selector = Selector.open();
SocketChannel activeChannel = SocketChannel.open();
activeChannel.configureBlocking(true);
@ -124,6 +131,10 @@ public class OsMoThread {
public boolean isConnected() {
return activeChannel != null;
}
public boolean isActive() {
return activeChannel != null && pingSent == 0 && authorized == 2;
}
protected void checkAsyncSocket() {
long delay = HEARTBEAT_DELAY;
@ -142,7 +153,9 @@ public class OsMoThread {
if (activeChannel != null && !activeChannel.isConnected()) {
activeChannel = null;
}
if (failures++ > LIMIT_OF_FAILURES_RECONNECT) {
if(lastSendCommand != 0 && System.currentTimeMillis() - lastSendCommand > TIMEOUT_TO_RECONNECT ) {
reconnect = true;
} else if (failures++ > LIMIT_OF_FAILURES_RECONNECT) {
reconnect = true;
}
}
@ -263,6 +276,9 @@ public class OsMoThread {
}
}
continue;
} else if(header.equalsIgnoreCase(PING_CMD)) {
pingSent = 0;
// lastSendCommand = System.currentTimeMillis(); // not needed handled by send
}
boolean processed = false;
for (OsMoReactor o : listReactors) {
@ -275,6 +291,7 @@ public class OsMoThread {
log.warn("Command not processed '" + cmd + "'");
}
}
lastSendCommand = System.currentTimeMillis();
}
private void parseAuthCommand(String data, JSONObject obj) throws JSONException {
@ -311,6 +328,7 @@ public class OsMoThread {
while (pendingSendCommand != null) {
activeChannel.write(pendingSendCommand);
if (!pendingSendCommand.hasRemaining()) {
lastSendCommand = System.currentTimeMillis();
pendingSendCommand = getNewPendingSendCommand();
} else {
break;
@ -338,6 +356,13 @@ public class OsMoThread {
return ByteBuffer.wrap(res.toString().getBytes("UTF-8"));
}
}
if(System.currentTimeMillis() - lastSendCommand > TIMEOUT_TO_PING) {
if(pingSent == 0) {
pingSent = System.currentTimeMillis();
return ByteBuffer.wrap(prepareCommand(PING_CMD).toString().getBytes("UTF-8"));
}
}
return null;
}
@ -369,4 +394,8 @@ public class OsMoThread {
}
return res;
}
public long getLastCommandTime() {
return lastSendCommand;
}
}