Add connected devices view

This commit is contained in:
vshcherb 2014-05-22 01:13:36 +02:00
parent 882c45bdd6
commit 505c0ff4b7
10 changed files with 664 additions and 29 deletions

View file

@ -105,7 +105,7 @@
<activity android:name="net.osmand.plus.activities.SettingsNavigationActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.monitoring.SettingsMonitoringActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.rastermaps.SettingsRasterMapsActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.osmo.SettingsOsMoActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.osmedit.SettingsOsmEditingActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.development.SettingsDevelopmentActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.audionotes.SettingsAudioVideoActivity" android:configChanges="keyboardHidden|orientation"></activity>
@ -120,6 +120,10 @@
<activity android:name="net.osmand.plus.activities.ContributionVersionActivity" android:configChanges="keyboardHidden|orientation" android:label="@string/contribution_activity"></activity>
<activity android:name="net.osmand.plus.osmo.SettingsOsMoActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.osmo.OsMoGroupsActivity"></activity>
<activity android:name="net.osmand.plus.activities.search.SearchPOIActivity" android:label="@string/searchpoi_activity"></activity>
<activity android:name="net.osmand.plus.activities.search.SearchAddressActivity" android:label="@string/select_address_activity"></activity>
<activity android:name="net.osmand.plus.activities.search.SearchCityByNameActivity"></activity>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="3dp"
android:paddingRight="3dp" android:stretchColumns="1">
<TableRow >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="@string/osmo_connect_to_device_tracker_id"/>
<EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="3dp"
android:id="@+id/TrackerId" android:inputType="textCapCharacters" android:selectAllOnFocus="true"/>
</TableRow>
<TableRow>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="@string/osmo_connect_to_device_name"/>
<EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="3dp"
android:id="@+id/Name" android:inputType="textCapWords" />
</TableRow>
</TableLayout>

View file

@ -0,0 +1,21 @@
<?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="horizontal"
android:paddingBottom="5dp"
android:paddingLeft="8dp"
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"/>
</LinearLayout>

View file

@ -0,0 +1,22 @@
<?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="fill_parent"
android:orientation="vertical"
>
<ExpandableListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"
android:layout_weight="1"
android:groupIndicator="@android:color/transparent"
style="@style/OsmandListView">
</ExpandableListView>
</LinearLayout>

View file

@ -9,6 +9,16 @@
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="hours_ago">hours ago</string>
<string name="minutes_ago">min ago</string>
<string name="seconds_ago">sec ago</string>
<string name="osmo_connect_to_device_name">Name of device</string>
<string name="osmo_connect_to_device_tracker_id">Tracker id</string>
<string name="osmo_connect_to_device">Link with device</string>
<string name="osmo_join_group">Join group</string>
<string name="osmo_new_device">New device</string>
<string name="osmo_connected_devices">Connected devices</string>
<string name="osmo_groups">OsMo Groups/Devices</string>
<string name="osmo_auto_send_locations_descr">Automatically start tracker session and send locations after application startup</string>
<string name="osmo_auto_send_locations">Automatically start tracker session</string>
<string name="osmo_tracker_id">Personal tracker id</string>

View file

