Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
e1e61349d3
37 changed files with 10 additions and 6202 deletions
|
@ -5,7 +5,7 @@ import net.osmand.render.RenderingRuleSearchRequest;
|
|||
|
||||
|
||||
public class RenderingContext {
|
||||
static enum ShadowRenderingMode {
|
||||
public static enum ShadowRenderingMode {
|
||||
// int shadowRenderingMode = 0; // no shadow (minumum CPU)
|
||||
// int shadowRenderingMode = 1; // classic shadow (the implementaton in master)
|
||||
// int shadowRenderingMode = 2; // blur shadow (most CPU, but still reasonable)
|
||||
|
|
|
@ -81,9 +81,9 @@ public class BinaryInspector {
|
|||
// "-lang=ru",
|
||||
// "-bbox=30.4981,50.4424,30.5195,50.4351",
|
||||
// "-osm="+System.getProperty("maps.dir")+"/map_full_1.obf.osm",
|
||||
System.getProperty("maps.dir")+"/diff/Bulgaria_europe_01_00.obf"
|
||||
// System.getProperty("maps.dir")+"/diff/Bulgaria_europe_01_00.obf"
|
||||
// System.getProperty("maps.dir")+"/diff/Diff.obf"
|
||||
// System.getProperty("maps.dir")+"/Ukraine_kiev-city_europe_2.obf"
|
||||
System.getProperty("maps.dir")+"/Map.obf"
|
||||
});
|
||||
} else {
|
||||
in.inspector(args);
|
||||
|
|
|
@ -2061,7 +2061,7 @@ public class BinaryMapIndexReader {
|
|||
private static boolean testAddressSearch = false;
|
||||
private static boolean testAddressSearchName = false;
|
||||
private static boolean testAddressJustifySearch = false;
|
||||
private static boolean testPoiSearch = false;
|
||||
private static boolean testPoiSearch = true;
|
||||
private static boolean testPoiSearchOnPath = false;
|
||||
private static boolean testTransportSearch = true;
|
||||
|
||||
|
@ -2227,7 +2227,7 @@ public class BinaryMapIndexReader {
|
|||
|
||||
private static void testPoiSearchByName(BinaryMapIndexReader reader) throws IOException {
|
||||
println("Searching by name...");
|
||||
SearchRequest<Amenity> req = buildSearchPoiRequest(0, 0, "Belar",
|
||||
SearchRequest<Amenity> req = buildSearchPoiRequest(0, 0, "Art",
|
||||
0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, null);
|
||||
|
||||
reader.searchPoiByName(req);
|
||||
|
@ -2360,7 +2360,7 @@ public class BinaryMapIndexReader {
|
|||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
}, "Красноарм", StringMatcherMode.CHECK_ONLY_STARTS_WITH);
|
||||
}, "Guy'", StringMatcherMode.CHECK_ONLY_STARTS_WITH);
|
||||
// req.setBBoxRadius(52.276142, 4.8608723, 15000);
|
||||
reader.searchAddressDataByName(req);
|
||||
}
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
<?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="7dp"
|
||||
android:paddingRight="7dp"
|
||||
android:stretchColumns="1">
|
||||
|
||||
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/LabelTrackerId"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_connect_to_device_tracker_id" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/TrackerId"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textCapCharacters"
|
||||
android:paddingLeft="3dp"
|
||||
android:selectAllOnFocus="true" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/LabelName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_connect_to_device_name" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/Name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textCapWords"
|
||||
android:paddingLeft="3dp" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:id="@+id/MyGroupName"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_connect_to_my_nickname" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/NickName"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textCapWords"
|
||||
android:paddingLeft="3dp" />
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
|
@ -1,105 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingBottom="@dimen/dialog_content_bottom_margin"
|
||||
android:paddingLeft="@dimen/dialog_content_margin"
|
||||
android:paddingRight="@dimen/dialog_content_margin"
|
||||
android:paddingTop="@dimen/dialog_content_bottom_margin">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="7dp"
|
||||
android:paddingRight="7dp"
|
||||
android:stretchColumns="1">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_group_name"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/Name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textLengthAlert"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_grop_name_length_alert"
|
||||
android:textColor="@color/osmbug_closed"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_group_description"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/Description"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_group_policy"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/Policy"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_group_by_invite"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/OnlyByInvite"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/osmo_group_create_info"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/osmo_group_information"
|
||||
android:textSize="@dimen/default_list_text_size"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/info"
|
||||
android:contentDescription="@string/osmo_group_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/dashboard_button"
|
||||
android:src="@drawable/ic_action_gabout_dark"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/osmo_group_create_dinfo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_group_information_desc"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
android:visibility="gone"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
|
@ -1,46 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="@dimen/dialog_content_bottom_margin"
|
||||
android:paddingTop="@dimen/dialog_content_bottom_margin"
|
||||
android:paddingLeft="@dimen/dialog_content_margin"
|
||||
android:paddingRight="@dimen/dialog_content_margin"
|
||||
android:stretchColumns="1">
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_connect_to_device_name" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/Name"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp">
|
||||
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmo_edit_color" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/ColorSpinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp" />
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
|
@ -1,47 +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="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingLeft="3dp"
|
||||
android:paddingRight="4dp"
|
||||
android:paddingTop="5dp">
|
||||
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/settings"
|
||||
android:contentDescription="@string/osmo_settings"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:focusable="false"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/explist_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="6dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/category_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_weight="1"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="@string/lorem_ipsum"/>
|
||||
|
||||
<include layout="@layout/check_item_rel"/>
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
|
@ -1,34 +0,0 @@
|
|||
<?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">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/memory_size"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text=""
|
||||
android:visibility="gone" />
|
||||
|
||||
<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"/>
|
||||
|
||||
<net.osmand.plus.activities.search.toolbar.SplitToolbar
|
||||
android:id="@+id/bottomControls"
|
||||
android:background="?attr/bottomToolBarColor"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,40 +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="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/expandable_list_item_background"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="4dp"
|
||||
android:paddingTop="5dp">
|
||||
|
||||
<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:textSize="@dimen/default_list_text_size_large"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_weight="1"
|
||||
android:maxLines="7"
|
||||
tools:text="@string/abc_action_bar_home_description"
|
||||
android:textColor="?android:textColorPrimary"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/osmo_label_time"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp"/>
|
||||
|
||||
<!-- <include layout="@layout/check_item" /> -->
|
||||
|
||||
</LinearLayout>
|
|
@ -1,19 +0,0 @@
|
|||
<?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">
|
||||
|
||||
<include layout="@layout/osmo_groups_list_header" />
|
||||
|
||||
<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"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/osmo_no_connection_msg"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:autoLink="web"
|
||||
android:linksClickable="true"
|
||||
android:padding="10dp"
|
||||
android:text="@string/osmo_no_connection_msg"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -1,75 +0,0 @@
|
|||
<?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/osmo_header_background"
|
||||
android:orientation="vertical"
|
||||
android:paddingRight="@dimen/list_content_padding">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/osmo_status"
|
||||
android:layout_width="@dimen/list_item_height"
|
||||
android:layout_height="@dimen/list_item_height"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/mon_osmo_conn_small"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/enable_service"
|
||||
layout="@layout/check_item"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:focusable="false"
|
||||
android:text="@string/osmo_start_service"
|
||||
android:textColor="@color/color_white"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/share_my_location_layout"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/share_my_location"
|
||||
android:contentDescription="@string/shared_string_share"
|
||||
android:layout_width="@dimen/list_item_height"
|
||||
android:layout_height="@dimen/list_item_height"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="?attr/dashboard_button"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_action_gshare_dark"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/enable_tracker"
|
||||
layout="@layout/check_item"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:focusable="false"
|
||||
android:text="@string/osmo_enable_tracker"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/motd"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/list_content_padding"
|
||||
android:autoLink="web"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
android:visibility="gone"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
|
@ -571,17 +571,6 @@
|
|||
<string name="rendering_value_bold_name">Bold</string>
|
||||
<string name="no_map_markers_found">Please add map markers via map</string>
|
||||
<string name="no_waypoints_found">No waypoints found</string>
|
||||
<string name="osmo_group_information_desc">
|
||||
- Creating a group please give it a name and fill in description\n
|
||||
- From the application group are created only with Simple type, read more on the website https://osmo.mobi/g/new \n
|
||||
- Through a website you can manage a group, to place tracks and points available all\n
|
||||
- We do not endorse the use of the group only one user, if this is not the POI group\n
|
||||
- Private groups are limited to 8 persons \n
|
||||
- Detailed terms and conditions always have an on website OsMo.mobi\n
|
||||
- If you need special conditions - please contact support: osmo.mobi@gmail.com
|
||||
</string>
|
||||
<string name="osmo_specify_tracker_id">Please specify ID</string>
|
||||
<string name="osmo_no_connection_msg">Cannot connect to the server OsMo:\n- check your Internet connection;\n- check the settings;\n- check out our Twitter: https://twitter.com/OsMomobi</string>
|
||||
<string name="anonymous_user_hint">An anonymous user cannot:\n- create groups;\n- synchronize groups and devices with the server;\n- manage groups and devices in a personal dashboard on website.</string>
|
||||
<string name="report">Report</string>
|
||||
<string name="osmo_connect_to_device_tracker_id">Tracker ID</string>
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
package com.OsMoDroid;
|
||||
|
||||
interface IRemoteOsMoDroidListener {
|
||||
|
||||
void channelUpdated();
|
||||
void channelsListUpdated();
|
||||
void routeTo(float Lat, float Lon);
|
||||
|
||||
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package com.OsMoDroid;
|
||||
|
||||
import com.OsMoDroid.IRemoteOsMoDroidListener;
|
||||
|
||||
interface IRemoteOsMoDroidService {
|
||||
|
||||
void registerListener(IRemoteOsMoDroidListener listener);
|
||||
|
||||
void unregisterListener(IRemoteOsMoDroidListener listener);
|
||||
|
||||
int getVersion();
|
||||
|
||||
int getBackwardCompatibleVersion();
|
||||
|
||||
void Deactivate();
|
||||
|
||||
void Activate();
|
||||
|
||||
boolean isActive();
|
||||
|
||||
int getNumberOfLayers();
|
||||
|
||||
int getLayerId(int pos);
|
||||
|
||||
String getLayerName(int layerId);
|
||||
|
||||
String getLayerDescription(int layerId);
|
||||
|
||||
int getNumberOfObjects(int layerId);
|
||||
|
||||
int getObjectId(int layerId, int pos);
|
||||
|
||||
float getObjectLat(int layerId, int objectId);
|
||||
|
||||
float getObjectLon(int layerId, int objectId);
|
||||
|
||||
String getObjectSpeed(int layerId, int objectId);
|
||||
|
||||
String getObjectName(int layerId, int objectId);
|
||||
|
||||
String getObjectDescription(int layerId, int objectId);
|
||||
|
||||
String getObjectColor(int layerId, int objectId);
|
||||
|
||||
int getNumberOfGpx(int layerId);
|
||||
|
||||
String getGpxFile (int layerId, int pos);
|
||||
|
||||
int getGpxColor (int layerId, int pos);
|
||||
|
||||
int getNumberOfPoints(int layerId);
|
||||
|
||||
int getPointId(int layerId, int pos);
|
||||
|
||||
float getPointLat(int layerId, int pointId);
|
||||
|
||||
float getPointLon(int layerId, int pointId);
|
||||
|
||||
String getPointName(int layerId, int pointId);
|
||||
|
||||
String getPointDescription(int layerId, int pointId);
|
||||
|
||||
String getPointColor(int layerId, int pointId);
|
||||
|
||||
void refreshChannels();
|
||||
}
|
|
@ -21,7 +21,6 @@ import android.widget.Toast;
|
|||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.notifications.OsmandNotification;
|
||||
import net.osmand.plus.osmo.OsMoPlugin;
|
||||
|
||||
public class NavigationService extends Service implements LocationListener {
|
||||
|
||||
|
@ -267,12 +266,6 @@ public class NavigationService extends Service implements LocationListener {
|
|||
app.getNotificationHelper().removeNotifications();
|
||||
if (app.getNavigationService() != null &&
|
||||
app.getSettings().DISABLE_RECORDING_ONCE_APP_KILLED.get()) {
|
||||
OsMoPlugin plugin = OsmandPlugin.getEnabledPlugin(OsMoPlugin.class);
|
||||
if (plugin != null) {
|
||||
if (plugin.getTracker().isEnabledTracker()) {
|
||||
plugin.getTracker().disableTracker();
|
||||
}
|
||||
}
|
||||
NavigationService.this.stopSelf();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,7 +136,6 @@ public abstract class OsmandPlugin {
|
|||
|
||||
allPlugins.add(new OsmandRasterMapsPlugin(app));
|
||||
allPlugins.add(new OsmandMonitoringPlugin(app));
|
||||
// allPlugins.add(new OsMoPlugin(app));
|
||||
checkMarketPlugin(app, new SRTMPlugin(app), true, SRTM_PLUGIN_COMPONENT_PAID, SRTM_PLUGIN_COMPONENT);
|
||||
|
||||
// ? questionable - definitely not market plugin
|
||||
|
|
|
@ -1177,23 +1177,6 @@ public class OsmandSettings {
|
|||
}
|
||||
}
|
||||
|
||||
public final OsmandPreference<String> OSMO_DEVICE_KEY = new StringPreference("osmo_device_token", "").makeGlobal();
|
||||
|
||||
public final OsmandPreference<String> OSMO_USER_NAME = new StringPreference("osmo_user_name", "").makeGlobal();
|
||||
|
||||
public final OsmandPreference<String> OSMO_USER_PWD = new StringPreference("osmo_user_pwd", null).makeGlobal();
|
||||
|
||||
public final OsmandPreference<Boolean> OSMO_AUTO_CONNECT = new BooleanPreference("osmo_automatically_connect", false).makeGlobal();
|
||||
|
||||
public final OsmandPreference<Long> OSMO_LAST_PING = new LongPreference("osmo_last_ping", 0).makeGlobal().cache();
|
||||
|
||||
public final OsmandPreference<Boolean> OSMO_SEND_LOCATIONS_STATE = new BooleanPreference("osmo_send_locations", false).cache().makeGlobal();
|
||||
|
||||
public final OsmandPreference<Boolean> OSMO_SHOW_GROUP_NOTIFICATIONS = new BooleanPreference("osmo_show_toast_notifications", true).makeGlobal();
|
||||
|
||||
public final CommonPreference<Integer> OSMO_SAVE_TRACK_INTERVAL = new IntPreference("osmo_save_track_interval", 10000).makeGlobal().cache();
|
||||
|
||||
public final OsmandPreference<String> OSMO_GROUPS = new StringPreference("osmo_groups", "{}").makeGlobal();
|
||||
|
||||
public final OsmandPreference<Boolean> NO_DISCOUNT_INFO = new BooleanPreference("no_discount_info", false).makeGlobal();
|
||||
|
||||
|
|
|
@ -66,8 +66,6 @@ import net.osmand.plus.osmedit.EditPOIMenuController;
|
|||
import net.osmand.plus.osmedit.OsmBugMenuController;
|
||||
import net.osmand.plus.osmedit.OsmBugsLayer.OpenStreetNote;
|
||||
import net.osmand.plus.osmedit.OsmPoint;
|
||||
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoDevice;
|
||||
import net.osmand.plus.osmo.OsMoMenuController;
|
||||
import net.osmand.plus.parkingpoint.ParkingPositionMenuController;
|
||||
import net.osmand.plus.resources.ResourceManager;
|
||||
import net.osmand.plus.transport.TransportStopRoute;
|
||||
|
@ -181,8 +179,6 @@ public abstract class MenuController extends BaseMenuController implements Colla
|
|||
menuController = new HistoryMenuController(mapActivity, pointDescription, (SearchHistoryHelper.HistoryEntry) object);
|
||||
} else if (object instanceof TargetPoint) {
|
||||
menuController = new TargetPointMenuController(mapActivity, pointDescription, (TargetPoint) object);
|
||||
} else if (object instanceof OsMoDevice) {
|
||||
menuController = new OsMoMenuController(mapActivity, pointDescription, (OsMoDevice) object);
|
||||
} else if (object instanceof Recording) {
|
||||
menuController = new AudioVideoNoteMenuController(mapActivity, pointDescription, (Recording) object);
|
||||
} else if (object instanceof OsmPoint) {
|
||||
|
|
|
@ -31,7 +31,6 @@ public abstract class OsmandNotification {
|
|||
public enum NotificationType {
|
||||
NAVIGATION,
|
||||
GPX,
|
||||
OSMO,
|
||||
GPS
|
||||
}
|
||||
|
||||
|
|
|
@ -1,346 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.IconsCache;
|
||||
import net.osmand.plus.NavigationService;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.dashboard.DashLocationFragment;
|
||||
import net.osmand.plus.dashboard.DashboardOnMap;
|
||||
import net.osmand.plus.dashboard.tools.DashFragmentData;
|
||||
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoDevice;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Denis
|
||||
* on 20.01.2015.
|
||||
*/
|
||||
public class DashOsMoFragment extends DashLocationFragment implements OsMoGroups.OsMoGroupsUIListener {
|
||||
|
||||
public static final String TAG = "DASH_OSMO_FRAGMENT";
|
||||
|
||||
private static final DashFragmentData.ShouldShowFunction SHOULD_SHOW_FUNCTION =
|
||||
new DashboardOnMap.DefaultShouldShow() {
|
||||
@Override
|
||||
public int getTitleId() {
|
||||
return R.string.osmo_plugin_name;
|
||||
}
|
||||
};
|
||||
static final DashFragmentData FRAGMENT_DATA = new DashFragmentData(
|
||||
DashOsMoFragment.TAG, DashOsMoFragment.class, SHOULD_SHOW_FUNCTION, 120, null);
|
||||
private Handler uiHandler = new Handler();
|
||||
|
||||
OsMoPlugin plugin;
|
||||
private CompoundButton trackr;
|
||||
|
||||
CompoundButton.OnCheckedChangeListener trackerCheckedChatgedListener = new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
plugin.getService().connect(true);
|
||||
|
||||
if (isChecked) {
|
||||
if (plugin != null && plugin.getTracker() != null) {
|
||||
plugin.getTracker().enableTracker();
|
||||
}
|
||||
getMyApplication().startNavigationService(NavigationService.USED_BY_LIVE, 0);
|
||||
} else {
|
||||
if (plugin != null && plugin.getTracker() != null) {
|
||||
plugin.getTracker().disableTracker();
|
||||
}
|
||||
if (getMyApplication().getNavigationService() != null) {
|
||||
getMyApplication().getNavigationService()
|
||||
.stopIfNeeded(getMyApplication(), NavigationService.USED_BY_LIVE);
|
||||
}
|
||||
}
|
||||
|
||||
updateStatus();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCloseDash() {
|
||||
if (plugin != null && plugin.getGroups() != null) {
|
||||
plugin.getGroups().removeUiListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View initView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
plugin = OsmandPlugin.getEnabledPlugin(OsMoPlugin.class);
|
||||
|
||||
View view = getActivity().getLayoutInflater().inflate(R.layout.dash_osmo_fragment, container, false);
|
||||
view.findViewById(R.id.manage).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
launchOsMoGroupsActivity();
|
||||
}
|
||||
});
|
||||
if(plugin != null) {
|
||||
plugin.setGroupsActivity(getActivity());
|
||||
}
|
||||
setupHader(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpenDash() {
|
||||
plugin = OsmandPlugin.getEnabledPlugin(OsMoPlugin.class);
|
||||
if (plugin != null) {
|
||||
plugin.getGroups().addUiListeners(this);
|
||||
plugin.setGroupsActivity(getActivity());
|
||||
|
||||
trackr.setChecked(plugin.getTracker().isEnabledTracker());
|
||||
trackr.setOnCheckedChangeListener(trackerCheckedChatgedListener);
|
||||
}
|
||||
setupOsMoView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
if (plugin != null) {
|
||||
plugin.setGroupsActivity(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (plugin != null) {
|
||||
plugin.setGroupsActivity(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupOsMoView() {
|
||||
View mainView = getView();
|
||||
|
||||
if (plugin == null) {
|
||||
mainView.setVisibility(View.GONE);
|
||||
return;
|
||||
} else {
|
||||
mainView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
private void setupHader(final View header) {
|
||||
trackr = (CompoundButton) header.findViewById(R.id.card_content).findViewById(R.id.toggle_item);
|
||||
|
||||
ImageButton share = (ImageButton) header.findViewById(R.id.share);
|
||||
IconsCache cache = getMyApplication().getIconsCache();
|
||||
share.setImageDrawable(cache.getThemedIcon(R.drawable.ic_action_gshare_dark));
|
||||
share.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
OsMoGroupsActivity.shareSessionUrl(plugin, getActivity());
|
||||
}
|
||||
});
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
private void updateStatus() {
|
||||
|
||||
View header = getView();
|
||||
if (getView() == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
View cardContent = header.findViewById(R.id.card_content);
|
||||
View enableOsmo = header.findViewById(R.id.header_layout).findViewById(R.id.toggle_item);
|
||||
View manage = header.findViewById(R.id.manage);
|
||||
if (plugin != null && plugin.getService().isEnabled() ) {
|
||||
cardContent.setVisibility(View.VISIBLE);
|
||||
enableOsmo.setVisibility(View.GONE);
|
||||
manage.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
cardContent.setVisibility(View.GONE);
|
||||
enableOsmo.setVisibility(View.VISIBLE);
|
||||
manage.setVisibility(View.GONE);
|
||||
getClearContentList(header);
|
||||
return;
|
||||
}
|
||||
|
||||
CompoundButton trackr = (CompoundButton) header.findViewById(R.id.toggle_item);
|
||||
if (plugin != null && plugin.getTracker() != null) {
|
||||
trackr.setChecked(plugin.getTracker().isEnabledTracker());
|
||||
}
|
||||
|
||||
updateConnectedDevices(header);
|
||||
}
|
||||
|
||||
private void updateConnectedDevices(View mainView) {
|
||||
OsMoGroups grps = plugin.getGroups();
|
||||
|
||||
LinearLayout contentList = getClearContentList(mainView);
|
||||
ArrayList<OsMoGroupsStorage.OsMoGroup> groups = new ArrayList<>(grps.getGroups());
|
||||
|
||||
List<OsMoGroupsStorage.OsMoDevice> devices = getOsMoDevices(groups);
|
||||
setupDeviceViews(contentList, devices);
|
||||
}
|
||||
|
||||
private List<OsMoGroupsStorage.OsMoDevice> getOsMoDevices(ArrayList<OsMoGroupsStorage.OsMoGroup> groups) {
|
||||
String trackerId = plugin.getService().getMyGroupTrackerId();
|
||||
List<OsMoGroupsStorage.OsMoDevice> devices = new ArrayList<>();
|
||||
if (groups.size() > 0) {
|
||||
for (OsMoGroupsStorage.OsMoGroup grp : groups) {
|
||||
for (OsMoGroupsStorage.OsMoDevice device : grp.getVisibleGroupUsers(trackerId)) {
|
||||
devices.add(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//remove all inactive devices
|
||||
Iterator<OsMoDevice> it = devices.iterator();
|
||||
while (it.hasNext()) {
|
||||
if (devices.size() < 4) {
|
||||
break;
|
||||
}
|
||||
OsMoGroupsStorage.OsMoDevice device = it.next();
|
||||
if (!device.isActive() && !device.isEnabled() && devices.size() > 2) {
|
||||
it.remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sortDevices(devices);
|
||||
|
||||
if (devices.size() > 3) {
|
||||
while (devices.size() > 3) {
|
||||
devices.remove(devices.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
private void sortDevices(List<OsMoGroupsStorage.OsMoDevice> devices) {
|
||||
try {
|
||||
Collections.sort(devices, new Comparator<OsMoDevice>() {
|
||||
|
||||
@Override
|
||||
public int compare(OsMoDevice lhs, OsMoDevice rhs) {
|
||||
Location ll = lhs.getLastLocation();
|
||||
Location rl = rhs.getLastLocation();
|
||||
double maxDist = 50000;
|
||||
double ld = ll == null || lastUpdatedLocation == null ? maxDist :
|
||||
MapUtils.getDistance(lastUpdatedLocation, ll.getLatitude(), ll.getLongitude());
|
||||
double rd = ll == null || lastUpdatedLocation == null ? maxDist :
|
||||
MapUtils.getDistance(lastUpdatedLocation, rl.getLatitude(), rl.getLongitude());
|
||||
if(ld == rd) {
|
||||
return lhs.getVisibleName().compareTo(rhs.getVisibleName());
|
||||
}
|
||||
return Double.compare(ld, rd);
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
// sorting could be unstable due to location change
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private LinearLayout getClearContentList(View mainView) {
|
||||
LinearLayout contentList = (LinearLayout) mainView.findViewById(R.id.items);
|
||||
contentList.removeAllViews();
|
||||
return contentList;
|
||||
}
|
||||
|
||||
private void setupDeviceViews(LinearLayout contentList, List<OsMoGroupsStorage.OsMoDevice> devices) {
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
List<DashLocationFragment.DashLocationView> distances = new ArrayList<>();
|
||||
for (final OsMoGroupsStorage.OsMoDevice device : devices) {
|
||||
View v = inflater.inflate(R.layout.dash_osmo_item, null, false);
|
||||
v.findViewById(R.id.people_icon).setVisibility(View.GONE);
|
||||
v.findViewById(R.id.people_count).setVisibility(View.GONE);
|
||||
v.findViewById(R.id.show_on_map).setVisibility(View.GONE);
|
||||
final String name = device.getVisibleName();
|
||||
final Location loc = device.getLastLocation();
|
||||
|
||||
ImageView direction = (ImageView) v.findViewById(R.id.direction_icon);
|
||||
direction.setVisibility(View.VISIBLE);
|
||||
TextView label = (TextView) v.findViewById(R.id.distance);
|
||||
DashLocationFragment.DashLocationView dv = new DashLocationFragment.DashLocationView(direction, label, loc != null ? new LatLon(loc.getLatitude(),
|
||||
loc.getLongitude()) : null);
|
||||
distances.add(dv);
|
||||
|
||||
final CompoundButton enableDevice = (CompoundButton) v.findViewById(R.id.toggle_item);
|
||||
enableDevice.setVisibility(View.GONE);
|
||||
ImageView icon = (ImageView) v.findViewById(R.id.icon);
|
||||
if (device.isEnabled()) {
|
||||
icon.setImageDrawable(getMyApplication().getIconsCache().
|
||||
getPaintedIcon(R.drawable.ic_person, device.getColor()));
|
||||
} else {
|
||||
icon.setImageDrawable(getMyApplication().getIconsCache().
|
||||
getThemedIcon(R.drawable.ic_person));
|
||||
}
|
||||
|
||||
((TextView) v.findViewById(R.id.name)).setText(name);
|
||||
v.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (loc == null || !device.isEnabled()) {
|
||||
launchOsMoGroupsActivity();
|
||||
} else {
|
||||
MapActivity.getSingleMapViewTrackingUtilities().setMapLinkedToLocation(false);
|
||||
getMyApplication().getSettings().setMapLocationToShow(loc.getLatitude(), loc.getLongitude(), getMyApplication().getSettings().getLastKnownMapZoom(),
|
||||
new PointDescription(PointDescription.POINT_TYPE_MARKER, device.getVisibleName()), false,
|
||||
device);
|
||||
OsMoPositionLayer.setFollowTrackerId(device, loc);
|
||||
MapActivity.launchMapActivityMoveToTop(getActivity());
|
||||
}
|
||||
}
|
||||
});
|
||||
contentList.addView(v);
|
||||
}
|
||||
this.distances = distances;
|
||||
}
|
||||
|
||||
|
||||
private void launchOsMoGroupsActivity() {
|
||||
Intent intent = new Intent(getActivity(), OsMoGroupsActivity.class);
|
||||
getActivity().startActivity(intent);
|
||||
closeDashboard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void groupsListChange(String operation, OsMoGroupsStorage.OsMoGroup group) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateStatus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deviceLocationChanged(OsMoGroupsStorage.OsMoDevice device) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateConnectedDevices(getView());
|
||||
updateAllWidgets();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
public class OsMoConnectionException extends RuntimeException {
|
||||
public OsMoConnectionException(String detailMessage) {
|
||||
super(detailMessage);
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.NavigationService;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.TargetPointsHelper;
|
||||
import net.osmand.plus.Version;
|
||||
import net.osmand.plus.TargetPointsHelper.TargetPoint;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Vibrator;
|
||||
|
||||
public class OsMoControlDevice implements OsMoReactor {
|
||||
|
||||
private OsMoService service;
|
||||
private OsmandApplication app;
|
||||
private OsMoTracker tracker;
|
||||
private OsMoPlugin plugin;
|
||||
|
||||
public OsMoControlDevice(OsmandApplication app, OsMoPlugin plugin,
|
||||
OsMoService service, OsMoTracker tracker) {
|
||||
this.app = app;
|
||||
this.plugin = plugin;
|
||||
this.service = service;
|
||||
this.tracker = tracker;
|
||||
service.registerReactor(this);
|
||||
}
|
||||
|
||||
public JSONObject getBatteryLevel() throws JSONException {
|
||||
Intent batteryIntent = app.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
|
||||
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
|
||||
int plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
|
||||
int temperature = batteryIntent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
|
||||
int voltage = batteryIntent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
|
||||
|
||||
JSONObject postjson = new JSONObject();
|
||||
postjson.put("batteryprocent", (level == -1 || scale == -1)? 50.0f : ((float)level / (float)scale) * 100.0f);
|
||||
postjson.put("temperature", temperature);
|
||||
postjson.put("voltage", voltage);
|
||||
postjson.put("plugged", plugged);
|
||||
|
||||
return postjson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptCommand(String command, String id, String data, JSONObject obj, OsMoThread tread) {
|
||||
if(command.equals("REMOTE_CONTROL")) {
|
||||
if(data.equals("PP")) {
|
||||
service.pushCommand("PP");
|
||||
} else if(data.equals("FF")) {
|
||||
Location ll = app.getLocationProvider().getLastKnownLocation();
|
||||
if(ll == null) {
|
||||
service.pushCommand("FF|0");
|
||||
} else {
|
||||
service.pushCommand("FF|"+OsMoTracker.formatLocation(ll));
|
||||
}
|
||||
} else if(data.equals("BATTERY_INFO")) {
|
||||
try {
|
||||
service.pushCommand("BATTERY_INFO|"+getBatteryLevel().toString());
|
||||
} catch(JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if(data.equals("VIBRATE")) {
|
||||
Vibrator v = (Vibrator) app.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
// Vibrate for 500 milliseconds
|
||||
v.vibrate(1000);
|
||||
} else if(data.equals("STOP_TRACKING")) {
|
||||
tracker.disableTracker();
|
||||
if (app.getNavigationService() != null) {
|
||||
app.getNavigationService().stopIfNeeded(app, NavigationService.USED_BY_LIVE);
|
||||
}
|
||||
} else if(data.equals("START_TRACKING")) {
|
||||
tracker.enableTrackerCmd();
|
||||
app.startNavigationService(NavigationService.USED_BY_LIVE, 0);
|
||||
//interval setting not needed here, handled centrally in app.startNavigationService
|
||||
//app.getSettings().SERVICE_OFF_INTERVAL.set(0);
|
||||
} else if(data.equals("OSMAND_INFO")) {
|
||||
JSONObject robj = new JSONObject();
|
||||
try {
|
||||
robj.put("full_version", Version.getFullVersion(app));
|
||||
robj.put("version", Version.getAppVersion(app));
|
||||
TargetPointsHelper tg = app.getTargetPointsHelper();
|
||||
if(tg.getPointToNavigate() != null) {
|
||||
addPoint(robj, "target_", tg.getPointToNavigate().point, tg.getPointToNavigate().getOriginalPointDescription());
|
||||
}
|
||||
List<TargetPoint> intermediatePoints = tg.getIntermediatePoints();
|
||||
if (intermediatePoints.size() > 0) {
|
||||
JSONArray ar = new JSONArray();
|
||||
robj.put("intermediates", ar);
|
||||
for (int i = 0; i < intermediatePoints.size(); i++) {
|
||||
JSONObject js = new JSONObject();
|
||||
ar.put(js);
|
||||
addPoint(js, "", intermediatePoints.get(i).point, intermediatePoints.get(i).getOriginalPointDescription());
|
||||
}
|
||||
}
|
||||
service.pushCommand("OSMAND_INFO|"+robj.toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if(command.equals("TP")) {
|
||||
plugin.getDownloadGpxTask(true).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, obj);
|
||||
} else if (command.equals("PP")) {
|
||||
service.pushCommand("PP");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addPoint(JSONObject robj, String prefix, LatLon pointToNavigate, PointDescription pointNavigateDescription) throws JSONException {
|
||||
robj.put(prefix+"lat", pointToNavigate.getLatitude());
|
||||
robj.put(prefix+"lon", pointToNavigate.getLongitude());
|
||||
if(pointNavigateDescription != null) {
|
||||
robj.put(prefix+"name", pointNavigateDescription.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextSendCommand(OsMoThread tracker) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(String msg) {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,498 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoDevice;
|
||||
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoGroup;
|
||||
import net.osmand.plus.osmo.OsMoTracker.OsmoTrackerListener;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
|
||||
|
||||
private static final String GROUP_NAME = "name";
|
||||
private static final String ACTIVE = "active";
|
||||
private static final String GROUP_ID = "group_id";
|
||||
private static final String EXPIRE_TIME = "expireTime";
|
||||
private static final String DESCRIPTION = "description";
|
||||
private static final String POLICY = "policy";
|
||||
private static final String USERS = "users";
|
||||
private static final String USER_NAME = "name";
|
||||
private static final String USER_COLOR = "color";
|
||||
private static final String DELETED = "deleted";
|
||||
private static final String GROUP_TRACKER_ID = "group_tracker_id";
|
||||
private static final String LAST_ONLINE = "last_online";
|
||||
private static final String TRACK = "track";
|
||||
private static final String POINT = "point";
|
||||
|
||||
private OsMoTracker tracker;
|
||||
private OsMoService service;
|
||||
private OsMoGroupsStorage storage;
|
||||
private ArrayList<OsMoGroupsUIListener> uiListeners = new ArrayList<>();
|
||||
private OsMoPlugin plugin;
|
||||
private OsmandApplication app;
|
||||
|
||||
private Gson gson = new Gson();
|
||||
|
||||
public interface OsMoGroupsUIListener {
|
||||
|
||||
public void groupsListChange(String operation, OsMoGroup group);
|
||||
|
||||
public void deviceLocationChanged(OsMoDevice device);
|
||||
}
|
||||
|
||||
public OsMoGroups(OsMoPlugin plugin, OsMoService service, OsMoTracker tracker, OsmandApplication app) {
|
||||
this.plugin = plugin;
|
||||
this.service = service;
|
||||
this.tracker = tracker;
|
||||
this.app = app;
|
||||
service.registerReactor(this);
|
||||
tracker.setTrackerListener(this);
|
||||
storage = new OsMoGroupsStorage(this, app.getSettings().OSMO_GROUPS);
|
||||
if (!service.isLoggedIn()) {
|
||||
storage.load();
|
||||
}
|
||||
}
|
||||
|
||||
public void addUiListeners(OsMoGroupsUIListener uiListener) {
|
||||
if (!uiListeners.contains(uiListener)) {
|
||||
uiListeners.add(uiListener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeUiListener(OsMoGroupsUIListener uiListener) {
|
||||
uiListeners.remove(uiListener);
|
||||
}
|
||||
|
||||
private void connectDeviceImpl(OsMoDevice d) {
|
||||
d.enabled = true;
|
||||
d.active = true;
|
||||
String mid = service.getMyTrackerId();
|
||||
String mgid = service.getMyGroupTrackerId();
|
||||
if ((mid == null || !mid.equals(d.getTrackerId()))
|
||||
&& (mgid == null || !mgid.equals(d.getTrackerId()))) {
|
||||
tracker.startTrackingId(d);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected() {
|
||||
if (service.isLoggedIn()) {
|
||||
service.pushCommand("GROUP_GET_ALL");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(String msg) {
|
||||
}
|
||||
|
||||
private String connectGroupImpl(OsMoGroup g) {
|
||||
g.enabled = true;
|
||||
String operation = "GROUP_CONNECT:" + g.groupId;
|
||||
service.pushCommand("GROUP_CONNECT:" + g.groupId);
|
||||
return operation;
|
||||
}
|
||||
|
||||
public String connectGroup(OsMoGroup model) {
|
||||
String op = connectGroupImpl(model);
|
||||
storage.save();
|
||||
return op;
|
||||
}
|
||||
|
||||
public String disconnectGroup(OsMoGroup model) {
|
||||
model.enabled = false;
|
||||
String operation = "GROUP_DISCONNECT:" + model.groupId;
|
||||
service.pushCommand(operation);
|
||||
for (OsMoDevice d : model.getGroupUsers(null)) {
|
||||
tracker.stopTrackingId(d);
|
||||
}
|
||||
storage.save();
|
||||
return operation;
|
||||
}
|
||||
|
||||
|
||||
private void disconnectImpl(OsMoDevice model) {
|
||||
model.active = false;
|
||||
tracker.stopTrackingId(model);
|
||||
}
|
||||
|
||||
|
||||
public Collection<OsMoGroup> getGroups() {
|
||||
return storage.getGroups();
|
||||
}
|
||||
|
||||
public void showErrorMessage(String message) {
|
||||
service.showErrorMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locationChange(String trackerId, Location location) {
|
||||
for (OsMoGroup g : getGroups()) {
|
||||
OsMoDevice d = g.updateLastLocation(trackerId, location);
|
||||
if (d != null && uiListeners != null) {
|
||||
for (OsMoGroupsUIListener listener : uiListeners) {
|
||||
listener.deviceLocationChanged(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean acceptCommand(String command, String gid, String data, JSONObject obj, OsMoThread thread) {
|
||||
boolean processed = false;
|
||||
String operation = command + ":" + gid;
|
||||
OsMoGroup group = null;
|
||||
if (command.equalsIgnoreCase("GP")) {
|
||||
group = storage.getGroup(gid);
|
||||
if (group != null && gid.length() > 0) {
|
||||
List<OsMoDevice> delta = mergeGroup(group, obj, false, false);
|
||||
String mygid = service.getMyGroupTrackerId();
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (OsMoDevice d : delta) {
|
||||
if (d.getDeletedTimestamp() != 0 && d.isEnabled()) {
|
||||
if (group.name != null && !d.getTrackerId().equals(mygid)) {
|
||||
b.append(app.getString(R.string.osmo_user_left, d.getVisibleName(), group.getVisibleName(app))).append("\n");
|
||||
}
|
||||
disconnectImpl(d);
|
||||
} else if (!d.isActive()) {
|
||||
if (group.name != null && !d.getTrackerId().equals(mygid)) {
|
||||
b.append(app.getString(R.string.osmo_user_joined, d.getVisibleName(), group.getVisibleName(app))).append("\n");
|
||||
}
|
||||
connectDeviceImpl(d);
|
||||
}
|
||||
}
|
||||
if (b.length() > 0 && app.getSettings().OSMO_SHOW_GROUP_NOTIFICATIONS.get()) {
|
||||
app.showToastMessage(b.toString().trim());
|
||||
}
|
||||
storage.save();
|
||||
}
|
||||
processed = true;
|
||||
} else if (command.equalsIgnoreCase("GROUP_DISCONNECT")) {
|
||||
group = storage.getGroup(gid);
|
||||
if (group != null) {
|
||||
if (obj == null || !obj.has("error")) {
|
||||
disconnectAllGroupUsers(group);
|
||||
disableGroupTracks(group, group.groupTracks);
|
||||
disableGroupTracks(group, Collections.singleton(group.name + " points.gpx"));
|
||||
}
|
||||
processed = true;
|
||||
}
|
||||
} else if (command.equalsIgnoreCase("GROUP_CONNECT")) {
|
||||
group = storage.getGroup(gid);
|
||||
if (group != null) {
|
||||
mergeGroup(group, obj, true, true);
|
||||
group.active = true;
|
||||
// connect to enabled devices in group
|
||||
for (OsMoDevice d : group.getGroupUsers(null)) {
|
||||
if (d.isEnabled()) {
|
||||
d.active = false;
|
||||
connectDeviceImpl(d);
|
||||
}
|
||||
}
|
||||
storage.save();
|
||||
}
|
||||
processed = true;
|
||||
} else if (command.equalsIgnoreCase("GROUP_CREATE") || command.equalsIgnoreCase("GROUP_JOIN")) {
|
||||
if (command.equalsIgnoreCase("GROUP_CREATE")) {
|
||||
operation = command;
|
||||
try {
|
||||
gid = obj.getString(GROUP_ID);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
service.showErrorMessage(e.getMessage());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
group = storage.getGroup(gid);
|
||||
if (group == null) {
|
||||
group = new OsMoGroup();
|
||||
group.groupId = gid;
|
||||
storage.addGroup(group);
|
||||
}
|
||||
connectGroupImpl(group);
|
||||
storage.save();
|
||||
processed = true;
|
||||
} else if (command.equals("GROUP_LEAVE")) {
|
||||
group = storage.getGroup(gid);
|
||||
if (group != null) {
|
||||
storage.deleteGroup(group);
|
||||
}
|
||||
storage.save();
|
||||
processed = true;
|
||||
} else if (command.equals("GROUP_GET_ALL")) {
|
||||
try {
|
||||
JSONArray arr = new JSONArray(data);
|
||||
int arrLength = arr.length();
|
||||
if (arrLength > 0) {
|
||||
Map<String, OsMoGroup> receivedGroups = new HashMap<String, OsMoGroupsStorage.OsMoGroup>();
|
||||
for (int i = 0; i < arrLength; i++) {
|
||||
JSONObject o = arr.getJSONObject(i);
|
||||
OsMoGroup parsedGroup = parseGroup(o);
|
||||
receivedGroups.put(parsedGroup.getGroupId(), parsedGroup);
|
||||
}
|
||||
|
||||
storage.mergeGroups(receivedGroups);
|
||||
storage.save();
|
||||
}
|
||||
processed = true;
|
||||
for (OsMoGroup g : storage.getGroups()) {
|
||||
if (!g.isMainGroup() && g.isEnabled()) {
|
||||
connectGroupImpl(g);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
service.showErrorMessage(e.getMessage());
|
||||
return processed;
|
||||
}
|
||||
}
|
||||
if (processed && uiListeners != null) {
|
||||
for (OsMoGroupsUIListener listener : uiListeners) {
|
||||
listener.groupsListChange(operation, group);
|
||||
}
|
||||
}
|
||||
return processed;
|
||||
}
|
||||
|
||||
private void disableGroupTracks(OsMoGroup group, Collection<String> tracks) {
|
||||
if (!tracks.isEmpty()) {
|
||||
GpxSelectionHelper helper = app.getSelectedGpxHelper();
|
||||
for (String t : tracks) {
|
||||
SelectedGpxFile sg = helper.getSelectedFileByName("osmo/" + t);
|
||||
if (sg != null && sg.getGpxFile() != null) {
|
||||
helper.selectGpxFile(sg.getGpxFile(), false, false);
|
||||
}
|
||||
}
|
||||
plugin.refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
private OsMoGroup parseGroup(JSONObject obj) throws JSONException {
|
||||
OsMoGroup groupe = new OsMoGroup();
|
||||
groupe.enabled = !(obj.has(ACTIVE) && ("0".equals(obj.getString(ACTIVE)) ||
|
||||
"false".equals(obj.getString(ACTIVE))));
|
||||
groupe.name = obj.optString(GROUP_NAME);
|
||||
groupe.groupId = obj.getString(GROUP_ID);
|
||||
groupe.description = obj.optString(DESCRIPTION);
|
||||
groupe.policy = obj.optString(POLICY);
|
||||
return groupe;
|
||||
}
|
||||
|
||||
|
||||
private void parseGroup(JSONObject obj, OsMoGroup gr) {
|
||||
try {
|
||||
if (obj.has(GROUP_NAME)) {
|
||||
gr.name = obj.getString(GROUP_NAME);
|
||||
}
|
||||
if (obj.has(DESCRIPTION)) {
|
||||
gr.description = obj.getString(DESCRIPTION);
|
||||
}
|
||||
if (obj.has(POLICY)) {
|
||||
gr.policy = obj.getString(POLICY);
|
||||
}
|
||||
if (obj.has(EXPIRE_TIME)) {
|
||||
gr.expireTime = obj.getLong(EXPIRE_TIME);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
service.showErrorMessage(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void disconnectAllGroupUsers(OsMoGroup gr) {
|
||||
gr.active = false;
|
||||
for (OsMoDevice d : gr.getGroupUsers(null)) {
|
||||
disconnectImpl(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<OsMoDevice> mergeGroup(OsMoGroup gr, JSONObject obj, boolean deleteUsers,
|
||||
boolean isGroupConnect) {
|
||||
List<OsMoDevice> delta = new ArrayList<OsMoDevice>();
|
||||
try {
|
||||
if (obj.has("group")) {
|
||||
parseGroup(obj.getJSONObject("group"), gr);
|
||||
}
|
||||
Map<String, OsMoDevice> toDelete = new HashMap<String, OsMoDevice>(gr.users);
|
||||
if (obj.has(USERS)) {
|
||||
JSONArray arr = obj.getJSONArray(USERS);
|
||||
for (int i = 0; i < arr.length(); i++) {
|
||||
JSONObject o = (JSONObject) arr.get(i);
|
||||
String tid = o.getString(GROUP_TRACKER_ID);
|
||||
OsMoDevice device = toDelete.remove(tid);
|
||||
if (device == null) {
|
||||
device = new OsMoDevice();
|
||||
device.group = gr;
|
||||
device.trackerId = tid;
|
||||
device.enabled = true;
|
||||
gr.users.put(tid, device);
|
||||
}
|
||||
if (o.has(USER_NAME)) {
|
||||
device.serverName = o.getString(USER_NAME);
|
||||
}
|
||||
if (o.has(DELETED)) {
|
||||
device.deleted = System.currentTimeMillis();
|
||||
} else {
|
||||
device.deleted = 0;
|
||||
}
|
||||
|
||||
if (o.has(LAST_ONLINE)) {
|
||||
device.lastOnline = o.getLong(LAST_ONLINE);
|
||||
}
|
||||
if (o.has(USER_COLOR)) {
|
||||
device.serverColor = net.osmand.util.Algorithms.parseColor(o.getString(USER_COLOR));
|
||||
}
|
||||
delta.add(device);
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.has(TRACK)) {
|
||||
JSONArray ar = obj.getJSONArray(TRACK);
|
||||
List<JSONObject> a = new ArrayList<>(ar.length());
|
||||
Set<String> toDeleteT = new HashSet<String>(gr.groupTracks);
|
||||
gr.groupTracks.clear();
|
||||
for (int i = 0; i < ar.length(); i++) {
|
||||
JSONObject trackJson = (JSONObject) ar.get(i);
|
||||
if (!trackJson.has(DELETED)) {
|
||||
String track = trackJson.getString("name") + ".gpx";
|
||||
gr.groupTracks.add(track);
|
||||
toDeleteT.remove(track);
|
||||
a.add(trackJson);
|
||||
}
|
||||
}
|
||||
plugin.getDownloadGpxTask(true).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, a.toArray(new JSONObject[a.size()]));
|
||||
disableGroupTracks(gr, toDeleteT);
|
||||
}
|
||||
|
||||
if (obj.has(POINT)) {
|
||||
JSONArray ar = obj.getJSONArray(POINT);
|
||||
ArrayList<WptPt> points = new ArrayList<WptPt>();
|
||||
long modify = obj.has("point_modify") ? obj.getLong("point_modify") : System.currentTimeMillis();
|
||||
JSONObject[] a = new JSONObject[ar.length()];
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
a[i] = (JSONObject) ar.get(i);
|
||||
final JSONObject jobj = a[i];
|
||||
WptPt pt = new WptPt();
|
||||
if (jobj.has("deleted")) {
|
||||
pt.deleted = true;
|
||||
} else {
|
||||
pt.lat = a[i].getDouble("lat");
|
||||
pt.lon = a[i].getDouble("lon");
|
||||
if (jobj.has("name")) {
|
||||
pt.name = jobj.getString("name");
|
||||
}
|
||||
if (jobj.has("color")) {
|
||||
pt.setColor(Algorithms.parseColor(jobj.getString("color")));
|
||||
}
|
||||
if (jobj.has("description")) {
|
||||
pt.desc = jobj.getString("description");
|
||||
}
|
||||
if (jobj.has("created")) {
|
||||
pt.getExtensionsToWrite().put("created", a[i].getLong("created") + "");
|
||||
}
|
||||
if (jobj.has("visible")) {
|
||||
pt.getExtensionsToWrite().put("visible", a[i].getBoolean("visible") + "");
|
||||
}
|
||||
}
|
||||
if (jobj.has("u")) {
|
||||
pt.getExtensionsToWrite().put("u", String.valueOf(a[i].getLong("u")));
|
||||
}
|
||||
points.add(pt);
|
||||
}
|
||||
if (points.size() > 0) {
|
||||
plugin.getSaveGpxTask(gr.name + " points", modify, false, isGroupConnect)
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, points.toArray(new WptPt[points.size()]));
|
||||
}
|
||||
}
|
||||
if (deleteUsers) {
|
||||
for (OsMoDevice s : toDelete.values()) {
|
||||
s.deleted = System.currentTimeMillis();
|
||||
delta.add(s);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
service.showErrorMessage(e.getMessage());
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
public String createGroup(String groupName, boolean onlyByInvite, String description, String policy) {
|
||||
Protocol.CreateGroupData obj = new Protocol.CreateGroupData(groupName,
|
||||
onlyByInvite, description, policy);
|
||||
service.pushCommand("GROUP_CREATE|" + gson.toJson(obj));
|
||||
return "GROUP_CREATE";
|
||||
}
|
||||
|
||||
|
||||
public void setGenColor(OsMoDevice device, int genColor) {
|
||||
device.genColor = genColor;
|
||||
storage.save();
|
||||
}
|
||||
|
||||
public String joinGroup(String groupId, String userName, String nick) {
|
||||
final String op = "GROUP_JOIN:" + groupId + "|" + nick;
|
||||
OsMoGroup g = storage.getGroup(groupId);
|
||||
if (g == null) {
|
||||
g = new OsMoGroup();
|
||||
g.groupId = groupId;
|
||||
storage.addGroup(g);
|
||||
}
|
||||
g.userName = userName;
|
||||
service.pushCommand(op);
|
||||
return "GROUP_JOIN:" + groupId;
|
||||
}
|
||||
|
||||
public String leaveGroup(OsMoGroup group) {
|
||||
final String op = "GROUP_LEAVE:" + group.groupId;
|
||||
storage.deleteGroup(group);
|
||||
storage.save();
|
||||
service.pushCommand(op);
|
||||
if (group.isEnabled()) {
|
||||
group.enabled = false;
|
||||
disconnectAllGroupUsers(group);
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
|
||||
public void setDeviceProperties(OsMoDevice model, String name, int color) {
|
||||
model.userName = name;
|
||||
model.userColor = color;
|
||||
storage.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextSendCommand(OsMoThread tracker) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clearGroups() {
|
||||
storage.clearGroups();
|
||||
storage.save();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,487 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.OsmandSettings.OsmandPreference;
|
||||
import net.osmand.plus.R;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
|
||||
public class OsMoGroupsStorage {
|
||||
private static final String GROUPS = "groups";
|
||||
private static final String USERS = "users";
|
||||
private static final String TRACKS = "tracks";
|
||||
private static final String SERVER_NAME = "serverName";
|
||||
private static final String GROUP_ID = "group_id";
|
||||
private static final String TRACKER_ID = "trackerId";
|
||||
private static final String USER_NAME = "userName";
|
||||
private static final String USER_COLOR = "userSetColor";
|
||||
private static final String GEN_COLOR = "genColor";
|
||||
private static final String SERVER_COLOR = "serverColor";
|
||||
private static final String DESCRIPTION = "description";
|
||||
private static final String POLICY = "policy";
|
||||
private static final String NAME = "name";
|
||||
private static final String ENABLED = "enabled";
|
||||
private static final String EXPIRE_TIME = "expireTime";
|
||||
private static final String DELETED = "deleted";
|
||||
|
||||
private OsmandPreference<String> pref;
|
||||
private OsMoGroups service;
|
||||
private ConcurrentHashMap<String, OsMoGroup> groups = new ConcurrentHashMap<String, OsMoGroup>();
|
||||
|
||||
public OsMoGroupsStorage(OsMoGroups service, OsmandPreference<String> pref) {
|
||||
this.service = service;
|
||||
this.pref = pref;
|
||||
}
|
||||
|
||||
public Collection<OsMoGroup> getGroups() {
|
||||
return groups.values();
|
||||
}
|
||||
|
||||
|
||||
public void load() {
|
||||
String grp = pref.get();
|
||||
try {
|
||||
JSONObject obj = new JSONObject(grp);
|
||||
if(!obj.has(GROUPS)) {
|
||||
return;
|
||||
}
|
||||
JSONArray groups = obj.getJSONArray(GROUPS);
|
||||
for (int i = 0; i < groups.length(); i++) {
|
||||
JSONObject o = (JSONObject) groups.get(i);
|
||||
OsMoGroup group = new OsMoGroup();
|
||||
group.groupId = o.getString(GROUP_ID);
|
||||
if(o.has(NAME)) {
|
||||
group.name = o.getString(NAME);
|
||||
}
|
||||
if(o.has(EXPIRE_TIME)) {
|
||||
group.expireTime = o.getLong(EXPIRE_TIME);
|
||||
}
|
||||
if(o.has(USER_NAME)) {
|
||||
group.userName = o.getString(USER_NAME);
|
||||
}
|
||||
if(o.has(DESCRIPTION)) {
|
||||
group.description = o.getString(DESCRIPTION);
|
||||
}
|
||||
if(o.has(POLICY)) {
|
||||
group.policy = o.getString(POLICY);
|
||||
}
|
||||
if(o.has(ENABLED) && o.getBoolean(ENABLED)) {
|
||||
group.enabled = true;
|
||||
}
|
||||
parseGroupUsers(group, o);
|
||||
// parseGroupTracks(group, obj);
|
||||
this.groups.put(group.groupId, group);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
service.showErrorMessage(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void save() {
|
||||
JSONObject mainObj = new JSONObject();
|
||||
try {
|
||||
JSONArray ar = new JSONArray();
|
||||
for(OsMoGroup gr : groups.values()) {
|
||||
if(gr.isMainGroup()) {
|
||||
continue;
|
||||
}
|
||||
JSONObject obj = new JSONObject();
|
||||
if (gr.userName != null) {
|
||||
obj.put(USER_NAME, gr.userName);
|
||||
}
|
||||
if (gr.name != null) {
|
||||
obj.put(NAME, gr.name);
|
||||
}
|
||||
if(gr.description != null) {
|
||||
obj.put(DESCRIPTION, gr.description);
|
||||
}
|
||||
if(gr.policy != null) {
|
||||
obj.put(POLICY, gr.policy);
|
||||
}
|
||||
if(gr.expireTime != 0) {
|
||||
obj.put(EXPIRE_TIME, gr.expireTime);
|
||||
}
|
||||
if (gr.enabled) {
|
||||
obj.put(ENABLED, true);
|
||||
}
|
||||
obj.put(GROUP_ID, gr.groupId);
|
||||
ar.put(obj);
|
||||
saveGroupUsers(gr, obj);
|
||||
saveGroupTracks(gr, obj);
|
||||
}
|
||||
mainObj.put(GROUPS, ar);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
service.showErrorMessage(e.getMessage());
|
||||
}
|
||||
pref.set(mainObj.toString());
|
||||
}
|
||||
|
||||
private void saveGroupUsers(OsMoGroup gr, JSONObject grObj) throws JSONException {
|
||||
JSONArray ar = new JSONArray();
|
||||
for(OsMoDevice u : gr.users.values()) {
|
||||
JSONObject obj = new JSONObject();
|
||||
if (u.userName != null) {
|
||||
obj.put(USER_NAME, u.userName);
|
||||
}
|
||||
if (u.serverName != null) {
|
||||
obj.put(SERVER_NAME, u.serverName);
|
||||
}
|
||||
if (u.userColor != 0) {
|
||||
obj.put(USER_COLOR, u.userColor);
|
||||
}
|
||||
if (u.genColor != 0) {
|
||||
obj.put(GEN_COLOR, u.genColor);
|
||||
}
|
||||
if (u.serverColor != 0) {
|
||||
obj.put(SERVER_COLOR, u.serverColor);
|
||||
}
|
||||
if (u.deleted != 0) {
|
||||
obj.put(DELETED, u.deleted);
|
||||
}
|
||||
if(u.enabled) {
|
||||
obj.put(ENABLED, u.enabled);
|
||||
}
|
||||
obj.put(TRACKER_ID, u.trackerId);
|
||||
|
||||
ar.put(obj);
|
||||
}
|
||||
grObj.put(USERS, ar);
|
||||
}
|
||||
|
||||
private void saveGroupTracks(OsMoGroup gr, JSONObject grObj) throws JSONException {
|
||||
if (gr.groupTracks.size() > 0) {
|
||||
JSONArray ar = new JSONArray();
|
||||
for (String u : gr.groupTracks) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(NAME, u);
|
||||
ar.put(obj);
|
||||
}
|
||||
grObj.put(TRACKS, ar);
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseGroupUsers(OsMoGroup gr, JSONObject obj) throws JSONException {
|
||||
if(!obj.has(USERS)) {
|
||||
return;
|
||||
}
|
||||
JSONArray users = obj.getJSONArray(USERS);
|
||||
for (int i = 0; i < users.length(); i++) {
|
||||
JSONObject o = (JSONObject) users.get(i);
|
||||
OsMoDevice user = new OsMoDevice();
|
||||
user.group = gr;
|
||||
if(o.has(SERVER_NAME)) {
|
||||
user.serverName = o.getString(SERVER_NAME);
|
||||
}
|
||||
if(o.has(USER_NAME)) {
|
||||
user.userName = o.getString(USER_NAME);
|
||||
}
|
||||
if(o.has(SERVER_COLOR)) {
|
||||
user.serverColor = o.getInt(SERVER_COLOR);
|
||||
}
|
||||
if(o.has(USER_COLOR)) {
|
||||
user.userColor = o.getInt(USER_COLOR);
|
||||
}
|
||||
if(o.has(GEN_COLOR)) {
|
||||
user.genColor = o.getInt(GEN_COLOR);
|
||||
}
|
||||
if(o.has(DELETED)) {
|
||||
user.deleted = o.getLong(DELETED);
|
||||
}
|
||||
if(o.has(ENABLED) && o.getBoolean(ENABLED)) {
|
||||
user.enabled = true;
|
||||
}
|
||||
user.trackerId = o.getString(TRACKER_ID);
|
||||
gr.users.put(user.trackerId, user);
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseGroupTracks(OsMoGroup gr, JSONObject obj) throws JSONException {
|
||||
if(!obj.has(TRACKS)) {
|
||||
return;
|
||||
}
|
||||
JSONArray tracks = obj.getJSONArray(TRACKS);
|
||||
for (int i = 0; i < tracks.length(); i++) {
|
||||
JSONObject o = (JSONObject) tracks.get(i);
|
||||
if(o.has(NAME)) {
|
||||
gr.groupTracks.add(NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class OsMoGroup {
|
||||
protected String name;
|
||||
protected String userName;
|
||||
protected String description;
|
||||
protected String policy;
|
||||
protected String groupId;
|
||||
protected boolean enabled;
|
||||
protected long expireTime;
|
||||
protected boolean active;
|
||||
protected boolean deleted;
|
||||
|
||||
protected Map<String, OsMoDevice> users = new ConcurrentHashMap<String, OsMoDevice>();
|
||||
protected List<String> groupTracks = new ArrayList<String>();
|
||||
|
||||
public List<OsMoDevice> getGroupUsers(String mygid) {
|
||||
// filter deleted
|
||||
List<OsMoDevice> dvs = new ArrayList<OsMoDevice>(users.size());
|
||||
for(OsMoDevice d : users.values()) {
|
||||
if(mygid != null && mygid.equals(d.trackerId)) {
|
||||
continue;
|
||||
}
|
||||
if(d.getDeletedTimestamp() == 0) {
|
||||
dvs.add(d);
|
||||
}
|
||||
}
|
||||
return dvs;
|
||||
}
|
||||
|
||||
public List<String> getGroupTracks() {
|
||||
return groupTracks;
|
||||
}
|
||||
|
||||
public List<OsMoDevice> getVisibleGroupUsers(String mygid) {
|
||||
if(!isActive() && !isMainGroup()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return getGroupUsers(mygid);
|
||||
}
|
||||
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getPolicy() {
|
||||
return policy;
|
||||
}
|
||||
|
||||
public long getExpireTime() {
|
||||
return expireTime;
|
||||
}
|
||||
|
||||
public boolean isMainGroup() {
|
||||
return groupId == null;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public String getVisibleName(Context ctx){
|
||||
if(isMainGroup()) {
|
||||
return ctx.getString(R.string.osmo_connected_devices);
|
||||
}
|
||||
if(userName != null && userName.length() > 0) {
|
||||
return userName;
|
||||
}
|
||||
if(name == null) {
|
||||
return "";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public OsMoDevice updateLastLocation(String trackerId, Location location) {
|
||||
OsMoDevice d = users.get(trackerId);
|
||||
if(d != null) {
|
||||
d.setLastLocation(location);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OsMoMessage {
|
||||
protected long timestamp;
|
||||
protected LatLon location;
|
||||
protected String text;
|
||||
protected OsMoDevice user;
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public LatLon getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public OsMoDevice getUser() {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OsMoDevice {
|
||||
protected String serverName;
|
||||
protected String userName;
|
||||
protected int serverColor;
|
||||
protected int userColor;
|
||||
protected int genColor;
|
||||
protected String trackerId;
|
||||
protected boolean enabled;
|
||||
protected boolean active;
|
||||
protected long deleted;
|
||||
protected OsMoGroup group ;
|
||||
|
||||
protected ConcurrentLinkedQueue<Location> previousLocations = new java.util.concurrent.ConcurrentLinkedQueue<Location>();
|
||||
protected List<OsMoMessage> messages = new ArrayList<OsMoMessage>();
|
||||
protected long lastOnline;
|
||||
protected Location lastLocation;
|
||||
|
||||
|
||||
public List<OsMoMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public ConcurrentLinkedQueue<Location> getPreviousLocations(long threshold) {
|
||||
while(!previousLocations.isEmpty() && previousLocations.peek().getTime() < threshold) {
|
||||
previousLocations.poll();
|
||||
}
|
||||
return previousLocations;
|
||||
}
|
||||
|
||||
public void setLastLocation(Location lastLocation) {
|
||||
if(this.lastLocation != null) {
|
||||
previousLocations.add(this.lastLocation);
|
||||
}
|
||||
this.lastLocation = lastLocation;
|
||||
if (lastLocation != null) {
|
||||
setLastOnline(lastLocation.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public Location getLastLocation() {
|
||||
return lastLocation;
|
||||
}
|
||||
|
||||
public void setLastOnline(long lastOnline) {
|
||||
this.lastOnline = lastOnline;
|
||||
}
|
||||
|
||||
public long getLastOnline() {
|
||||
return lastOnline;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public long getDeletedTimestamp() {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public OsMoGroup getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public String getTrackerId() {
|
||||
return trackerId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getColor() {
|
||||
if(userColor != 0) {
|
||||
return userColor;
|
||||
}
|
||||
if(serverColor != 0) {
|
||||
return serverColor ;
|
||||
}
|
||||
return genColor;
|
||||
}
|
||||
|
||||
public int getNonActiveColor() {
|
||||
int color = getColor();
|
||||
int alpha = Math.round(Color.alpha(color) * 0.3f);
|
||||
int red = Color.red(color);
|
||||
int green = Color.green(color);
|
||||
int blue = Color.blue(color);
|
||||
return Color.argb(alpha, red, green, blue);
|
||||
}
|
||||
|
||||
public String getVisibleName(){
|
||||
if(userName != null && userName.length() > 0) {
|
||||
return userName;
|
||||
}
|
||||
if(serverName == null || serverName.length() == 0) {
|
||||
return trackerId;
|
||||
}
|
||||
return serverName;
|
||||
}
|
||||
}
|
||||
|
||||
public OsMoGroup getGroup(String gid) {
|
||||
return groups.get(gid);
|
||||
}
|
||||
|
||||
public void deleteGroup(OsMoGroup gr) {
|
||||
groups.remove(gr.groupId);
|
||||
gr.deleted = true;
|
||||
}
|
||||
|
||||
public void addGroup(OsMoGroup g) {
|
||||
groups.put(g.groupId, g);
|
||||
g.deleted = false;
|
||||
|
||||
}
|
||||
|
||||
public void mergeGroups(Map<String, OsMoGroup> groupsToMerge) {
|
||||
Set<String> toDelete = new HashSet<String>(groups.keySet());
|
||||
if (groupsToMerge != null) {
|
||||
Set<String> toMerge = groupsToMerge.keySet();
|
||||
for (String id: toMerge) {
|
||||
if (toDelete.contains(id)) {
|
||||
toDelete.remove(id);
|
||||
} else {
|
||||
addGroup(groupsToMerge.get(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String id: toDelete) {
|
||||
OsMoGroup group = getGroup(id);
|
||||
if (group != null) {
|
||||
deleteGroup(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clearGroups() {
|
||||
groups.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
public class OsMoIntentHandler extends AsyncTask<Intent, Void, String> {
|
||||
|
||||
private OsmandApplication app;
|
||||
private OsMoPlugin plugin;
|
||||
|
||||
public OsMoIntentHandler(OsmandApplication app, OsMoPlugin plugin) {
|
||||
this.app = app;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Intent... params) {
|
||||
try {
|
||||
while (app.isApplicationInitializing()) {
|
||||
Thread.sleep(200);
|
||||
}
|
||||
for (Intent intent : params) {
|
||||
String scheme = intent.getScheme();
|
||||
Uri data = intent.getData();
|
||||
if ("http".equals(scheme) && data.getHost().equals("z.osmo.mobi")) {
|
||||
String path = data.getPath();
|
||||
String lastPath = path.substring(path.lastIndexOf('/') + 1);
|
||||
if(lastPath.equals("login")) {
|
||||
String user = data.getQueryParameter("u");
|
||||
String pwd = data.getQueryParameter("p");
|
||||
app.getSettings().OSMO_USER_NAME.set(user);
|
||||
app.getSettings().OSMO_USER_PWD.set(pwd);
|
||||
plugin.getService().reconnectToServer();
|
||||
} else if(lastPath.equals("join")) {
|
||||
String gid = data.getQueryParameter("id");
|
||||
String name = data.getQueryParameter("name");
|
||||
if(name == null) {
|
||||
name = "";
|
||||
}
|
||||
plugin.getGroups().joinGroup(gid, name, app.getSettings().OSMO_USER_NAME.get());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
if(result != null) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.TargetPointsHelper;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.mapcontextmenu.MenuBuilder;
|
||||
import net.osmand.plus.mapcontextmenu.MenuController;
|
||||
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoDevice;
|
||||
|
||||
public class OsMoMenuController extends MenuController {
|
||||
|
||||
private OsMoDevice device;
|
||||
|
||||
public OsMoMenuController(MapActivity mapActivity, PointDescription pointDescription, OsMoDevice device) {
|
||||
super(new MenuBuilder(mapActivity), pointDescription, mapActivity);
|
||||
this.device = device;
|
||||
|
||||
leftTitleButtonController = new TitleButtonController() {
|
||||
@Override
|
||||
public void buttonPressed() {
|
||||
if (OsMoPositionLayer.getFollowDestinationId() != null) {
|
||||
OsMoPositionLayer.setFollowDestination(null);
|
||||
} else {
|
||||
OsMoDevice dev = getDevice();
|
||||
if(dev.getLastLocation() != null) {
|
||||
TargetPointsHelper targets = getMapActivity().getMyApplication().getTargetPointsHelper();
|
||||
targets.navigateToPoint(new LatLon(dev.getLastLocation().getLatitude(), dev.getLastLocation().getLongitude()), true, -1);
|
||||
}
|
||||
OsMoPositionLayer.setFollowDestination(dev);
|
||||
}
|
||||
getMapActivity().getContextMenu().updateMenuUI();
|
||||
}
|
||||
};
|
||||
|
||||
rightTitleButtonController = new TitleButtonController() {
|
||||
@Override
|
||||
public void buttonPressed() {
|
||||
OsMoPlugin osMoPlugin = OsmandPlugin.getEnabledPlugin(OsMoPlugin.class);
|
||||
if (osMoPlugin != null) {
|
||||
OsMoGroupsActivity.showSettingsDialog(getMapActivity(), osMoPlugin, getDevice());
|
||||
}
|
||||
}
|
||||
};
|
||||
rightTitleButtonController.caption = getMapActivity().getString(R.string.shared_string_settings);
|
||||
rightTitleButtonController.leftIconId = R.drawable.ic_action_settings;
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setObject(Object object) {
|
||||
if (object instanceof OsMoDevice) {
|
||||
this.device = (OsMoDevice) object;
|
||||
updateData();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getObject() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public OsMoDevice getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateData() {
|
||||
super.updateData();
|
||||
|
||||
if (OsMoPositionLayer.getFollowDestinationId() != null) {
|
||||
leftTitleButtonController.caption = getMapActivity().getString(R.string.shared_string_cancel);
|
||||
leftTitleButtonController.leftIconId = R.drawable.ic_action_remove_dark;
|
||||
} else {
|
||||
leftTitleButtonController.caption = getMapActivity().getString(R.string.mark_point);
|
||||
leftTitleButtonController.leftIconId = R.drawable.ic_action_intermediate;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSupportedMenuStatesPortrait() {
|
||||
return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needTypeStr() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getRightIcon() {
|
||||
if (isLight()) {
|
||||
return getIconOrig(R.drawable.widget_osmo_connected_location_day);
|
||||
} else {
|
||||
return getIconOrig(R.drawable.widget_osmo_connected_location_night);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeStr() {
|
||||
OsmandApplication app = getMapActivity().getMyApplication();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final Location l = device.getLastLocation();
|
||||
if(l != null && l.hasSpeed()) {
|
||||
sb.append(OsmAndFormatter.getFormattedSpeed(l.getSpeed(), app));
|
||||
sb.append(" — ");
|
||||
}
|
||||
Location myLocation = app.getLocationProvider().getLastKnownLocation();
|
||||
if (myLocation != null) {
|
||||
float dist = myLocation.distanceTo(l);
|
||||
sb.append(OsmAndFormatter.getFormattedDistance(dist, app));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needStreetName() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,523 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.ContextMenuAdapter;
|
||||
import net.osmand.plus.ContextMenuItem;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.NavigationService;
|
||||
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.dashboard.tools.DashFragmentData;
|
||||
import net.osmand.plus.download.DownloadFileHelper;
|
||||
import net.osmand.plus.osmo.OsMoService.SessionInfo;
|
||||
import net.osmand.plus.views.MapInfoLayer;
|
||||
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.mapwidgets.TextInfoWidget;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
public class OsMoPlugin extends OsmandPlugin implements OsMoReactor {
|
||||
|
||||
private OsmandApplication app;
|
||||
public static final String ID = "osmand.osmo";
|
||||
private OsMoService service;
|
||||
private OsMoTracker tracker;
|
||||
private OsMoGroups groups;
|
||||
private TextInfoWidget osmoControl;
|
||||
private OsMoPositionLayer olayer;
|
||||
protected MapActivity mapActivity;
|
||||
protected Activity groupsActivity;
|
||||
protected OsMoControlDevice deviceControl;
|
||||
|
||||
private final static Log LOG = PlatformUtil.getLog(OsMoPlugin.class);
|
||||
|
||||
|
||||
public OsMoPlugin(final OsmandApplication app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAssetResourceName() {
|
||||
return R.drawable.osmo_monitoring;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean init(final OsmandApplication app, Activity activity) {
|
||||
if (service == null) {
|
||||
service = new OsMoService(app, this);
|
||||
tracker = new OsMoTracker(service, app.getSettings().OSMO_SAVE_TRACK_INTERVAL,
|
||||
app.getSettings().OSMO_SEND_LOCATIONS_STATE);
|
||||
deviceControl = new OsMoControlDevice(app, this, service, tracker);
|
||||
groups = new OsMoGroups(this, service, tracker, app);
|
||||
}
|
||||
ApplicationMode.regWidgetVisibility("osmo_control", (ApplicationMode[]) null);
|
||||
if (app.getSettings().OSMO_AUTO_CONNECT.get() ||
|
||||
(System.currentTimeMillis() - app.getSettings().OSMO_LAST_PING.get() < 5 * 60 * 1000)) {
|
||||
service.connect(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public Activity getGroupsActivity() {
|
||||
return groupsActivity;
|
||||
}
|
||||
|
||||
public void setGroupsActivity(Activity groupsActivity) {
|
||||
this.groupsActivity = groupsActivity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(OsmandApplication app) {
|
||||
super.disable(app);
|
||||
if (app.getNavigationService() != null) {
|
||||
app.getNavigationService().stopIfNeeded(app, NavigationService.USED_BY_LIVE);
|
||||
}
|
||||
tracker.disableTracker();
|
||||
service.disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLocation(Location location) {
|
||||
tracker.sendCoordinate(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return app.getString(R.string.osmo_plugin_description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return app.getString(R.string.osmo_plugin_name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLogoResourceId() {
|
||||
return R.drawable.ic_osmo_dark;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelpFileName() {
|
||||
return "feature_articles/osmo-plugin.html";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayers(OsmandMapTileView mapView, MapActivity activity) {
|
||||
if (isActive()) {
|
||||
if (olayer == null) {
|
||||
registerLayers(activity);
|
||||
}
|
||||
if (osmoControl == null) {
|
||||
registerSideWidget(activity);
|
||||
}
|
||||
} else {
|
||||
MapInfoLayer layer = activity.getMapLayers().getMapInfoLayer();
|
||||
if (layer != null && osmoControl != null) {
|
||||
layer.removeSideWidget(osmoControl);
|
||||
osmoControl = null;
|
||||
layer.recreateControls();
|
||||
}
|
||||
if (olayer != null) {
|
||||
activity.getMapView().removeLayer(olayer);
|
||||
olayer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerLayers(MapActivity activity) {
|
||||
registerSideWidget(activity);
|
||||
if (olayer != null) {
|
||||
activity.getMapView().removeLayer(olayer);
|
||||
}
|
||||
olayer = new OsMoPositionLayer(activity, this);
|
||||
activity.getMapView().addLayer(olayer, 5.5f);
|
||||
}
|
||||
|
||||
private void registerSideWidget(MapActivity activity) {
|
||||
MapInfoLayer layer = activity.getMapLayers().getMapInfoLayer();
|
||||
if (layer != null) {
|
||||
osmoControl = createOsMoControl(activity);
|
||||
layer.registerSideWidget(osmoControl, R.drawable.ic_osmo_dark, R.string.osmo_control, "osmo_control",
|
||||
false, 31);
|
||||
layer.recreateControls();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mapActivityPause(MapActivity activity) {
|
||||
groups.removeUiListener(olayer);
|
||||
mapActivity = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mapActivityResume(MapActivity activity) {
|
||||
if (olayer != null) {
|
||||
groups.addUiListeners(olayer);
|
||||
}
|
||||
mapActivity = activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates (if it wasn't created previously) the control to be added on a MapInfoLayer that shows a monitoring state (recorded/stopped)
|
||||
*/
|
||||
private TextInfoWidget createOsMoControl(final MapActivity map) {
|
||||
final TextInfoWidget osmoControl = new TextInfoWidget(map) {
|
||||
long lastUpdateTime;
|
||||
private int blinkImg;
|
||||
|
||||
@Override
|
||||
public boolean updateInfo(DrawSettings drawSettings) {
|
||||
String txt = "OsMo";
|
||||
String subtxt = "";
|
||||
SessionInfo si = getService().getCurrentSessionInfo();
|
||||
if (si != null) {
|
||||
String uname = si.username;
|
||||
if (uname != null && uname.length() > 0) {
|
||||
if (uname.length() > 7) {
|
||||
for (int k = 4; k < uname.length(); k++) {
|
||||
if (!Character.isLetterOrDigit(uname.charAt(k)) &&
|
||||
uname.charAt(k) != '.' && uname.charAt(k) != '-') {
|
||||
uname = uname.substring(0, k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uname.length() > 12) {
|
||||
uname = uname.substring(0, 12);
|
||||
}
|
||||
}
|
||||
if (uname.length() > 4) {
|
||||
txt = "";
|
||||
subtxt = uname;
|
||||
} else {
|
||||
txt = uname;
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean night = drawSettings != null && drawSettings.isNightMode();
|
||||
int srcSignalinactive = !night ? R.drawable.widget_osmo_inactive_day : R.drawable.widget_osmo_inactive_night;
|
||||
int small = srcSignalinactive; //tracker.isEnabledTracker() ? srcSignalinactive : srcinactive;
|
||||
int big = srcSignalinactive; // tracker.isEnabledTracker() ? srcSignalinactive : srcinactive;
|
||||
long last = service.getLastCommandTime();
|
||||
if (service.isActive()) {
|
||||
if (tracker.isEnabledTracker()) {
|
||||
small = night ? R.drawable.widget_osmo_connected_location_night : R.drawable.widget_osmo_connected_location_day;
|
||||
big = night ? R.drawable.widget_osmo_connected_location_night : R.drawable.widget_osmo_connected_location_day;
|
||||
} else {
|
||||
small = night ? R.drawable.widget_osmo_connected_night : R.drawable.widget_osmo_connected_day;
|
||||
big = night ? R.drawable.widget_osmo_connected_night : R.drawable.widget_osmo_connected_day;
|
||||
}
|
||||
}
|
||||
setText(txt, subtxt);
|
||||
if (blinkImg != small) {
|
||||
setImageDrawable(small);
|
||||
}
|
||||
if (last != lastUpdateTime) {
|
||||
lastUpdateTime = last;
|
||||
blink(big, small);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void blink(int bigger, final int smaller) {
|
||||
blinkImg = smaller;
|
||||
setImageDrawable(bigger);
|
||||
map.getMyApplication().runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
blinkImg = 0;
|
||||
setImageDrawable(smaller);
|
||||
}
|
||||
}, 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
|
||||
public Class<? extends Activity> getSettingsActivity() {
|
||||
return SettingsOsMoActivity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerOptionsMenuItems(final MapActivity mapActivity, ContextMenuAdapter helper) {
|
||||
helper.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.osmo_groups, mapActivity)
|
||||
.setIcon(R.drawable.ic_osmo_dark)
|
||||
.setListener(new ContextMenuAdapter.ItemClickListener() {
|
||||
@Override
|
||||
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
|
||||
Intent intent = new Intent(mapActivity, OsMoGroupsActivity.class);
|
||||
mapActivity.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
})
|
||||
.setPosition(6)
|
||||
.createItem());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public OsMoGroups getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public OsMoTracker getTracker() {
|
||||
return tracker;
|
||||
}
|
||||
|
||||
public OsMoService getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public AsyncTask<WptPt, String, String> getSaveGpxTask(final String name,
|
||||
final long timestamp,
|
||||
final boolean generateToast,
|
||||
final boolean isGroupConnect) {
|
||||
return new AsyncTask<WptPt, String, String>() {
|
||||
|
||||
protected void onProgressUpdate(String... values) {
|
||||
if (values != null && generateToast) {
|
||||
String t = "";
|
||||
for (String s : values) {
|
||||
t += s + "\n";
|
||||
}
|
||||
app.showToastMessage(t.trim());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(WptPt... params) {
|
||||
final File fl = app.getAppPath(IndexConstants.GPX_INDEX_DIR + "/osmo");
|
||||
if (!fl.exists()) {
|
||||
fl.mkdirs();
|
||||
}
|
||||
File ps = new File(fl, name + ".gpx");
|
||||
String errors = "";
|
||||
boolean changed = false;
|
||||
if (!ps.exists() || (ps.lastModified() / 1000) != (timestamp / 1000)) {
|
||||
changed = true;
|
||||
GPXFile g;
|
||||
if (isGroupConnect) {
|
||||
g = new GPXFile();
|
||||
} else {
|
||||
g = GPXUtilities.loadGPXFile(app, ps);
|
||||
}
|
||||
for (WptPt point : params) {
|
||||
if (point.deleted) {
|
||||
for (WptPt pointInTrack : g.getPoints()) {
|
||||
if (pointInTrack.getExtensionsToRead().get("u").equals(
|
||||
point.getExtensionsToRead().get("u"))) {
|
||||
g.deleteWptPt(pointInTrack);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
g.addPoint(point);
|
||||
}
|
||||
}
|
||||
errors = GPXUtilities.writeGpxFile(ps, g, app);
|
||||
ps.setLastModified(timestamp);
|
||||
if (errors == null) {
|
||||
errors = "";
|
||||
}
|
||||
if (generateToast) {
|
||||
publishProgress(app.getString(R.string.osmo_gpx_points_downloaded, name));
|
||||
}
|
||||
}
|
||||
SelectedGpxFile byPath = app.getSelectedGpxHelper().getSelectedFileByPath(ps.getAbsolutePath());
|
||||
if (byPath == null || changed) {
|
||||
GPXFile selectGPXFile = GPXUtilities.loadGPXFile(app, ps);
|
||||
if (byPath != null) {
|
||||
app.getSelectedGpxHelper().selectGpxFile(selectGPXFile, false, false);
|
||||
}
|
||||
app.getSelectedGpxHelper().setGpxFileToDisplay(selectGPXFile);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
if (result.length() > 0 && generateToast) {
|
||||
app.showToastMessage(app.getString(R.string.osmo_io_error) + result);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public AsyncTask<JSONObject, String, String> getDownloadGpxTask(final boolean makeVisible) {
|
||||
|
||||
return new AsyncTask<JSONObject, String, String>() {
|
||||
|
||||
@Override
|
||||
protected String doInBackground(JSONObject... params) {
|
||||
final File fl = app.getAppPath(IndexConstants.GPX_INDEX_DIR + "/osmo");
|
||||
if (!fl.exists()) {
|
||||
fl.mkdirs();
|
||||
}
|
||||
String errors = "";
|
||||
for (JSONObject obj : params) {
|
||||
try {
|
||||
File f = new File(fl, obj.getString("name") + ".gpx");
|
||||
long timestamp = obj.getLong("created") * 1000;
|
||||
int color = 0;
|
||||
if (obj.has("color")) {
|
||||
try {
|
||||
color = Algorithms.parseColor(obj.getString("color"));
|
||||
} catch (RuntimeException e) {
|
||||
LOG.warn("", e);
|
||||
}
|
||||
}
|
||||
boolean visible = obj.has("visible");
|
||||
boolean changed = false;
|
||||
if (!f.exists() || (f.lastModified() != timestamp)) {
|
||||
long len = !f.exists() ? -1 : f.length();
|
||||
boolean sizeEqual = obj.has("size") && obj.getLong("size") == len;
|
||||
boolean modifySupported = f.setLastModified(timestamp - 1);
|
||||
if (!sizeEqual || modifySupported) {
|
||||
changed = true;
|
||||
String url = obj.getString("url");
|
||||
LOG.info("Download gpx " + url);
|
||||
DownloadFileHelper df = new DownloadFileHelper(app);
|
||||
InputStream is = df.getInputStreamToDownload(new URL(url), false);
|
||||
int av = is.available();
|
||||
if (av > 0 && !modifySupported && len == av) {
|
||||
// ignore
|
||||
is.close();
|
||||
} else {
|
||||
redownloadFile(f, timestamp, color, is);
|
||||
publishProgress(app.getString(R.string.osmo_gpx_track_downloaded, obj.getString("name")));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (visible && (changed || makeVisible)) {
|
||||
GPXFile selectGPXFile = GPXUtilities.loadGPXFile(app, f);
|
||||
if (color != 0) {
|
||||
selectGPXFile.setColor(color);
|
||||
}
|
||||
app.getSelectedGpxHelper().setGpxFileToDisplay(selectGPXFile);
|
||||
}
|
||||
} catch (JSONException | IOException e) {
|
||||
e.printStackTrace();
|
||||
errors += e.getMessage() + "\n";
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private void redownloadFile(File f, long timestamp, int color, InputStream is)
|
||||
throws IOException {
|
||||
FileOutputStream fout = new FileOutputStream(f);
|
||||
byte[] buf = new byte[1024];
|
||||
int k;
|
||||
while ((k = is.read(buf)) >= 0) {
|
||||
fout.write(buf, 0, k);
|
||||
}
|
||||
fout.close();
|
||||
is.close();
|
||||
if (!f.setLastModified(timestamp)) {
|
||||
LOG.error("Timestamp updates are not supported");
|
||||
}
|
||||
}
|
||||
|
||||
protected void onProgressUpdate(String... values) {
|
||||
if (values != null) {
|
||||
String t = "";
|
||||
for (String s : values) {
|
||||
t += s + "\n";
|
||||
}
|
||||
app.showToastMessage(t.trim());
|
||||
refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
if (result.length() > 0) {
|
||||
app.showToastMessage(app.getString(R.string.osmo_io_error) + result);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public void refreshMap() {
|
||||
if (mapActivity != null) {
|
||||
mapActivity.getMapView().refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptCommand(String command, String id, String data, JSONObject obj, OsMoThread tread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextSendCommand(OsMoThread tracker) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected() {
|
||||
if (groupsActivity instanceof OsMoGroupsActivity) {
|
||||
((OsMoGroupsActivity) groupsActivity).handleConnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(String msg) {
|
||||
if (groupsActivity instanceof OsMoGroupsActivity) {
|
||||
((OsMoGroupsActivity) groupsActivity).handleDisconnect(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean useHttps() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DashFragmentData getCardFragment() {
|
||||
return DashOsMoFragment.FRAGMENT_DATA;
|
||||
}
|
||||
}
|
|
@ -1,422 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Paint.Cap;
|
||||
import android.graphics.Paint.Join;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
import android.os.Handler;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.TargetPointsHelper;
|
||||
import net.osmand.plus.TargetPointsHelper.TargetPoint;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.osmo.OsMoGroups.OsMoGroupsUIListener;
|
||||
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoDevice;
|
||||
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoGroup;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.plus.views.ContextMenuLayer;
|
||||
import net.osmand.plus.views.OsmandMapLayer;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
/**
|
||||
* Class represents a layer for osmo positions
|
||||
*
|
||||
*/
|
||||
public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider, OsMoGroupsUIListener,
|
||||
ContextMenuLayer.IContextMenuProviderSelection{
|
||||
|
||||
private static int POINT_OUTER_COLOR = 0x88555555;
|
||||
private static int PAINT_TEXT_ICON_COLOR = Color.BLACK;
|
||||
|
||||
private DisplayMetrics dm;
|
||||
private final MapActivity map;
|
||||
private OsmandMapTileView view;
|
||||
private Paint pointInnerCircle;
|
||||
private Paint pointOuter;
|
||||
private OsMoPlugin plugin;
|
||||
private final static float startZoom = 7;
|
||||
private Handler uiHandler;
|
||||
private Paint paintPath;
|
||||
private Path pth;
|
||||
private Paint paintTextIcon;
|
||||
|
||||
public OsMoPositionLayer(MapActivity map, OsMoPlugin plugin) {
|
||||
this.map = map;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initLayer(OsmandMapTileView view) {
|
||||
this.view = view;
|
||||
uiHandler = new Handler();
|
||||
dm = new DisplayMetrics();
|
||||
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
|
||||
wmgr.getDefaultDisplay().getMetrics(dm);
|
||||
|
||||
pointInnerCircle = new Paint();
|
||||
pointInnerCircle.setColor(view.getApplication().getResources().getColor(R.color.poi_background));
|
||||
pointInnerCircle.setStyle(Style.FILL);
|
||||
pointInnerCircle.setAntiAlias(true);
|
||||
|
||||
paintPath = new Paint();
|
||||
paintPath.setStyle(Style.STROKE);
|
||||
paintPath.setStrokeWidth(14);
|
||||
paintPath.setAntiAlias(true);
|
||||
paintPath.setStrokeCap(Cap.ROUND);
|
||||
paintPath.setStrokeJoin(Join.ROUND);
|
||||
|
||||
paintTextIcon = new Paint();
|
||||
paintTextIcon.setTextSize(10 * view.getDensity());
|
||||
paintTextIcon.setTextAlign(Align.CENTER);
|
||||
paintTextIcon.setFakeBoldText(true);
|
||||
paintTextIcon.setColor(PAINT_TEXT_ICON_COLOR);
|
||||
paintTextIcon.setAntiAlias(true);
|
||||
|
||||
pth = new Path();
|
||||
|
||||
pointOuter = new Paint();
|
||||
pointOuter.setColor(POINT_OUTER_COLOR);
|
||||
pointOuter.setAntiAlias(true);
|
||||
pointOuter.setStyle(Style.FILL_AND_STROKE);
|
||||
}
|
||||
|
||||
public Collection<OsMoDevice> getTrackingDevices() {
|
||||
return plugin.getTracker().getTrackingDevices();
|
||||
}
|
||||
|
||||
public int getRadiusPoi(RotatedTileBox tb){
|
||||
int r = 0;
|
||||
final double zoom = tb.getZoom();
|
||||
if(zoom < startZoom){
|
||||
r = 0;
|
||||
} else if(zoom <= 11){
|
||||
r = 10;
|
||||
} else if(zoom <= 14){
|
||||
r = 12;
|
||||
} else {
|
||||
r = 14;
|
||||
}
|
||||
return (int) (r * tb.getDensity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings nightMode) {
|
||||
final int r = getRadiusPoi(tileBox);
|
||||
long treshold = System.currentTimeMillis() - 15000;
|
||||
for (OsMoDevice t : getTrackingDevices()) {
|
||||
Location l = t.getLastLocation();
|
||||
ConcurrentLinkedQueue<Location> plocations = t.getPreviousLocations(treshold);
|
||||
if (!plocations.isEmpty() && l != null) {
|
||||
int x = (int) tileBox.getPixXFromLonNoRot(l.getLongitude());
|
||||
int y = (int) tileBox.getPixYFromLatNoRot(l.getLatitude());
|
||||
pth.rewind();
|
||||
Iterator<Location> it = plocations.iterator();
|
||||
boolean f = true;
|
||||
while (it.hasNext()) {
|
||||
Location lo = it.next();
|
||||
int xt = (int) tileBox.getPixXFromLonNoRot(lo.getLongitude());
|
||||
int yt = (int) tileBox.getPixYFromLatNoRot(lo.getLatitude());
|
||||
if (f) {
|
||||
f = false;
|
||||
pth.moveTo(xt, yt);
|
||||
} else {
|
||||
pth.lineTo(xt, yt);
|
||||
}
|
||||
}
|
||||
pth.lineTo(x, y);
|
||||
paintPath.setColor(t.getColor());
|
||||
canvas.drawPath(pth, paintPath);
|
||||
}
|
||||
}
|
||||
canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
||||
for (OsMoDevice t : getTrackingDevices()) {
|
||||
Location l = t.getLastLocation();
|
||||
if (l != null) {
|
||||
int x = (int) tileBox.getPixXFromLatLon(l.getLatitude(), l.getLongitude());
|
||||
int y = (int) tileBox.getPixYFromLatLon(l.getLatitude(), l.getLongitude());
|
||||
pointInnerCircle.setColor(t.getColor());
|
||||
pointOuter.setColor(POINT_OUTER_COLOR);
|
||||
paintTextIcon.setColor(PAINT_TEXT_ICON_COLOR);
|
||||
Location lastLocation = t.getLastLocation();
|
||||
if (lastLocation != null) {
|
||||
long now = System.currentTimeMillis();
|
||||
boolean recent = Math.abs( now - lastLocation.getTime() ) < OsMoGroupsActivity.RECENT_THRESHOLD;
|
||||
if (!recent) {
|
||||
int color = t.getNonActiveColor();
|
||||
pointInnerCircle.setColor(color);
|
||||
pointOuter.setColor(Color.argb(Color.alpha(color),
|
||||
Color.red(POINT_OUTER_COLOR), Color.green(POINT_OUTER_COLOR),
|
||||
Color.blue(POINT_OUTER_COLOR)));
|
||||
paintTextIcon.setColor(Color.argb(Color.alpha(color),
|
||||
Color.red(PAINT_TEXT_ICON_COLOR), Color.green(PAINT_TEXT_ICON_COLOR),
|
||||
Color.blue(PAINT_TEXT_ICON_COLOR)));
|
||||
}
|
||||
} else {
|
||||
int color = t.getNonActiveColor();
|
||||
pointInnerCircle.setColor(color);
|
||||
pointOuter.setColor(Color.argb(Color.alpha(color),
|
||||
Color.red(POINT_OUTER_COLOR), Color.green(POINT_OUTER_COLOR),
|
||||
Color.blue(POINT_OUTER_COLOR)));
|
||||
paintTextIcon.setColor(Color.argb(Color.alpha(color),
|
||||
Color.red(PAINT_TEXT_ICON_COLOR), Color.green(PAINT_TEXT_ICON_COLOR),
|
||||
Color.blue(PAINT_TEXT_ICON_COLOR)));
|
||||
}
|
||||
canvas.drawCircle(x, y, r + (float)Math.ceil(tileBox.getDensity()), pointOuter);
|
||||
canvas.drawCircle(x, y, r - (float)Math.ceil(tileBox.getDensity()), pointInnerCircle);
|
||||
paintTextIcon.setTextSize(r * 3 / 2);
|
||||
canvas.drawText(t.getVisibleName().substring(0, 1).toUpperCase(), x, y + r / 2, paintTextIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyLayer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawInScreenPixels() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableSingleTap() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableLongPressOnMap() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObjectClickable(Object o) {
|
||||
return o instanceof OsMoDevice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runExclusiveAction(Object o, boolean unknownLocation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> o, boolean unknownLocation) {
|
||||
getOsmoFromPoint(tileBox, point, o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LatLon getObjectLocation(Object o) {
|
||||
if(o instanceof OsMoDevice) {
|
||||
Location loc = ((OsMoDevice) o).getLastLocation();
|
||||
if(loc != null) {
|
||||
return new LatLon(loc.getLatitude(), loc.getLongitude());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PointDescription getObjectName(Object o) {
|
||||
if(o instanceof OsMoDevice) {
|
||||
return new PointDescription(PointDescription.POINT_TYPE_MARKER, map.getString(R.string.osmo_user_name) + " " + ((OsMoDevice) o).getVisibleName());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
//String desc = getObjectDescription(o);
|
||||
//return desc == null ? null : new PointDescription(PointDescription.POINT_TYPE_MARKER, desc);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
if (view != null) {
|
||||
view.refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void getOsmoFromPoint(RotatedTileBox tb, PointF point, List<? super OsMoDevice> points) {
|
||||
if (view != null) {
|
||||
int ex = (int) point.x;
|
||||
int ey = (int) point.y;
|
||||
final int rp = getRadiusPoi(tb);
|
||||
int compare = rp;
|
||||
int radius = rp * 3 / 2;
|
||||
for (OsMoDevice d : getTrackingDevices()) {
|
||||
Location position = d.getLastLocation();
|
||||
if (position != null) {
|
||||
int x = (int) tb.getPixXFromLatLon(position.getLatitude(), position.getLongitude());
|
||||
int y = (int) tb.getPixYFromLatLon(position.getLatitude(), position.getLongitude());
|
||||
// the width of an image is 40 px, the height is 60 px -> radius = 20,
|
||||
// the position of a parking point relatively to the icon is at the center of the bottom line of the
|
||||
// image
|
||||
if (Math.abs(x - ex) <= compare && Math.abs(y - ey) <= compare) {
|
||||
compare = radius;
|
||||
points.add(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void groupsListChange(String operation, OsMoGroup group) {
|
||||
}
|
||||
|
||||
private volatile boolean schedule = false;
|
||||
// store between rotations
|
||||
private static String followTrackerId;
|
||||
private static LatLon followMapLocation;
|
||||
private static String followDestinationId;
|
||||
private static LatLon followTargetLocation;
|
||||
|
||||
public static void setFollowTrackerId(OsMoDevice d, Location l) {
|
||||
if(d != null) {
|
||||
followTrackerId = d.trackerId;
|
||||
if(l != null) {
|
||||
followMapLocation = new LatLon(l.getLatitude(), l.getLongitude());
|
||||
}
|
||||
} else {
|
||||
followTrackerId = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void setFollowDestination(OsMoDevice followDestination) {
|
||||
followDestinationId = followDestination == null ? null : followDestination.trackerId;
|
||||
}
|
||||
|
||||
public static String getFollowDestinationId() {
|
||||
return followDestinationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deviceLocationChanged(final OsMoDevice device) {
|
||||
boolean sameDestId = Algorithms.objectEquals(followDestinationId, device.trackerId);
|
||||
Location l = device.getLastLocation();
|
||||
if(sameDestId && l != null) {
|
||||
TargetPointsHelper targets = map.getMyApplication().getTargetPointsHelper();
|
||||
final TargetPoint pn = targets.getPointToNavigate();
|
||||
LatLon lt = new LatLon(l.getLatitude(), l.getLongitude());
|
||||
boolean cancelDestinationId = false;
|
||||
if(followTargetLocation != null ) {
|
||||
if(pn == null || pn.point == null || MapUtils.getDistance(pn.point, followTargetLocation) > 10) {
|
||||
cancelDestinationId = true;
|
||||
}
|
||||
}
|
||||
if(cancelDestinationId) {
|
||||
followTargetLocation = null;
|
||||
followDestinationId = null;
|
||||
} else {
|
||||
RoutingHelper rh = map.getMyApplication().getRoutingHelper();
|
||||
double dist = 1;
|
||||
if (rh.isRouteBeingCalculated()) {
|
||||
dist = 100;
|
||||
} else if (rh.isRouteCalculated()) {
|
||||
dist = 30;
|
||||
}
|
||||
if (pn == null || MapUtils.getDistance(pn.point, lt) > dist) {
|
||||
followTargetLocation = lt;
|
||||
targets.navigateToPoint(lt, true, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean sameId = Algorithms.objectEquals(followTrackerId, device.trackerId);
|
||||
if(sameId && !schedule && l != null) {
|
||||
ContextMenuLayer cl = map.getMapLayers().getContextMenuLayer();
|
||||
final boolean sameObject;
|
||||
if (map.getContextMenu().getObject() instanceof OsMoDevice && cl.isVisible()) {
|
||||
sameObject = Algorithms.objectEquals(device.trackerId,
|
||||
((OsMoDevice) map.getContextMenu().getObject()).trackerId);
|
||||
} else {
|
||||
sameObject = false;
|
||||
}
|
||||
LatLon mapLoc = new LatLon(map.getMapView().getLatitude(), map.getMapView().getLongitude());
|
||||
final boolean centered = followMapLocation != null && MapUtils.getDistance(mapLoc, followMapLocation) < 1;
|
||||
if(sameObject || centered) {
|
||||
final LatLon loc;
|
||||
if(centered ) {
|
||||
loc = new LatLon(l.getLatitude(), l.getLongitude());
|
||||
} else if(!map.getMapView().getAnimatedDraggingThread().isAnimating()) {
|
||||
// disable tracking
|
||||
loc = null;
|
||||
} else {
|
||||
loc = followMapLocation;
|
||||
}
|
||||
followMapLocation = loc;
|
||||
schedule = true;
|
||||
uiHandler.postDelayed(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
schedule = false;
|
||||
if (sameObject) {
|
||||
Location l = device.getLastLocation();
|
||||
if (centered) {
|
||||
map.getContextMenu().updateMapCenter(loc);
|
||||
}
|
||||
map.getContextMenu().update(new LatLon(l.getLatitude(), l.getLongitude()),
|
||||
getObjectName(device), device);
|
||||
}
|
||||
if (centered) {
|
||||
map.getMapView().setLatLon(loc.getLatitude(), loc.getLongitude());
|
||||
}
|
||||
map.getMapView().refreshMap();
|
||||
}
|
||||
|
||||
}, 150);
|
||||
} else {
|
||||
followTrackerId = null;
|
||||
}
|
||||
}
|
||||
uiHandler.postDelayed(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
map.getMapView().refreshMap();
|
||||
}
|
||||
|
||||
}, 350);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder(Object o) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedObject(Object o) {
|
||||
if(o instanceof OsMoDevice) {
|
||||
followTrackerId = ((OsMoDevice) o).getTrackerId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSelectedObject() {
|
||||
LatLon mapLoc = new LatLon(map.getMapView().getLatitude(), map.getMapView().getLongitude());
|
||||
final boolean centered = Algorithms.objectEquals(followMapLocation, mapLoc);
|
||||
if(!centered && followTrackerId != null) {
|
||||
followTrackerId = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
public interface OsMoReactor {
|
||||
|
||||
public boolean acceptCommand(String command, String id, String data, JSONObject obj, OsMoThread tread);
|
||||
|
||||
public String nextSendCommand(OsMoThread tracker);
|
||||
|
||||
public void onConnected();
|
||||
|
||||
public void onDisconnected(String msg);
|
||||
|
||||
}
|
|
@ -1,483 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.Version;
|
||||
import net.osmand.plus.notifications.OsmandNotification.NotificationType;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class OsMoService implements OsMoReactor {
|
||||
private static final String HTTP_API_PREPARE = "http://api.osmo.mobi/prepare";
|
||||
private static final String HTTPS_API_PREPARE = "https://api.osmo.mobi/prepare";
|
||||
private static final String HTTP_AUTH = "http://api.osmo.mobi/auth";
|
||||
private static final String HTTPS_AUTH = "https://api.osmo.mobi/auth";
|
||||
|
||||
public static final String REGENERATE_CMD = "TRACKER_REGENERATE_ID";
|
||||
public static final String SIGN_IN_URL = "http://osmo.mobi/signin?key=";
|
||||
private OsMoThread thread;
|
||||
private List<OsMoReactor> listReactors = new java.util.concurrent.CopyOnWriteArrayList<OsMoReactor>();
|
||||
private ConcurrentLinkedQueue<String> commands = new ConcurrentLinkedQueue<String>();
|
||||
private OsmandApplication app;
|
||||
private static final Log log = PlatformUtil.getLog(OsMoService.class);
|
||||
public static final String SHARE_TRACKER_URL = "http://z.osmo.mobi/connect?id=";
|
||||
public static final String SHARE_GROUP_URL = "http://z.osmo.mobi/join?id=";
|
||||
public static final String SIGNED_IN_CONTAINS = "z.osmo.mobi/login";
|
||||
public static final String TRACK_URL = "http://osmo.mobi/s/";
|
||||
private String lastRegistrationError = null;
|
||||
private OsMoPlugin plugin;
|
||||
private boolean enabled = false;
|
||||
private BroadcastReceiver broadcastReceiver;
|
||||
private Notification notification;
|
||||
|
||||
public final static String OSMO_REGISTER_AGAIN = "OSMO_REGISTER_AGAIN"; //$NON-NLS-1$
|
||||
private final static int SIMPLE_NOTFICATION_ID = 5;
|
||||
|
||||
private class HttpPostWriter {
|
||||
BufferedWriter writer;
|
||||
boolean first;
|
||||
|
||||
HttpPostWriter(OutputStream outputStream) {
|
||||
this.writer = new BufferedWriter(new OutputStreamWriter(outputStream));
|
||||
this.first = true;
|
||||
}
|
||||
|
||||
void addPair(String key, String value) throws IOException {
|
||||
if (this.first)
|
||||
this.first = false;
|
||||
else
|
||||
this.writer.write("&");
|
||||
|
||||
this.writer.write(URLEncoder.encode(key, "UTF-8"));
|
||||
this.writer.write("=");
|
||||
this.writer.write(URLEncoder.encode(value, "UTF-8"));
|
||||
}
|
||||
|
||||
void flush() throws IOException {
|
||||
this.writer.flush();
|
||||
this.writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public OsMoService(final OsmandApplication app, OsMoPlugin plugin) {
|
||||
this.app = app;
|
||||
this.plugin = plugin;
|
||||
listReactors.add(this);
|
||||
listReactors.add(plugin);
|
||||
broadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
notification = null;
|
||||
NotificationManager mNotificationManager = (NotificationManager) app
|
||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager.cancel(SIMPLE_NOTFICATION_ID);
|
||||
registerAsync();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
app.registerReceiver(broadcastReceiver, new IntentFilter(OSMO_REGISTER_AGAIN));
|
||||
}
|
||||
|
||||
private void registerAsync() {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
public Void doInBackground(Void... voids ) {
|
||||
try {
|
||||
registerOsmoDeviceKey();
|
||||
onConnected();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void)null);
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return thread != null && thread.isConnected();
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive() {
|
||||
return thread != null && thread.isActive();
|
||||
}
|
||||
|
||||
public long getLastCommandTime() {
|
||||
if(isConnected()) {
|
||||
return thread.getLastCommandTime();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public List<String> getHistoryOfCommands() {
|
||||
if(thread == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ArrayList<String>(thread.getLastCommands());
|
||||
}
|
||||
|
||||
|
||||
public long getConnectionTime() {
|
||||
return thread == null || !thread.isConnected() ? System.currentTimeMillis() : thread.getConnectionTime();
|
||||
}
|
||||
|
||||
protected List<OsMoReactor> getListReactors() {
|
||||
return listReactors;
|
||||
}
|
||||
|
||||
|
||||
public String getLastRegistrationError() {
|
||||
return lastRegistrationError;
|
||||
}
|
||||
|
||||
public boolean connect(boolean forceReconnect) {
|
||||
if(thread != null) {
|
||||
if(!forceReconnect ) {
|
||||
return isConnected();
|
||||
}
|
||||
thread.stopConnection();
|
||||
}
|
||||
thread = new OsMoThread(this);
|
||||
enabled = true;
|
||||
app.getNotificationHelper().refreshNotification(NotificationType.OSMO);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
if(thread != null) {
|
||||
enabled = false;
|
||||
thread.stopConnection();
|
||||
app.getSettings().OSMO_LAST_PING.set(0l);
|
||||
app.getNotificationHelper().refreshNotification(NotificationType.OSMO);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerReactor(OsMoReactor reactor) {
|
||||
if(!listReactors.contains(reactor)) {
|
||||
ArrayList<OsMoReactor> lst = new ArrayList<OsMoReactor>(listReactors);
|
||||
lst.add(reactor);
|
||||
listReactors = lst;
|
||||
}
|
||||
}
|
||||
|
||||
public void removeReactor(OsMoReactor s) {
|
||||
if(listReactors.contains(s)) {
|
||||
ArrayList<OsMoReactor> lst = new ArrayList<OsMoReactor>(listReactors);
|
||||
lst.remove(s);
|
||||
listReactors = lst;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String registerOsmoDeviceKey() throws IOException {
|
||||
URL url = new URL(plugin.useHttps()? HTTPS_AUTH : HTTP_AUTH);
|
||||
|
||||
try {
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setDoOutput(true);
|
||||
|
||||
// Add your data
|
||||
HttpPostWriter postWriter = new HttpPostWriter(conn.getOutputStream());
|
||||
postWriter.addPair("android_id", Secure.getString(app.getContentResolver(),
|
||||
Secure.ANDROID_ID));
|
||||
|
||||
postWriter.addPair("android_model", Build.MODEL);
|
||||
postWriter.addPair("imei", "0");
|
||||
postWriter.addPair("android_product", Build.PRODUCT);
|
||||
postWriter.addPair("client", Version.getFullVersion(app));
|
||||
postWriter.addPair("osmand", Version.getFullVersion(app));
|
||||
|
||||
// Execute HTTP Post Request
|
||||
postWriter.flush();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String r = reader.readLine();
|
||||
reader.close();
|
||||
conn.disconnect();
|
||||
log.info("Authorization key : " + r);
|
||||
final JSONObject obj = new JSONObject(r);
|
||||
if(obj.has("error")) {
|
||||
lastRegistrationError = obj.getString("error");
|
||||
throw new OsMoConnectionException(obj.getString("error"));
|
||||
}
|
||||
app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key"));
|
||||
return obj.getString("key");
|
||||
} catch (JSONException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SessionInfo {
|
||||
public String hostName;
|
||||
public String port;
|
||||
public String token;
|
||||
public String uid;
|
||||
public String username;
|
||||
|
||||
// after auth
|
||||
public String protocol = "";
|
||||
public String groupTrackerId;
|
||||
public String trackerId;
|
||||
public long serverTimeDelta;
|
||||
public long motdTimestamp;
|
||||
|
||||
public String motd = "";
|
||||
}
|
||||
|
||||
public SessionInfo getCurrentSessionInfo() {
|
||||
if(thread == null) {
|
||||
return null;
|
||||
}
|
||||
return thread.getSessionInfo();
|
||||
}
|
||||
|
||||
public String getRegisteredUserName() {
|
||||
SessionInfo si = getCurrentSessionInfo();
|
||||
if(si != null && si.username != null && si.username.length() > 0) {
|
||||
return si.username;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getMyGroupTrackerId() {
|
||||
String myGroupTrackerId = "";
|
||||
SessionInfo currentSessionInfo = getCurrentSessionInfo();
|
||||
if (currentSessionInfo != null) {
|
||||
myGroupTrackerId = currentSessionInfo.groupTrackerId;
|
||||
}
|
||||
return myGroupTrackerId;
|
||||
}
|
||||
|
||||
public String getMyTrackerId() {
|
||||
String myGroupTrackerId = "";
|
||||
SessionInfo currentSessionInfo = getCurrentSessionInfo();
|
||||
if (currentSessionInfo != null) {
|
||||
myGroupTrackerId = currentSessionInfo.trackerId;
|
||||
}
|
||||
return myGroupTrackerId;
|
||||
}
|
||||
|
||||
public SessionInfo prepareSessionToken() throws IOException {
|
||||
String deviceKey = app.getSettings().OSMO_DEVICE_KEY.get();
|
||||
if (deviceKey.length() == 0) {
|
||||
deviceKey = registerOsmoDeviceKey();
|
||||
}
|
||||
|
||||
URL url = new URL(plugin.useHttps() ? HTTPS_API_PREPARE : HTTP_API_PREPARE);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
try {
|
||||
conn.setDoOutput(true);
|
||||
HttpPostWriter postWriter = new HttpPostWriter(conn.getOutputStream());
|
||||
|
||||
// Add your data
|
||||
postWriter.addPair("app", Version.getFullVersion(app));
|
||||
postWriter.addPair("key", deviceKey);
|
||||
if (app.getSettings().OSMO_USER_PWD.get() != null) {
|
||||
postWriter.addPair("auth", app.getSettings().OSMO_USER_PWD.get());
|
||||
}
|
||||
postWriter.addPair("protocol", "1");
|
||||
|
||||
// Execute HTTP Post Request
|
||||
postWriter.flush();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String r = reader.readLine();
|
||||
reader.close();
|
||||
conn.disconnect();
|
||||
log.info("Authorization key : " + r);
|
||||
final JSONObject obj = new JSONObject(r);
|
||||
if (obj.has("error")) {
|
||||
lastRegistrationError = obj.getString("error");
|
||||
runNotification(lastRegistrationError);
|
||||
return null;
|
||||
}
|
||||
if (!obj.has("address")) {
|
||||
lastRegistrationError = "Host name not specified";
|
||||
throw new RuntimeException("Host name not specified");
|
||||
}
|
||||
if (!obj.has("token")) {
|
||||
lastRegistrationError = "Token not specified by server";
|
||||
throw new RuntimeException("Token not specified by server");
|
||||
}
|
||||
|
||||
SessionInfo si = new SessionInfo();
|
||||
String a = obj.getString("address");
|
||||
if (obj.has("name")) {
|
||||
si.username = obj.getString("name");
|
||||
}
|
||||
if (obj.has("uid")) {
|
||||
si.uid = obj.getString("uid");
|
||||
}
|
||||
int i = a.indexOf(':');
|
||||
si.hostName = a.substring(0, i);
|
||||
si.port = a.substring(i + 1);
|
||||
si.token = obj.getString("token");
|
||||
return si;
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (JSONException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void runNotification(final String error) {
|
||||
final Activity ga = plugin.getGroupsActivity();
|
||||
if(ga != null) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
showRegisterAgain(ga, app.getString(R.string.osmo_auth_error, error));
|
||||
|
||||
}
|
||||
});
|
||||
} else if (notification == null) {
|
||||
Intent notificationIntent = new Intent(OSMO_REGISTER_AGAIN);
|
||||
PendingIntent intent = PendingIntent.getBroadcast(app, 0, notificationIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
android.support.v4.app.NotificationCompat.Builder bld = new NotificationCompat.Builder(app);
|
||||
bld.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
bld.setContentInfo(app.getString(R.string.osmo_auth_error, error));
|
||||
bld.setContentIntent(intent);
|
||||
bld.setContentTitle(app.getString(R.string.osmo_auth_error_short));
|
||||
bld.setSmallIcon(R.drawable.bgs_icon);
|
||||
|
||||
NotificationManager mNotificationManager = (NotificationManager) app
|
||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notification = bld.getNotification();
|
||||
mNotificationManager.notify(SIMPLE_NOTFICATION_ID, notification);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void showRegisterAgain(Activity ga, String msg) {
|
||||
AlertDialog.Builder bld = new AlertDialog.Builder(ga);
|
||||
bld.setMessage(msg);
|
||||
bld.setPositiveButton(R.string.shared_string_ok, new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
registerAsync();
|
||||
}
|
||||
});
|
||||
bld.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void showErrorMessage(String string) {
|
||||
app.showToastMessage(app.getString(R.string.osmo_io_error) + string);
|
||||
}
|
||||
|
||||
|
||||
public void pushCommand(String cmd) {
|
||||
commands.add(cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextSendCommand(OsMoThread tracker) {
|
||||
if(System.currentTimeMillis() - app.getSettings().OSMO_LAST_PING.get() > 30000) {
|
||||
app.getSettings().OSMO_LAST_PING.set(System.currentTimeMillis());
|
||||
}
|
||||
if(!commands.isEmpty()) {
|
||||
return commands.poll();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptCommand(String command, String id, String data, JSONObject obj, OsMoThread tread) {
|
||||
if(command.equals("MOTD")) {
|
||||
SessionInfo si = getCurrentSessionInfo();
|
||||
if(si != null) {
|
||||
if(data.startsWith("[")){
|
||||
try {
|
||||
data = new JSONArray(data).getString(0);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
si.motd = data;
|
||||
}
|
||||
return true;
|
||||
} else if(command.equals("TRACK_GET")) {
|
||||
try {
|
||||
JSONArray ar = new JSONArray(data);
|
||||
AsyncTask<JSONObject, String, String> task = plugin.getDownloadGpxTask(false);
|
||||
JSONObject[] a = new JSONObject[ar.length()];
|
||||
for(int i = 0; i < a.length; i++) {
|
||||
a[i] = (JSONObject) ar.get(i);
|
||||
}
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, a);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
showErrorMessage(e.getMessage());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConnected() {
|
||||
pushCommand("TRACK_GET");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(String msg) {
|
||||
}
|
||||
|
||||
public void reconnectToServer() {
|
||||
if(thread != null) {
|
||||
thread.reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isLoggedIn() {
|
||||
String psswd = app.getSettings().OSMO_USER_PWD.get();
|
||||
String userName = app.getSettings().OSMO_USER_NAME.get();
|
||||
return ((!TextUtils.isEmpty(psswd) && !TextUtils.isEmpty(userName)));
|
||||
}
|
||||
|
||||
public OsmandApplication getMyApplication() {
|
||||
return app;
|
||||
}
|
||||
}
|
|
@ -1,488 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.osmo.OsMoService.SessionInfo;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
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 = 60 * 1000;
|
||||
private static final int SOCKET_TIMEOUT = 60 * 1000;
|
||||
private static final long TIMEOUT_TO_PING = 5 * 60 * 1000;
|
||||
private static final long LIMIT_OF_FAILURES_RECONNECT = 10;
|
||||
private static final long SELECT_TIMEOUT = 500;
|
||||
private static int HEARTBEAT_MSG = 3;
|
||||
private Handler serviceThread;
|
||||
|
||||
private int failures = 0;
|
||||
private int activeConnectionId = 0;
|
||||
private boolean stopThread;
|
||||
private boolean reconnect;
|
||||
private Selector selector;
|
||||
|
||||
private int authorized = 0; // 1 - send, 2 - authorized
|
||||
private OsMoService service;
|
||||
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);
|
||||
private LinkedList<String> queueOfMessages = new LinkedList<String>();
|
||||
|
||||
private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss", Locale.US);
|
||||
|
||||
private ConcurrentLinkedQueue<String> lastCommands = new ConcurrentLinkedQueue<String>();
|
||||
private final static int STACK_CMD = 30;
|
||||
|
||||
|
||||
|
||||
public OsMoThread(OsMoService service) {
|
||||
this.service = service;
|
||||
// start thread to receive events from OSMO
|
||||
HandlerThread h = new HandlerThread("OSMo Service");
|
||||
h.start();
|
||||
serviceThread = new Handler(h.getLooper());
|
||||
scheduleHeartbeat(HEARTBEAT_DELAY);
|
||||
}
|
||||
|
||||
public void stopConnection() {
|
||||
stopThread = true;
|
||||
}
|
||||
|
||||
protected void initConnection() throws IOException {
|
||||
// always ask session token
|
||||
// if (sessionInfo == null) {
|
||||
sessionInfo = service.prepareSessionToken();
|
||||
// }
|
||||
if(sessionInfo == null) {
|
||||
return;
|
||||
}
|
||||
this.activeChannel = null;
|
||||
authorized = 0;
|
||||
reconnect = false;
|
||||
pingSent = 0;
|
||||
failures = 0;
|
||||
lastSendCommand = 0;
|
||||
selector = Selector.open();
|
||||
SocketChannel activeChannel = SocketChannel.open();
|
||||
activeChannel.configureBlocking(true);
|
||||
activeChannel.connect(new InetSocketAddress(sessionInfo.hostName, Integer.parseInt(sessionInfo.port)));
|
||||
activeChannel.configureBlocking(false);
|
||||
activeChannel.socket().setSoTimeout(SOCKET_TIMEOUT);
|
||||
SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
|
||||
connectionTime = System.currentTimeMillis();
|
||||
if (this.activeChannel != null) {
|
||||
stopChannel();
|
||||
}
|
||||
this.activeChannel = activeChannel;
|
||||
key.attach(new Integer(++activeConnectionId));
|
||||
for(OsMoReactor sender : getReactors()) {
|
||||
sender.onConnected();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Collection<OsMoReactor> getReactors() {
|
||||
return service.getListReactors();
|
||||
}
|
||||
|
||||
public String format(String cmd, Map<String, Object> params) {
|
||||
JSONObject json;
|
||||
try {
|
||||
json = new JSONObject();
|
||||
Iterator<Entry<String, Object>> it = params.entrySet().iterator();
|
||||
while(it.hasNext()) {
|
||||
Entry<String, Object> e = it.next();
|
||||
json.put(e.getKey(), e.getValue());
|
||||
}
|
||||
return cmd + "|"+json.toString();
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void scheduleHeartbeat(long delay) {
|
||||
Message msg = serviceThread.obtainMessage();
|
||||
msg.what = HEARTBEAT_MSG;
|
||||
serviceThread.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
checkAsyncSocket();
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return activeChannel != null;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return activeChannel != null && pingSent == 0 && authorized == 2;
|
||||
}
|
||||
|
||||
protected void checkAsyncSocket() {
|
||||
long delay = HEARTBEAT_DELAY;
|
||||
try {
|
||||
// if (selector == null) {
|
||||
// stopThread = true;
|
||||
if(activeChannel == null || reconnect) {
|
||||
initConnection();
|
||||
if(activeChannel == null) {
|
||||
delay = HEARTBEAT_FAILED_DELAY;
|
||||
}
|
||||
} else {
|
||||
checkSelectedKeys();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.info("Exception selecting socket", e);
|
||||
exc("ERROR HEARTBEAT : ", e);
|
||||
e.printStackTrace();
|
||||
if (activeChannel != null && !activeChannel.isConnected()) {
|
||||
activeChannel = null;
|
||||
}
|
||||
final String msg = e.getMessage();
|
||||
for(OsMoReactor sender : getReactors()) {
|
||||
sender.onDisconnected(msg);
|
||||
}
|
||||
delay = HEARTBEAT_FAILED_DELAY;
|
||||
if (e instanceof OsMoConnectionException) {
|
||||
stopThread = true;
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(service.getMyApplication(), msg, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (lastSendCommand != 0 && System.currentTimeMillis() - lastSendCommand > TIMEOUT_TO_RECONNECT) {
|
||||
reconnect = true;
|
||||
} else if (failures++ > LIMIT_OF_FAILURES_RECONNECT) {
|
||||
reconnect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stopThread) {
|
||||
stopChannel();
|
||||
for(OsMoReactor sender : getReactors()) {
|
||||
sender.onDisconnected(null);
|
||||
}
|
||||
serviceThread.getLooper().quit();
|
||||
} else {
|
||||
scheduleHeartbeat(delay);
|
||||
}
|
||||
}
|
||||
|
||||
protected void exc(String header, Exception e) {
|
||||
String eMsg = e.getMessage();
|
||||
if(e.getStackTrace() != null && e.getStackTrace().length > 0) {
|
||||
eMsg += " " + e.getStackTrace()[0].toString();
|
||||
}
|
||||
cmd(header + eMsg, true);
|
||||
}
|
||||
|
||||
private void stopChannel() {
|
||||
if (activeChannel != null) {
|
||||
try {
|
||||
activeChannel.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
activeChannel = null;
|
||||
}
|
||||
|
||||
private void checkSelectedKeys() throws IOException {
|
||||
/* int s = */selector.select(SELECT_TIMEOUT);
|
||||
Set<SelectionKey> keys = selector.selectedKeys();
|
||||
if (keys == null) {
|
||||
return;
|
||||
}
|
||||
Iterator<SelectionKey> iterator = keys.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
SelectionKey key = iterator.next();
|
||||
final boolean isActive = new Integer(activeConnectionId).equals(key.attachment());
|
||||
// final boolean isActive = activeChannel == key.channel();
|
||||
if (isActive) {
|
||||
if (key.isWritable()) {
|
||||
writeCommands();
|
||||
}
|
||||
if (key.isReadable()) {
|
||||
readCommands();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
key.channel().close();
|
||||
} catch (Exception e) {
|
||||
log.info("Exception closing channel", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private void readCommands() throws IOException {
|
||||
boolean hasSomethingToRead = true;
|
||||
while (hasSomethingToRead) {
|
||||
pendingReadCommand.clear();
|
||||
int read = activeChannel.read(pendingReadCommand);
|
||||
if (!pendingReadCommand.hasRemaining()) {
|
||||
hasSomethingToRead = true;
|
||||
} else {
|
||||
hasSomethingToRead = false;
|
||||
}
|
||||
if(read == -1) {
|
||||
reconnect = true;
|
||||
} else if (read > 0) {
|
||||
byte[] ar = pendingReadCommand.array();
|
||||
String res = new String(ar, 0, read);
|
||||
readCommand += res;
|
||||
int i;
|
||||
while ((i = readCommand.indexOf('\n')) != -1) {
|
||||
String cmd = readCommand.substring(0, i);
|
||||
readCommand = readCommand.substring(i + 1);
|
||||
queueOfMessages.add(cmd.replace("\\n", "\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (queueOfMessages.size() > 0) {
|
||||
processReadMessages();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void processReadMessages() {
|
||||
while(!queueOfMessages.isEmpty()){
|
||||
String cmd = queueOfMessages.poll();
|
||||
cmd(cmd, false);
|
||||
int k = cmd.indexOf('|');
|
||||
String header = cmd;
|
||||
String id = "";
|
||||
String data = "";
|
||||
if(k >= 0) {
|
||||
header = cmd.substring(0, k);
|
||||
data = cmd.substring(k + 1);
|
||||
}
|
||||
int ks = header.indexOf(':');
|
||||
if (ks >= 0) {
|
||||
id = header.substring(ks + 1);
|
||||
header = header.substring(0, ks);
|
||||
}
|
||||
JSONObject obj = null;
|
||||
if(data.startsWith("{")) {
|
||||
try {
|
||||
obj = new JSONObject(data);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
boolean error = false;
|
||||
if(obj != null && obj.has("error")) {
|
||||
error = true;
|
||||
try {
|
||||
String s = obj.getString("error");
|
||||
if(obj.has("error_description")) {
|
||||
s += " " +obj.getString("error_description");
|
||||
}
|
||||
service.showErrorMessage(s);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(header.equalsIgnoreCase("TOKEN")) {
|
||||
if(!error){
|
||||
authorized = 2;
|
||||
try {
|
||||
parseAuthCommand(data, obj);
|
||||
} catch (JSONException e) {
|
||||
service.showErrorMessage(e.getMessage());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else if(header.equalsIgnoreCase(OsMoService.REGENERATE_CMD)) {
|
||||
reconnect = true;
|
||||
continue;
|
||||
} else if(header.equalsIgnoreCase(PING_CMD)) {
|
||||
pingSent = 0;
|
||||
continue;
|
||||
// lastSendCommand = System.currentTimeMillis(); // not needed handled by send
|
||||
}
|
||||
boolean processed = false;
|
||||
for (OsMoReactor o : getReactors()) {
|
||||
try {
|
||||
if (o.acceptCommand(header, id, data, obj, this)) {
|
||||
processed = true;
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {e.printStackTrace();
|
||||
exc("ERROR REACTOR:", e);
|
||||
}
|
||||
}
|
||||
if (!processed) {
|
||||
log.warn("Command not processed '" + cmd + "'");
|
||||
}
|
||||
}
|
||||
lastSendCommand = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void parseAuthCommand(String data, JSONObject obj) throws JSONException {
|
||||
if(sessionInfo != null) {
|
||||
if(obj.has("protocol")) {
|
||||
sessionInfo.protocol = obj.getString("protocol");
|
||||
}
|
||||
if(obj.has("now")) {
|
||||
sessionInfo.serverTimeDelta = obj.getLong("now") - System.currentTimeMillis();
|
||||
}
|
||||
if(obj.has("name")) {
|
||||
sessionInfo.username = obj.getString("name");
|
||||
}
|
||||
if (obj.has("motd")) {
|
||||
long l = obj.getLong("motd");
|
||||
if(l != sessionInfo.motdTimestamp ){
|
||||
sessionInfo.motdTimestamp = l;
|
||||
service.pushCommand("MOTD");
|
||||
}
|
||||
}
|
||||
if(obj.has("tracker_id")) {
|
||||
sessionInfo.trackerId= obj.getString("tracker_id");
|
||||
}
|
||||
if(obj.has("group_tracker_id")) {
|
||||
sessionInfo.groupTrackerId= obj.getString("group_tracker_id");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getConnectionTime() {
|
||||
return connectionTime;
|
||||
}
|
||||
|
||||
private void writeCommands() throws UnsupportedEncodingException, IOException {
|
||||
if(authorized == 0) {
|
||||
String auth = "TOKEN|"+ sessionInfo.token;
|
||||
cmd(auth, true);
|
||||
authorized = 1;
|
||||
pendingSendCommand = ByteBuffer.wrap(prepareCommand(auth).toString().getBytes("UTF-8"));
|
||||
}
|
||||
if (pendingSendCommand == null) {
|
||||
pendingSendCommand = getNewPendingSendCommand();
|
||||
}
|
||||
while (pendingSendCommand != null) {
|
||||
activeChannel.write(pendingSendCommand);
|
||||
if (!pendingSendCommand.hasRemaining()) {
|
||||
lastSendCommand = System.currentTimeMillis();
|
||||
pendingSendCommand = getNewPendingSendCommand();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ByteBuffer getNewPendingSendCommand() throws UnsupportedEncodingException {
|
||||
if(authorized == 1) {
|
||||
return null;
|
||||
}
|
||||
for (OsMoReactor s : getReactors()) {
|
||||
String l = null;
|
||||
try {
|
||||
l = s.nextSendCommand(this);
|
||||
} catch (Exception e) {
|
||||
exc("ERROR SENDER:", e);
|
||||
}
|
||||
if (l != null) {
|
||||
cmd(l, true);
|
||||
return ByteBuffer.wrap(prepareCommand(l).toString().getBytes("UTF-8"));
|
||||
}
|
||||
|
||||
}
|
||||
final long interval = System.currentTimeMillis() - lastSendCommand;
|
||||
if(interval > TIMEOUT_TO_PING) {
|
||||
final long pingInterval = System.currentTimeMillis() - pingSent;
|
||||
if(pingSent == 0 || pingInterval > TIMEOUT_TO_PING) {
|
||||
pingSent = System.currentTimeMillis();
|
||||
cmd(PING_CMD, true);
|
||||
return ByteBuffer.wrap(prepareCommand(PING_CMD).toString().getBytes("UTF-8"));
|
||||
}
|
||||
} else if(pingSent != 0) {
|
||||
pingSent = 0;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ConcurrentLinkedQueue<String> getLastCommands() {
|
||||
return lastCommands;
|
||||
}
|
||||
|
||||
private void cmd(String cmd, boolean send) {
|
||||
log.info("OsMO" + (send ? "> " : ">> ") + cmd);
|
||||
lastCommands.add((send ? "> " : ">> ") + df.format(new Date()) + " " + cmd);
|
||||
while(lastCommands.size() > STACK_CMD) {
|
||||
lastCommands.poll();
|
||||
}
|
||||
}
|
||||
|
||||
public SessionInfo getSessionInfo() {
|
||||
return sessionInfo;
|
||||
}
|
||||
|
||||
private String prepareCommand(String l) {
|
||||
StringBuilder res = new StringBuilder(l.length());
|
||||
for (int i = 0; i < l.length(); i++) {
|
||||
char c = l.charAt(i);
|
||||
if (c == '\n' || c == '=' || c == '\\') {
|
||||
res.append('\\');
|
||||
}
|
||||
res.append(c);
|
||||
}
|
||||
|
||||
String finalCmd = res.toString().trim();
|
||||
return finalCmd + "=\n";
|
||||
}
|
||||
|
||||
public long getLastCommandTime() {
|
||||
return lastSendCommand;
|
||||
}
|
||||
|
||||
public void reconnect() {
|
||||
sessionInfo = null;
|
||||
reconnect = true;
|
||||
}
|
||||
}
|
|
@ -1,264 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandSettings.OsmandPreference;
|
||||
import net.osmand.plus.notifications.OsmandNotification;
|
||||
import net.osmand.plus.notifications.OsmandNotification.NotificationType;
|
||||
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoDevice;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.FieldPosition;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class OsMoTracker implements OsMoReactor {
|
||||
// 130.5143667 Maximum is 8 digits and minimum 1
|
||||
private static final DecimalFormat floatingPointFormat = new DecimalFormat("0.0#######");
|
||||
private static final DecimalFormat twoDigitsFormat = new DecimalFormat("0.0#");
|
||||
private static final DecimalFormat integerFormat = new DecimalFormat("0");
|
||||
static {
|
||||
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.ENGLISH);
|
||||
floatingPointFormat.setDecimalFormatSymbols(symbols);
|
||||
twoDigitsFormat.setDecimalFormatSymbols(symbols);
|
||||
integerFormat.setDecimalFormatSymbols(symbols);
|
||||
}
|
||||
|
||||
private ConcurrentLinkedQueue<Location> bufferOfLocations = new ConcurrentLinkedQueue<>();
|
||||
private OsMoService service;
|
||||
private int locationsSent = 0;
|
||||
private OsmoTrackerListener trackerListener = null;
|
||||
private Location lastSendLocation;
|
||||
private Location lastBufferLocation;
|
||||
private OsmandPreference<Integer> pref;
|
||||
private String sessionURL;
|
||||
private Map<String, OsMoDevice> trackingDevices = new java.util.concurrent.ConcurrentHashMap<>();
|
||||
private OsmandPreference<Boolean> stateSendLocation;
|
||||
protected static final Log LOG = PlatformUtil.getLog(OsMoTracker.class);
|
||||
|
||||
public interface OsmoTrackerListener {
|
||||
void locationChange(String trackerId, Location location);
|
||||
}
|
||||
|
||||
public OsMoTracker(OsMoService service, OsmandPreference<Integer> interval,
|
||||
OsmandPreference<Boolean> stateSendLocation) {
|
||||
this.service = service;
|
||||
this.pref = interval;
|
||||
this.stateSendLocation = stateSendLocation;
|
||||
service.registerReactor(this);
|
||||
}
|
||||
|
||||
public String getSessionURL() {
|
||||
if (!isEnabledTracker() || sessionURL == null) {
|
||||
return null;
|
||||
}
|
||||
return OsMoService.TRACK_URL + sessionURL;
|
||||
}
|
||||
|
||||
public boolean isEnabledTracker() {
|
||||
return stateSendLocation.get();
|
||||
}
|
||||
|
||||
public void enableTracker() {
|
||||
if (!isEnabledTracker()) {
|
||||
enableTrackerCmd();
|
||||
service.getMyApplication().getNotificationHelper().refreshNotification(NotificationType.OSMO);
|
||||
}
|
||||
}
|
||||
|
||||
public void enableTrackerCmd() {
|
||||
stateSendLocation.set(true);
|
||||
service.pushCommand("TRACKER_SESSION_OPEN");
|
||||
}
|
||||
|
||||
public void disableTracker() {
|
||||
if (isEnabledTracker()) {
|
||||
stateSendLocation.set(false);
|
||||
service.pushCommand("TRACKER_SESSION_CLOSE");
|
||||
}
|
||||
service.getMyApplication().getNotificationHelper().refreshNotification(NotificationType.OSMO);
|
||||
}
|
||||
|
||||
public void startTrackingId(OsMoDevice d) {
|
||||
service.pushCommand("LISTEN:" + d.getTrackerId());
|
||||
trackingDevices.put(d.getTrackerId(), d);
|
||||
}
|
||||
|
||||
public void stopTrackingId(OsMoDevice d) {
|
||||
service.pushCommand("UNLISTEN:" + d.getTrackerId());
|
||||
trackingDevices.remove(d.getTrackerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextSendCommand(OsMoThread thread) {
|
||||
if (!bufferOfLocations.isEmpty()) {
|
||||
Location loc = bufferOfLocations.poll();
|
||||
lastSendLocation = loc;
|
||||
locationsSent++;
|
||||
if ((System.currentTimeMillis() - loc.getTime()) > 2 * 60000 && loc.getTime() != 0) {
|
||||
return "B|" + formatLocation(loc);
|
||||
} else {
|
||||
return "T|" + formatLocation(loc);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String formatLocation(Location loc) {
|
||||
StringBuffer cmd = new StringBuffer();
|
||||
cmd.append("L");
|
||||
floatingPointFormat.format(loc.getLatitude(), cmd, new FieldPosition(cmd.length()));
|
||||
cmd.append(":");
|
||||
floatingPointFormat.format(loc.getLongitude(), cmd, new FieldPosition(cmd.length()));
|
||||
if (loc.hasAccuracy()) {
|
||||
cmd.append("H");
|
||||
integerFormat.format(loc.getAccuracy(), cmd, new FieldPosition(cmd.length()));
|
||||
}
|
||||
if (loc.hasAltitude()) {
|
||||
cmd.append("A");
|
||||
integerFormat.format(loc.getAltitude(), cmd, new FieldPosition(cmd.length()));
|
||||
}
|
||||
if (loc.hasSpeed() && (int) (loc.getSpeed() * 100) != 0) {
|
||||
cmd.append("S");
|
||||
twoDigitsFormat.format(loc.getSpeed(), cmd, new FieldPosition(cmd.length()));
|
||||
}
|
||||
if (loc.hasBearing()) {
|
||||
cmd.append("C");
|
||||
integerFormat.format(loc.getBearing(), cmd, new FieldPosition(cmd.length()));
|
||||
}
|
||||
if (loc.getTime() != 0) {
|
||||
cmd.append("T");
|
||||
integerFormat.format(loc.getTime(), cmd, new FieldPosition(cmd.length()));
|
||||
}
|
||||
LOG.debug("formatLocation cmd=" + cmd);
|
||||
return cmd.toString();
|
||||
}
|
||||
|
||||
public Location getLastSendLocation() {
|
||||
return lastSendLocation;
|
||||
}
|
||||
|
||||
public void sendCoordinate(Location location) {
|
||||
if (stateSendLocation.get() && location != null) {
|
||||
long ltime = lastBufferLocation == null ? 0 : lastBufferLocation.getTime();
|
||||
|
||||
if (location.getTime() - ltime > pref.get()) {
|
||||
if (lastBufferLocation != null && (!lastBufferLocation.hasSpeed() || lastBufferLocation.getSpeed() < 1) &&
|
||||
lastBufferLocation.distanceTo(location) < 20) {
|
||||
if (lastBufferLocation != null && location.getTime() - ltime < 60000) {
|
||||
// ignores
|
||||
return;
|
||||
}
|
||||
}
|
||||
lastBufferLocation = location;
|
||||
bufferOfLocations.add(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getLocationsSent() {
|
||||
return locationsSent;
|
||||
}
|
||||
|
||||
public int getBufferLocationsSize() {
|
||||
return bufferOfLocations.size();
|
||||
}
|
||||
|
||||
public void sendCoordinate(double lat, double lon) {
|
||||
Location l = new Location("test");
|
||||
l.setTime(System.currentTimeMillis());
|
||||
l.setLatitude(lat);
|
||||
l.setLongitude(lon);
|
||||
sendCoordinate(l);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean acceptCommand(String command, String tid, String data, JSONObject obj, OsMoThread thread) {
|
||||
switch (command) {
|
||||
case "LISTEN":
|
||||
return true;
|
||||
case "UNLISTEN":
|
||||
return true;
|
||||
case "TRACKER_SESSION_CLOSE":
|
||||
return true;
|
||||
case "TRACKER_SESSION_OPEN":
|
||||
try {
|
||||
sessionURL = obj.getString("url");
|
||||
} catch (JSONException e) {
|
||||
service.showErrorMessage(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
case "LT":
|
||||
double lat = 0;
|
||||
double lon = 0;
|
||||
double speed = 0;
|
||||
int k = 0;
|
||||
for (int i = 1; i <= data.length(); i++) {
|
||||
boolean separator = i == data.length() ||
|
||||
!(Character.isDigit(data.charAt(i)) ||
|
||||
data.charAt(i) == ':' || data.charAt(i) == '.' || data.charAt(i) == '-');
|
||||
if (separator) {
|
||||
char ch = data.charAt(k);
|
||||
String vl = data.substring(k + 1, i);
|
||||
if (ch == 'L') {
|
||||
int l = vl.indexOf(":");
|
||||
lat = Double.parseDouble(vl.substring(0, l));
|
||||
lon = Double.parseDouble(vl.substring(l + 1));
|
||||
} else if (ch == 'S') {
|
||||
speed = Double.parseDouble(vl);
|
||||
}
|
||||
k = i;
|
||||
}
|
||||
}
|
||||
if (lat != 0 || lon != 0) {
|
||||
Location loc = new Location("osmo");
|
||||
loc.setTime(System.currentTimeMillis());
|
||||
loc.setLatitude(lat);
|
||||
loc.setLongitude(lon);
|
||||
if (speed > 0) {
|
||||
loc.setSpeed((float) speed);
|
||||
}
|
||||
if (trackerListener != null) {
|
||||
trackerListener.locationChange(tid, loc);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setTrackerListener(OsmoTrackerListener trackerListener) {
|
||||
this.trackerListener = trackerListener;
|
||||
}
|
||||
|
||||
public OsmoTrackerListener getTrackerListener() {
|
||||
return trackerListener;
|
||||
}
|
||||
|
||||
|
||||
public Collection<OsMoDevice> getTrackingDevices() {
|
||||
return trackingDevices.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected() {
|
||||
if (stateSendLocation.get()) {
|
||||
enableTrackerCmd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(String msg) {
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
public class Protocol {
|
||||
public static class CreateGroupData {
|
||||
public final String name;
|
||||
public final boolean onlyByInvite;
|
||||
public final String description;
|
||||
public final String policy;
|
||||
|
||||
public CreateGroupData(String name, boolean onlyByInvite, String description, String policy) {
|
||||
this.name = name;
|
||||
this.onlyByInvite = onlyByInvite;
|
||||
this.description = description;
|
||||
this.policy = policy;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.SettingsBaseActivity;
|
||||
import net.osmand.plus.activities.actions.ShareDialog;
|
||||
import net.osmand.plus.osmo.OsMoService.SessionInfo;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SettingsOsMoActivity extends SettingsBaseActivity {
|
||||
|
||||
private Preference debugPref;
|
||||
private Preference trackerId;
|
||||
// private CheckBoxPreference sendLocationsref;
|
||||
|
||||
public static final int[] SECONDS = new int[] {0, 1, 2, 3, 5, 10, 15, 30, 60, 90};
|
||||
public static final int[] MINUTES = new int[] {2, 3, 5};
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
((OsmandApplication) getApplication()).applyTheme(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
getToolbar().setTitle(R.string.osmo_settings);
|
||||
PreferenceScreen grp = getPreferenceScreen();
|
||||
|
||||
|
||||
|
||||
trackerId = new Preference(this);
|
||||
trackerId.setTitle(R.string.osmo_tracker_id);
|
||||
trackerId.setSummary(R.string.osmo_tracker_id_descr);
|
||||
trackerId.setOnPreferenceClickListener(this);
|
||||
grp.addPreference(trackerId);
|
||||
|
||||
CheckBoxPreference autoConnectref = createCheckBoxPreference(settings.OSMO_AUTO_CONNECT);
|
||||
autoConnectref.setTitle(R.string.osmo_auto_connect);
|
||||
autoConnectref.setSummary(R.string.osmo_auto_connect_descr);
|
||||
grp.addPreference(autoConnectref);
|
||||
|
||||
// sendLocationsref = createCheckBoxPreference(settings.OSMO_AUTO_SEND_LOCATIONS);
|
||||
// sendLocationsref.setTitle(R.string.osmo_auto_send_locations);
|
||||
// sendLocationsref.setSummary(R.string.osmo_auto_send_locations_descr);
|
||||
// sendLocationsref.setEnabled(settings.OSMO_AUTO_CONNECT.get());
|
||||
// grp.addPreference(sendLocationsref);
|
||||
|
||||
grp.addPreference(createTimeListPreference(settings.OSMO_SAVE_TRACK_INTERVAL, SECONDS,
|
||||
MINUTES, 1000, R.string.osmo_track_interval, R.string.osmo_track_interval_descr));
|
||||
|
||||
CheckBoxPreference showGroupNotifiations = createCheckBoxPreference(settings.OSMO_SHOW_GROUP_NOTIFICATIONS);
|
||||
showGroupNotifiations.setTitle(R.string.osmo_show_group_notifications);
|
||||
showGroupNotifiations.setSummary(R.string.osmo_show_group_notifications_descr);
|
||||
grp.addPreference(showGroupNotifiations);
|
||||
|
||||
// if (OsmandPlugin.isDevelopment()) {
|
||||
debugPref = new Preference(this);
|
||||
debugPref.setTitle(R.string.osmo_settings_debug);
|
||||
debugPref.setOnPreferenceClickListener(this);
|
||||
updateDebugPref();
|
||||
grp.addPreference(debugPref);
|
||||
// }
|
||||
}
|
||||
|
||||
private void updateDebugPref() {
|
||||
final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class);
|
||||
assert plugin != null;
|
||||
OsMoService service = plugin.getService();
|
||||
OsMoTracker tracker = plugin.getTracker();
|
||||
StringBuilder s = new StringBuilder();
|
||||
if(service.isConnected()) {
|
||||
int seconds = (int) ((System.currentTimeMillis() - service.getConnectionTime()) / 1000);
|
||||
s.append(getString(R.string.osmo_conn_successfull, Algorithms.formatDuration(seconds, getMyApplication().accessibilityEnabled()))).append("\n");
|
||||
SessionInfo si = service.getCurrentSessionInfo();
|
||||
if(si == null) {
|
||||
s.append(getString(R.string.osmo_auth_pending)).append("\n");
|
||||
} else {
|
||||
s.append(getString(R.string.osmo_session_token, si.token)).append("\n");
|
||||
}
|
||||
} else {
|
||||
String err = service.getLastRegistrationError();
|
||||
if(err == null) {
|
||||
err = "...";
|
||||
}
|
||||
s.append(getString(R.string.osmo_io_error)).append(err).append("\n");
|
||||
}
|
||||
s.append(getString(R.string.osmo_locations_sent,
|
||||
tracker.getLocationsSent(),
|
||||
tracker.getBufferLocationsSize())).append("\n");
|
||||
s.append(getString(R.string.osmo_settings_uuid)).append(" : ")
|
||||
.append(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()).append("\n");
|
||||
debugPref.setSummary(s.toString().trim());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class);
|
||||
assert plugin != null;
|
||||
if (preference == debugPref) {
|
||||
updateDebugPref();
|
||||
AlertDialog.Builder bld = new AlertDialog.Builder(this);
|
||||
StringBuilder bs = new StringBuilder();
|
||||
List<String> hs = plugin.getService().getHistoryOfCommands();
|
||||
if(hs != null) {
|
||||
for(int i = hs.size() - 1 ; i >= 0; i--) {
|
||||
bs.append(hs.get(i)).append("\n");
|
||||
}
|
||||
}
|
||||
ScrollView sv = new ScrollView(this);
|
||||
TextView tv = new TextView(this);
|
||||
sv.addView(tv);
|
||||
final String log = bs.toString();
|
||||
tv.setText(log);
|
||||
tv.setPadding(5, 0, 5, 5);
|
||||
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 19);
|
||||
tv.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
bld.setView(sv);
|
||||
bld.setNegativeButton(R.string.shared_string_ok, null);
|
||||
bld.setPositiveButton(R.string.shared_string_share, new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_fav_subject));
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, log);
|
||||
sendIntent.setType("text/plain");
|
||||
startActivity(sendIntent);
|
||||
}
|
||||
});
|
||||
bld.show();
|
||||
return true;
|
||||
} else if(preference == trackerId) {
|
||||
OsMoService service = plugin.getService();
|
||||
SessionInfo ci = service.getCurrentSessionInfo();
|
||||
if(ci == null || ci.trackerId == null) {
|
||||
Toast.makeText(this, R.string.osmo_auth_pending, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
ShareDialog dlg = new ShareDialog(this);
|
||||
dlg.setTitle(getString(R.string.osmo_tracker_id));
|
||||
dlg.viewContent(ci.trackerId);
|
||||
String url = OsMoService.SHARE_TRACKER_URL+Uri.encode(ci.trackerId);
|
||||
dlg.shareURLOrText(ci.trackerId, getString(R.string.osmo_tracker_id_share, ci.trackerId, "", url), null);
|
||||
dlg.showDialog();
|
||||
}
|
||||
}
|
||||
return super.onPreferenceClick(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean p = super.onPreferenceChange(preference, newValue);
|
||||
String id = preference.getKey();
|
||||
if (id.equals(settings.OSMO_AUTO_CONNECT.getId())) {
|
||||
if ((Boolean) newValue) {
|
||||
final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class);
|
||||
assert plugin != null;
|
||||
plugin.getService().connect(false);
|
||||
}
|
||||
// sendLocationsref.setEnabled(settings.OSMO_AUTO_CONNECT.get());
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
public void updateAllSettings() {
|
||||
super.updateAllSettings();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
|||
|
||||
import net.osmand.NativeLibrary;
|
||||
import net.osmand.NativeLibrary.NativeSearchResult;
|
||||
import net.osmand.RenderingContext.ShadowRenderingMode;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.binary.BinaryMapDataObject;
|
||||
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
||||
|
@ -786,7 +787,7 @@ public class OsmandRenderer {
|
|||
p.setShader(getShader(resId));
|
||||
}
|
||||
// do not check shadow color here
|
||||
if(rc.shadowRenderingMode == 1) {
|
||||
if(rc.shadowRenderingMode == ShadowRenderingMode.ONE_STEP.value) {
|
||||
int shadowColor = req.getIntPropertyValue(req.ALL.R_SHADOW_COLOR);
|
||||
if(shadowColor == 0) {
|
||||
shadowColor = rc.shadowRenderingColor;
|
||||
|
@ -852,7 +853,7 @@ public class OsmandRenderer {
|
|||
|
||||
private void drawPolylineShadow(Canvas canvas, RenderingContext rc, Path path, int shadowColor, int shadowRadius) {
|
||||
// blurred shadows
|
||||
if (rc.shadowRenderingMode == 2 && shadowRadius > 0) {
|
||||
if (rc.shadowRenderingMode == ShadowRenderingMode.BLUR_SHADOW.value && shadowRadius > 0) {
|
||||
// simply draw shadow? difference from option 3 ?
|
||||
// paint.setColor(shadowRadius);
|
||||
// paint.setColor(0xffffffff);
|
||||
|
@ -861,7 +862,7 @@ public class OsmandRenderer {
|
|||
}
|
||||
|
||||
// option shadow = 3 with solid border
|
||||
if (rc.shadowRenderingMode == 3 && shadowRadius > 0) {
|
||||
if (rc.shadowRenderingMode == ShadowRenderingMode.SOLID_SHADOW.value && shadowRadius > 0) {
|
||||
paint.clearShadowLayer();
|
||||
paint.setStrokeWidth(paint.getStrokeWidth() + shadowRadius * 2);
|
||||
ColorFilter cf = new PorterDuffColorFilter(shadowColor, Mode.SRC_IN);
|
||||
|
|
Loading…
Reference in a new issue