@ -1,12 +1,9 @@
package net.osmand.plus;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.view.Window;
import net.osmand.IProgress;
import net.osmand.plus.activities.DownloadIndexActivity;
import net.osmand.plus.activities.FavouritesActivity;
@ -18,6 +15,8 @@ import net.osmand.plus.activities.SettingsActivity;
import net.osmand.plus.activities.search.SearchActivity;
import net.osmand.plus.api.SettingsAPI;
import net.osmand.plus.download.DownloadActivityType;
import android.app.Activity;
import android.view.Window;
public class OsmAndAppCustomization {

View file

@ -9,11 +9,15 @@ import java.util.concurrent.ConcurrentHashMap;
import net.osmand.data.LatLon;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.osmo.OsMoService.SessionInfo;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
public class OsMoGroups implements OsMoReactor {
private static final String TRACKER_ID = "trackerId";
@ -22,7 +26,6 @@ public class OsMoGroups implements OsMoReactor {
private static final String NAME = "name";
private static final String USER_NAME = "userName";
private static final String GROUP_NAME = "group_name";
private static final String MY_GROUP_TRACKER_ID = "my_group_tracker_id";
private OsMoTracker tracker;
private ConcurrentHashMap<String, OsMoGroup> groups = new ConcurrentHashMap<String, OsMoGroup>();
private OsMoGroup mainGroup;
@ -33,7 +36,6 @@ public class OsMoGroups implements OsMoReactor {
public String name;
public String userName;
public String groupId;
public String myGroupTrackerId;
public boolean active;
public Map<String, OsMoUser> users = new ConcurrentHashMap<String, OsMoGroups.OsMoUser>();
@ -42,7 +44,10 @@ public class OsMoGroups implements OsMoReactor {
return groupId == null;
}
public String getVisibleName(){
public String getVisibleName(Context ctx){
if(isMainGroup()) {
return ctx.getString(R.string.osmo_connected_devices);
}
if(userName != null && userName.length() > 0) {
return userName;
}
@ -60,8 +65,13 @@ public class OsMoGroups implements OsMoReactor {
public String serverName;
public String userName;
public String trackerId;
public OsMoGroup group ;
public List<OsMoMessage> messages = new ArrayList<OsMoMessage>();
public OsMoGroup getGroup() {
return group;
}
public String getVisibleName(){
if(userName != null && userName.length() > 0) {
return userName;
@ -87,6 +97,9 @@ public class OsMoGroups implements OsMoReactor {
try {
JSONObject obj = new JSONObject(grp);
parseGroupUsers(mainGroup, obj);
for(String connectedDevice : mainGroup.users.keySet()) {
tracker.startTrackingId(connectedDevice);
}
if(!obj.has("groups")) {
return;
}
@ -95,9 +108,6 @@ public class OsMoGroups implements OsMoReactor {
JSONObject o = (JSONObject) groups.get(i);
OsMoGroup group = new OsMoGroup();
group.groupId = o.getString(GROUP_ID);
if(o.has(MY_GROUP_TRACKER_ID)) {
group.myGroupTrackerId = o.getString(MY_GROUP_TRACKER_ID);
}
if(o.has(NAME)) {
group.name = o.getString(NAME);
}
@ -164,6 +174,7 @@ public class OsMoGroups implements OsMoReactor {
for (int i = 0; i < users.length(); i++) {
JSONObject o = (JSONObject) users.get(i);
OsMoUser user = new OsMoUser();
user.group = gr;
if(o.has("serverName")) {
user.serverName = o.getString("serverName");
}
@ -173,6 +184,21 @@ public class OsMoGroups implements OsMoReactor {
user.trackerId = o.getString(TRACKER_ID);
}
}
public ConcurrentHashMap<String, OsMoGroup> getGroups() {
return groups;
}
public OsMoUser registerUser(String trackerId, String nameUser) {
OsMoUser us = new OsMoUser();
us.group = mainGroup;
us.trackerId = trackerId;
us.userName = nameUser;
mainGroup.users.put(trackerId, us);
tracker.startTrackingId(trackerId);
saveGroups();
return us;
}
@Override
public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread thread) {
@ -196,24 +222,26 @@ public class OsMoGroups implements OsMoReactor {
joinGroup(gid);
} else if(command.startsWith("JOIN_GROUP:")) {
String gid = command.substring(command.indexOf(':') + 1);
String myGroupTrackerId = getMyGroupTrackerId();
OsMoGroup gr = groups.get(gid);
if(gr != null) {
mergeGroup(gr, obj, true);
gr.active = true;
for(String key : gr.users.keySet()) {
if (!key.equals(gr.myGroupTrackerId)) {
if (!key.equals(myGroupTrackerId)) {
tracker.startTrackingId(key);
}
}
}
return true;
} else if(command.startsWith("LEAVE_GROUP:")) {
String myGroupTrackerId = getMyGroupTrackerId();
String gid = command.substring(command.indexOf(':') + 1);
OsMoGroup gr = groups.get(gid);
if(gr != null) {
gr.active = false;
for(String key : gr.users.keySet()) {
if (!key.equals(gr.myGroupTrackerId)) {
if (!key.equals(myGroupTrackerId)) {
tracker.stopTrackingId(key);
}
}
@ -222,6 +250,15 @@ public class OsMoGroups implements OsMoReactor {
}
return false;
}
private String getMyGroupTrackerId() {
String myGroupTrackerId = "";
SessionInfo currentSessionInfo = service.getCurrentSessionInfo();
if(currentSessionInfo != null) {
myGroupTrackerId = currentSessionInfo.groupTrackerId;
}
return myGroupTrackerId;
}
private void mergeGroup(OsMoGroup gr, JSONObject obj, boolean deleteUsers) {
@ -229,9 +266,7 @@ public class OsMoGroups implements OsMoReactor {
if(obj.has(GROUP_NAME)) {
gr.name = obj.getString(GROUP_NAME);
}
if(obj.has(MY_GROUP_TRACKER_ID)) {
gr.myGroupTrackerId = obj.getString(MY_GROUP_TRACKER_ID);
}
String myGroupTrackerId = getMyGroupTrackerId();
JSONArray arr = obj.getJSONArray(GROUP_TRACKERS);
Set<String> toDelete = new HashSet<String>(gr.users.keySet());
for (int i = 0; i < arr.length(); i++) {
@ -241,10 +276,11 @@ public class OsMoGroups implements OsMoReactor {
OsMoUser us = gr.users.get(tid);
if (us == null) {
us = new OsMoUser();
us.group = gr;
us.trackerId = tid;
gr.users.put(tid, us);
if(gr.active) {
if (!tid.equals(gr.myGroupTrackerId)) {
if (!tid.equals(myGroupTrackerId)) {
tracker.startTrackingId(tid);
}
}
@ -280,4 +316,5 @@ public class OsMoGroups implements OsMoReactor {
service.pushCommand("LEAVE_GROUP|"+group.groupId);
}
}

View file

@ -0,0 +1,504 @@
/**
*
*/
package net.osmand.plus.osmo;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.plus.OsmAndConstants;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
import net.osmand.plus.activities.OsmandExpandableListActivity;
import net.osmand.plus.osmo.OsMoGroups.OsMoGroup;
import net.osmand.plus.osmo.OsMoGroups.OsMoUser;
import net.osmand.plus.osmo.OsMoTracker.OsmoTrackerListener;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Spannable;
import android.text.style.ForegroundColorSpan;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
/**
*
*/
public class OsMoGroupsActivity extends OsmandExpandableListActivity implements OsmAndCompassListener,
OsmAndLocationListener, OsmoTrackerListener {
public static final int CONNECT_TO_DEVICE = 1;
public static final int DELETE_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;
private static final long RECENT_THRESHOLD = 60000;
private Set<String> groupsToDelete = new LinkedHashSet<String>();
private OsMoPlugin osMoPlugin;
private OsMoGroupsAdapter adapter;
private LatLon mapLocation;
private OsmandApplication app;
private Handler uiHandler;
private float width = 24;
private float height = 24;
private Path directionPath = new Path();
private Location lastLocation;
private float lastCompass;
@Override
public void onCreate(Bundle icicle) {
// This has to be called before setContentView and you must use the
// class in com.actionbarsherlock.view and NOT android.view
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);
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();
}
private Path createDirectionPath() {
int h = 15;
int w = 4;
float sarrowL = 8; // side of arrow
float harrowL = (float) Math.sqrt(2) * sarrowL; // hypotenuse of arrow
float hpartArrowL = (float) (harrowL - w) / 2;
Path path = new Path();
path.moveTo(width / 2, height - (height - h) / 3);
path.rMoveTo(w / 2, 0);
path.rLineTo(0, -h);
path.rLineTo(hpartArrowL, 0);
path.rLineTo(-harrowL / 2, -harrowL / 2); // center
path.rLineTo(-harrowL / 2, harrowL / 2);
path.rLineTo(hpartArrowL, 0);
path.rLineTo(0, h);
Matrix pathTransform = new Matrix();
WindowManager mgr = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
mgr.getDefaultDisplay().getMetrics(dm);
pathTransform.postScale(dm.density, dm.density);
path.transform(pathTransform);
width *= dm.density;
height *= dm.density;
return path;
}
@Override
protected void onResume() {
super.onResume();
mapLocation = getMyApplication().getSettings().getLastKnownMapLocation();
app.getLocationProvider().addCompassListener(this);
app.getLocationProvider().registerOrUnregisterCompassListener(true);
app.getLocationProvider().addLocationListener(this);
app.getLocationProvider().resumeAllUpdates();
osMoPlugin.getTracker().setTrackerListener(this);
adapter.synchronizeGroups();
}
@Override
protected void onPause() {
super.onPause();
app.getLocationProvider().pauseAllUpdates();
app.getLocationProvider().removeCompassListener(this);
app.getLocationProvider().removeLocationListener(this);
osMoPlugin.getTracker().setTrackerListener(null);
}
@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);
// }
return true;
}
@Override
public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) {
if (item.getItemId() == CONNECT_TO_DEVICE) {
connectToDevice();
return true;
} 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);
}
}
private void connectToDevice() {
Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.osmo_connect_to_device);
final View v = getLayoutInflater().inflate(R.layout.osmo_connect_to_device, getExpandableListView(), false);
final EditText tracker = (EditText) v.findViewById(R.id.TrackerId);
final EditText name = (EditText) v.findViewById(R.id.Name);
builder.setView(v);
builder.setNegativeButton(R.string.default_buttons_cancel, null);
builder.setPositiveButton(R.string.default_buttons_apply, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String nameUser = name.getText().toString();
adapter.registerUser(tracker.getText().toString(), nameUser);
}
});
builder.create().show();
tracker.requestFocus();
}
@Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
createMenuItem(menu, CONNECT_TO_DEVICE, R.string.osmo_new_device, R.drawable.ic_action_marker_light,
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);
}
public void showProgressBar() {
setSupportProgressBarIndeterminateVisibility(true);
}
public void hideProgressBar() {
setSupportProgressBarIndeterminateVisibility(false);
}
class OsMoGroupsAdapter extends OsmandBaseExpandableListAdapter {
private List<OsMoGroup> sortedGroups = new ArrayList<OsMoGroups.OsMoGroup>();
private Map<OsMoGroup, List<OsMoUser>> users = new LinkedHashMap<OsMoGroups.OsMoGroup, List<OsMoUser>>();
private OsMoGroups grs;
private OsMoTracker tracker;
public OsMoGroupsAdapter(OsMoGroups grs, OsMoTracker tracker) {
this.grs = grs;
this.tracker = tracker;
synchronizeGroups();
}
public void registerUser(String trackerId, String nameUser) {
addUser(grs.registerUser(trackerId, nameUser));
}
public void sort(Comparator<OsMoUser> comparator) {
for (List<OsMoUser> ps : users.values()) {
Collections.sort(ps, comparator);
}
}
public void addUser(OsMoUser p) {
if (!users.containsKey(p.getGroup())) {
users.put(p.getGroup(), new ArrayList<OsMoUser>());
sortedGroups.add(p.getGroup());
}
users.get(p.getGroup()).add(p);
notifyDataSetChanged();
}
public void synchronizeGroups() {
users.clear();
sortedGroups.clear();
final Collator clt = Collator.getInstance();
for (OsMoGroup key : grs.getGroups().values()) {
sortedGroups.add(key);
final ArrayList<OsMoUser> list = new ArrayList<OsMoUser>(key.users.values());
Collections.sort(list, new Comparator<OsMoGroups.OsMoUser>() {
@Override
public int compare(OsMoUser lhs, OsMoUser rhs) {
return clt.compare(lhs.getVisibleName(), rhs.getVisibleName());
}
});
users.put(key, list);
}
Collections.sort(sortedGroups, new Comparator<OsMoGroups.OsMoGroup>() {
@Override
public int compare(OsMoGroup lhs, OsMoGroup rhs) {
if (lhs.isMainGroup()) {
return 1;
}
if (rhs.isMainGroup()) {
return -1;
}
return clt.compare(lhs.getVisibleName(OsMoGroupsActivity.this),
rhs.getVisibleName(OsMoGroupsActivity.this));
}
});
notifyDataSetChanged();
}
@Override
public OsMoUser getChild(int groupPosition, int childPosition) {
return users.get(sortedGroups.get(groupPosition)).get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return groupPosition * 10000 + childPosition;
}
@Override
public int getChildrenCount(int groupPosition) {
return users.get(sortedGroups.get(groupPosition)).size();
}
@Override
public OsMoGroup getGroup(int groupPosition) {
return sortedGroups.get(groupPosition);
}
@Override
public int getGroupCount() {
return sortedGroups.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.expandable_list_item_category, 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);
// }
// }
// });
return row;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.osmo_group_list_item, parent, false);
}
TextView label = (TextView) row.findViewById(R.id.osmo_label);
ImageView icon = (ImageView) row.findViewById(R.id.osmo_user_icon);
final OsMoUser model = (OsMoUser) getChild(groupPosition, childPosition);
row.setTag(model);
LatLon lnLocation = mapLocation;
Location location = tracker.getLastLocation(model.trackerId);
if (location == null || lnLocation == null) {
icon.setImageResource(R.drawable.list_favorite);
label.setText(model.getVisibleName());
} else {
DirectionDrawable draw = new DirectionDrawable();
float[] mes = new float[2];
net.osmand.Location.distanceBetween(location.getLatitude(), location.getLongitude(),
lnLocation.getLatitude(), lnLocation.getLongitude(), mes);
draw.setAngle(mes[1] - lastCompass + 180);
draw.setRecent(Math.abs(location.getTime() - System.currentTimeMillis()) < RECENT_THRESHOLD);
icon.setImageDrawable(draw);
icon.setImageResource(R.drawable.list_favorite);
int dist = (int) mes[0];
long seconds = Math.max(0, (System.currentTimeMillis() - location.getTime()) / 1000);
String time = " (";
if (seconds < 100) {
time = seconds + " " + getString(R.string.seconds_ago);
} else if (seconds / 60 < 100) {
time = (seconds / 60) + " " + getString(R.string.minutes_ago);
} else {
time = (seconds / (60 * 60)) + " " + getString(R.string.hours_ago);
}
time += ")";
String distance = OsmAndFormatter.getFormattedDistance(dist, getMyApplication()) + " ";
String visibleName = model.getVisibleName();
String firstPart = distance + visibleName;
final String fullText = firstPart + time;
label.setText(fullText, TextView.BufferType.SPANNABLE);
((Spannable) label.getText()).setSpan(
new ForegroundColorSpan(getResources().getColor(R.color.color_distance)), 0,
distance.length() - 1, 0);
((Spannable) label.getText()).setSpan(
new ForegroundColorSpan(getResources().getColor(R.color.color_unknown)), firstPart.length(),
fullText.length() - 1, 0);
}
return row;
}
}
@Override
public void updateLocation(Location location) {
lastLocation = location;
adapter.notifyDataSetInvalidated();
}
@Override
public void updateCompassValue(float value) {
lastCompass = value;
refreshList();
}
private void refreshList() {
if (!uiHandler.hasMessages(LIST_REFRESH_MSG_ID)) {
Message msg = Message.obtain(uiHandler, new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
msg.what = LIST_REFRESH_MSG_ID;
uiHandler.sendMessageDelayed(msg, 100);
}
}
@Override
public void locationChange(String trackerId) {
refreshList();
}
class DirectionDrawable extends Drawable {
Paint paintRouteDirection;
private float angle;
public DirectionDrawable() {
paintRouteDirection = new Paint();
paintRouteDirection.setStyle(Style.FILL_AND_STROKE);
paintRouteDirection.setColor(getResources().getColor(R.color.color_unknown));
paintRouteDirection.setAntiAlias(true);
}
public void setRecent(boolean recent) {
if (recent) {
paintRouteDirection.setColor(getResources().getColor(R.color.color_ok));
} else {
paintRouteDirection.setColor(getResources().getColor(R.color.color_unknown));
}
}
public void setAngle(float angle) {
this.angle = angle;
}
@Override
public void draw(Canvas canvas) {
canvas.rotate(angle, width / 2, height / 2);
canvas.drawPath(directionPath, paintRouteDirection);
}
@Override
public int getOpacity() {
return 0;
}
@Override
public void setAlpha(int alpha) {
paintRouteDirection.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
paintRouteDirection.setColorFilter(cf);
}
}
}

View file

@ -124,6 +124,19 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
grp.setKey("osmo_settings");
screen.addPreference(grp);
}
@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)
.listen(new OnContextMenuClick() {
@Override
public void onContextMenuClick(int itemId, int pos, boolean isChecked, DialogInterface dialog) {
Intent intent = new Intent(mapActivity, OsMoGroupsActivity.class);
mapActivity.startActivity(intent);
}
}).reg();
}
@Override
public String getId() {

View file

@ -5,7 +5,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import net.osmand.Location;
import net.osmand.plus.views.OsmandMapTileView;
import org.json.JSONObject;
@ -13,9 +12,14 @@ public class OsMoTracker implements OsMoSender, OsMoReactor {
private ConcurrentLinkedQueue<Location> bufferOfLocations = new ConcurrentLinkedQueue<Location>();
private Map<String, Location> otherLocations = new ConcurrentHashMap<String, Location>();
private boolean startSendingLocations;
private OsmandMapTileView view;
private OsMoService service;
private int locationsSent = 0;
private OsmoTrackerListener trackerListener = null;
public interface OsmoTrackerListener {
public void locationChange(String trackerId);
}
public OsMoTracker(OsMoService service) {
this.service = service;
@ -41,9 +45,12 @@ public class OsMoTracker implements OsMoSender, OsMoReactor {
}
}
public Location getLastLocation(String trackerId) {
return otherLocations.get(trackerId);
}
public void startTrackingId(String id) {
service.pushCommand("LISTEN|"+id);
otherLocations.put(id, null);
}
public void stopTrackingId(String id) {
@ -99,13 +106,6 @@ public class OsMoTracker implements OsMoSender, OsMoReactor {
bufferOfLocations.add(l);
}
public void setView(OsmandMapTileView view) {
this.view = view;
}
public OsmandMapTileView getView() {
return view;
}
@Override
public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread thread) {
@ -140,9 +140,8 @@ public class OsMoTracker implements OsMoSender, OsMoReactor {
loc.setSpeed(speed);
}
otherLocations.put(tid, loc);
OsmandMapTileView v = view;
if(v != null){
v.refreshMap();
if(trackerListener != null){
trackerListener.locationChange(tid);
}
}
return true;
@ -150,5 +149,14 @@ public class OsMoTracker implements OsMoSender, OsMoReactor {
return false;
}
public OsmoTrackerListener getTrackerListener() {
return trackerListener;
}
public void setTrackerListener(OsmoTrackerListener trackerListener) {
this.trackerListener = trackerListener;
}
}