stations) {
109 | //search for widgets with same city ID
110 | int widgetCityID = getWidgetCityID(context);
111 |
112 | int[] widgetIDs = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, Widget.class));
113 |
114 | for (int widgetID : widgetIDs) {
115 | //check if city ID is same
116 | if (cityID == widgetCityID) {
117 | //perform update for the widget
118 |
119 | RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
120 | AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
121 |
122 | CityToWatch city = dbHelper.getCityToWatch(cityID);
123 |
124 | Widget.updateView(context, appWidgetManager, views, widgetID, city, stations);
125 | appWidgetManager.updateAppWidget(widgetID, views);
126 | }
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/database/City.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.database;
2 |
3 |
4 | /**
5 | * Created by yonjuni on 04.01.17.
6 | * data object for city
7 | *
8 | * Structure taken from the old orm package from previous versions of this app.
9 | */
10 |
11 | public class City {
12 |
13 | private int cityId;
14 | private String cityName;
15 | private String countryCode;
16 | private float lon;
17 | private float lat;
18 |
19 | public City() {
20 | }
21 |
22 | public int getCityId() {
23 | return cityId;
24 | }
25 |
26 | public void setCityId(int cityId) {
27 | this.cityId = cityId;
28 | }
29 |
30 | public String getCityName() {
31 | return cityName;
32 | }
33 |
34 | public void setCityName(String cityName) {
35 | this.cityName = cityName;
36 | }
37 |
38 | public String getCountryCode() {
39 | return countryCode;
40 | }
41 |
42 | public void setCountryCode(String countryCode) {
43 | this.countryCode = countryCode;
44 | }
45 |
46 | public void setLatitude(float latitude) {
47 | lat = latitude;
48 | }
49 |
50 | public float getLatitude() {
51 | return lat;
52 | }
53 |
54 | public float getLongitude() {
55 | return lon;
56 | }
57 |
58 | public void setLongitude(float lon) {
59 | this.lon = lon;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/database/CityToWatch.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.database;
2 |
3 | /**
4 | * This class is the database model for the cities to watch. 'Cities to watch' means the locations
5 | * for which a user would like to see the gas prices.
6 | */
7 | public class CityToWatch {
8 |
9 | private int id;
10 | private int cityId;
11 | private String cityName;
12 | private float lon;
13 | private float lat;
14 | private int rank;
15 |
16 | public CityToWatch() {
17 | }
18 |
19 | public CityToWatch(int rank, int id, int cityId, float lon, float lat, String cityName) {
20 | this.rank = rank;
21 | this.lon = lon;
22 | this.lat = lat;
23 | this.id = id;
24 | this.cityId = cityId;
25 | this.cityName = cityName;
26 | }
27 |
28 | public int getId() {
29 | return id;
30 | }
31 |
32 | public void setId(int id) {
33 | this.id = id;
34 | }
35 |
36 | public int getCityId() {
37 | return cityId;
38 | }
39 |
40 | public void setCityId(int cityId) {
41 | this.cityId = cityId;
42 | }
43 |
44 | public String getCityName() {
45 | return cityName;
46 | }
47 |
48 | public void setCityName(String cityName) {
49 | this.cityName = cityName;
50 | }
51 |
52 | public int getRank() {
53 | return rank;
54 | }
55 |
56 | public void setRank(int rank) {
57 | this.rank = rank;
58 | }
59 |
60 | public void setLongitude(float lon) { this.lon = lon; }
61 |
62 | public float getLongitude() { return lon; }
63 |
64 | public float getLatitude() { return lat; }
65 |
66 | public void setLatitude(float lat) { this.lat = lat; }
67 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/database/Station.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.database;
2 |
3 | /**
4 | * This class is the database model for the stations.
5 | */
6 | public class Station {
7 |
8 | private int id;
9 | private int city_id;
10 | private long timestamp;
11 | private double diesel;
12 | private double e5;
13 | private double e10;
14 | private boolean isOpen;
15 | private String brand;
16 | private String name;
17 | private String address1;
18 | private String address2;
19 | private double distance;
20 | private double latitude;
21 | private double longitude;
22 | private String uuid;
23 |
24 |
25 | public Station() {
26 | }
27 |
28 | public Station(int id, int city_id, long timestamp, double diesel, double e5, double e10, boolean isOpen, String brand, String name, String address1, String address2, double distance, double latitude, double longitude, String uuid) {
29 | this.id = id;
30 | this.city_id = city_id;
31 | this.timestamp = timestamp;
32 | this.diesel = diesel;
33 | this.e5 = e5;
34 | this.e10 = e10;
35 | this.isOpen = isOpen;
36 | this.brand = brand;
37 | this.name = name;
38 | this.address1 = address1;
39 | this.address2 = address2;
40 | this.distance = distance;
41 | this.latitude = latitude;
42 | this.longitude = longitude;
43 | this.uuid = uuid;
44 | }
45 |
46 | public int getId() {
47 | return id;
48 | }
49 |
50 | public void setId(int id) {
51 | this.id = id;
52 | }
53 |
54 | public int getCity_id() {
55 | return city_id;
56 | }
57 |
58 | public void setCity_id(int city_id) {
59 | this.city_id = city_id;
60 | }
61 |
62 | public long getTimestamp() {
63 | return timestamp;
64 | }
65 |
66 | public void setTimestamp(long timestamp) {
67 | this.timestamp = timestamp;
68 | }
69 |
70 | public double getDiesel() {
71 | return diesel;
72 | }
73 |
74 | public void setDiesel(double diesel) {
75 | this.diesel = diesel;
76 | }
77 |
78 | public double getE5() {
79 | return e5;
80 | }
81 |
82 | public void setE5(double e5) {
83 | this.e5 = e5;
84 | }
85 |
86 | public double getE10() {
87 | return e10;
88 | }
89 |
90 | public void setE10(double e10) {
91 | this.e10 = e10;
92 | }
93 |
94 | public boolean isOpen() {
95 | return isOpen;
96 | }
97 |
98 | public void setOpen(boolean open) {
99 | isOpen = open;
100 | }
101 |
102 | public String getBrand() {
103 | return brand;
104 | }
105 |
106 | public void setBrand(String brand) {
107 | this.brand = brand;
108 | }
109 |
110 | public String getName() {
111 | return name;
112 | }
113 |
114 | public void setName(String name) {
115 | this.name = name;
116 | }
117 |
118 | public String getAddress1() {
119 | return address1;
120 | }
121 |
122 | public void setAddress1(String address1) {
123 | this.address1 = address1;
124 | }
125 |
126 | public String getAddress2() {
127 | return address2;
128 | }
129 |
130 | public void setAddress2(String address2) {
131 | this.address2 = address2;
132 | }
133 |
134 | public double getDistance() {
135 | return distance;
136 | }
137 |
138 | public void setDistance(double distance) {
139 | this.distance = distance;
140 | }
141 |
142 | public double getLatitude() {
143 | return latitude;
144 | }
145 |
146 | public void setLatitude(double latitude) {
147 | this.latitude = latitude;
148 | }
149 |
150 | public double getLongitude() {
151 | return longitude;
152 | }
153 |
154 | public void setLongitude(double longitude) {
155 | this.longitude = longitude;
156 | }
157 |
158 | public String getUuid() {
159 | return uuid;
160 | }
161 |
162 | public void setUuid(String uuid) {
163 | this.uuid = uuid;
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/http/HttpRequestType.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.http;
2 |
3 | /**
4 | * A list of all the possible HTTP request types (there are more, for sure, but for this project
5 | * the four below are definitely sufficient).
6 | */
7 | public enum HttpRequestType {
8 | POST,
9 | GET,
10 | PUT,
11 | DELETE
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/http/IHttpRequest.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.http;
2 |
3 | import org.woheller69.spritpreise.api.IProcessHttpRequest;
4 |
5 | /**
6 | * This interface defines the template for making HTTP request. Furthermore, it provides a generic
7 | * way for handling the responses.
8 | */
9 | public interface IHttpRequest {
10 |
11 | /**
12 | * Makes an HTTP request and processes the response.
13 | *
14 | * @param URL The target of the HTTP request.
15 | * @param method Which method to use for the HTTP request (e.g. GET or POST)
16 | * @param requestProcessor This object with its implemented methods processSuccessScenario and
17 | * processFailScenario defines how to handle the response in the success
18 | * and error case respectively.
19 | */
20 | void make(final String URL, HttpRequestType method, IProcessHttpRequest requestProcessor);
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/http/VolleyHttpRequest.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.http;
2 |
3 | import android.content.Context;
4 | import com.android.volley.AuthFailureError;
5 | import com.android.volley.Request;
6 | import com.android.volley.RequestQueue;
7 | import com.android.volley.Response;
8 | import com.android.volley.VolleyError;
9 | import com.android.volley.toolbox.StringRequest;
10 | import com.android.volley.toolbox.Volley;
11 |
12 | import org.woheller69.spritpreise.BuildConfig;
13 | import org.woheller69.spritpreise.api.IProcessHttpRequest;
14 |
15 | import java.util.HashMap;
16 | import java.util.Map;
17 |
18 |
19 | /**
20 | * This class implements the IHttpRequest interface. It provides HTTP requests by using Volley.
21 | * See: https://developer.android.com/training/volley/simple.html
22 | */
23 | public class VolleyHttpRequest implements IHttpRequest {
24 |
25 | private Context context;
26 | private int cityId;
27 |
28 | /**
29 | * Constructor.
30 | *
31 | * @param context Volley needs a context "for creating the cache dir".
32 | * @see Volley#newRequestQueue(Context)
33 | */
34 | public VolleyHttpRequest(Context context, int cityId) {
35 | this.context = context;
36 | this.cityId = cityId;
37 | }
38 |
39 | /**
40 | * @see IHttpRequest#make(String, HttpRequestType, IProcessHttpRequest)
41 | */
42 | @Override
43 | public void make(String URL, HttpRequestType method, final IProcessHttpRequest requestProcessor) {
44 | RequestQueue queue = Volley.newRequestQueue(context);
45 |
46 | // Set the request method
47 | int requestMethod;
48 | switch (method) {
49 | case POST:
50 | requestMethod = Request.Method.POST;
51 | break;
52 | case GET:
53 | requestMethod = Request.Method.GET;
54 | break;
55 | case PUT:
56 | requestMethod = Request.Method.PUT;
57 | break;
58 | case DELETE:
59 | requestMethod = Request.Method.DELETE;
60 | break;
61 | default:
62 | requestMethod = Request.Method.GET;
63 | }
64 |
65 | // Execute the request and handle the response
66 | StringRequest stringRequest = new StringRequest(requestMethod, URL,
67 | new Response.Listener() {
68 | @Override
69 | public void onResponse(String response) {
70 | requestProcessor.processSuccessScenario(response, cityId);
71 | }
72 | },
73 | new Response.ErrorListener() {
74 | @Override
75 | public void onErrorResponse(VolleyError error) {
76 | requestProcessor.processFailScenario(error);
77 | }
78 | }
79 | ) {
80 | @Override
81 | public Map getHeaders() { //from https://stackoverflow.com/questions/17049473/how-to-set-custom-header-in-volley-request
82 | Map params = new HashMap();
83 | params.put("User-Agent", BuildConfig.APPLICATION_ID + "/" + BuildConfig.VERSION_NAME);
84 | return params;
85 | }
86 | };
87 | queue.add(stringRequest);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/preferences/AppPreferencesManager.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.preferences;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.os.Handler;
6 | import android.os.Looper;
7 | import android.widget.Toast;
8 |
9 | import org.woheller69.spritpreise.BuildConfig;
10 | import org.woheller69.spritpreise.R;
11 | import static org.woheller69.preferences.Utils.getKey;
12 | import androidx.preference.PreferenceManager;
13 |
14 | /**
15 | * This class provides access and methods for relevant preferences.
16 | */
17 | public class AppPreferencesManager {
18 |
19 |
20 | /**
21 | * Member variables
22 | */
23 | SharedPreferences preferences;
24 |
25 | /**
26 | * Constructor.
27 | *
28 | * @param preferences Source for the preferences to use.
29 | */
30 | public AppPreferencesManager(SharedPreferences preferences) {
31 | this.preferences = preferences;
32 | }
33 |
34 | public boolean isFirstTimeLaunch(Context context) {
35 | boolean result = preferences.getInt("versionCode",0)==0; //true if versionCode not yet initialized
36 | if (isApiKeyMissing()) return true; //show Tutorial at every launch until API key is set
37 | else return result;
38 | }
39 |
40 | public boolean isApiKeyMissing() {
41 | return (preferences.getString("API_key_value", "").equals("") && BuildConfig.DEFAULT_API_KEY.equals(BuildConfig.UNPATCHED_API_KEY));
42 | }
43 |
44 |
45 | public String getTKApiKey(Context context){
46 | String prefValue = preferences.getString("API_key_value", "");
47 | if (prefValue.length()==36) return prefValue; // if a valid key has been entered use it
48 | else if (BuildConfig.DEFAULT_API_KEY.equals(BuildConfig.UNPATCHED_API_KEY)){ // no key entered and build config not patched when compiling
49 | new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, context.getResources().getString(R.string.settings_title_API_key), Toast.LENGTH_LONG).show());
50 | return "";
51 | } else {
52 | return getKey(BuildConfig.DEFAULT_API_KEY);
53 | }
54 | }
55 |
56 | public boolean showStarDialog(Context context) {
57 | int versionCode = preferences.getInt("versionCode",BuildConfig.VERSION_CODE);
58 | boolean askForStar=preferences.getBoolean("askForStar",true);
59 |
60 | if (!isFirstTimeLaunch(context) && BuildConfig.VERSION_CODE>versionCode && askForStar){ //not at first start, only after upgrade and only if use has not yet given a star or has declined
61 | SharedPreferences.Editor editor = preferences.edit();
62 | editor.putInt("versionCode", BuildConfig.VERSION_CODE);
63 | editor.apply();
64 | return true;
65 | } else {
66 | SharedPreferences.Editor editor = preferences.edit();
67 | editor.putInt("versionCode", BuildConfig.VERSION_CODE);
68 | editor.apply();
69 | return false;
70 | }
71 | }
72 |
73 | public void setAskForStar(boolean askForStar){
74 | SharedPreferences.Editor editor = preferences.edit();
75 | editor.putBoolean("askForStar", askForStar);
76 | editor.apply();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/services/UpdateDataService.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.services;
2 |
3 | import android.content.Intent;
4 | import android.content.SharedPreferences;
5 | import android.os.Handler;
6 | import androidx.preference.PreferenceManager;
7 | import androidx.core.app.JobIntentService;
8 | import android.widget.Toast;
9 |
10 | import org.woheller69.spritpreise.BuildConfig;
11 | import org.woheller69.spritpreise.R;
12 | import org.woheller69.spritpreise.activities.NavigationActivity;
13 | import org.woheller69.spritpreise.database.CityToWatch;
14 | import org.woheller69.spritpreise.database.Station;
15 | import org.woheller69.spritpreise.database.SQLiteHelper;
16 | import org.woheller69.spritpreise.api.IHttpRequestForStations;
17 | import org.woheller69.spritpreise.api.tankerkoenig.TKHttpRequestForStations;
18 |
19 | import java.io.IOException;
20 | import java.net.InetAddress;
21 | import java.net.URL;
22 | import java.util.List;
23 | import java.util.concurrent.ExecutionException;
24 | import java.util.concurrent.Executors;
25 | import java.util.concurrent.Future;
26 | import java.util.concurrent.TimeUnit;
27 | import java.util.concurrent.TimeoutException;
28 |
29 | /**
30 | * This class provides the functionality to fetch price data for a given city as a background
31 | * task.
32 | */
33 |
34 | public class UpdateDataService extends JobIntentService {
35 |
36 | public static final String UPDATE_SINGLE_ACTION = "org.woheller69.spritpreise.services.UpdateDataService.UPDATE_SINGLE_ACTION";
37 | public static final String SKIP_UPDATE_INTERVAL = "skipUpdateInterval";
38 | private static final long MIN_UPDATE_INTERVAL=20;
39 |
40 | private SQLiteHelper dbHelper;
41 | private SharedPreferences prefManager;
42 |
43 | /**
44 | * Constructor.
45 | */
46 | public UpdateDataService() {
47 | super();
48 | }
49 |
50 | @Override
51 | public void onCreate() {
52 | super.onCreate();
53 | dbHelper = SQLiteHelper.getInstance(getApplicationContext());
54 | prefManager = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
55 | }
56 |
57 | @Override
58 | protected void onHandleWork(Intent intent) {
59 | if (!isOnline(2000)) {
60 | Handler h = new Handler(getApplicationContext().getMainLooper());
61 | h.post(new Runnable() {
62 | @Override
63 | public void run() {
64 | if (NavigationActivity.isVisible) Toast.makeText(getApplicationContext(), getResources().getString(R.string.error_no_internet), Toast.LENGTH_LONG).show();
65 | }
66 | });
67 | return;
68 | }
69 |
70 | if (intent != null) {
71 | if (UPDATE_SINGLE_ACTION.equals(intent.getAction())) handleUpdateSingle(intent);
72 | }
73 | }
74 |
75 |
76 |
77 | private void handleUpdateSingle(Intent intent) {
78 | int cityId = intent.getIntExtra("cityId",-1);
79 | CityToWatch city = dbHelper.getCityToWatch(cityId);
80 | handleUpdateStationsAction(intent, cityId, city.getLatitude(), city.getLongitude());
81 | }
82 |
83 | private void handleUpdateStationsAction(Intent intent, int cityId, float lat, float lon) {
84 | boolean skipUpdateInterval = intent.getBooleanExtra(SKIP_UPDATE_INTERVAL, false);
85 |
86 | long timestamp = 0;
87 | long systemTime = System.currentTimeMillis() / 1000;
88 | long updateInterval = (long) (Float.parseFloat(prefManager.getString("pref_updateInterval", "15")) * 60);
89 |
90 | List stations = dbHelper.getStationsByCityId(cityId);
91 | if (stations.size() > 0) { // check timestamp of stations
92 | timestamp = stations.get(0).getTimestamp();
93 | }
94 |
95 | if (skipUpdateInterval) {
96 | // check timestamp of the current stations
97 | if ((timestamp+MIN_UPDATE_INTERVAL-systemTime)>0) skipUpdateInterval=false; //even if skipUpdateInterval is true, never update if less than MIN_UPDATE_INTERVAL s
98 | }
99 |
100 | // Update if update forced or if a certain time has passed
101 | if (skipUpdateInterval || timestamp + updateInterval - systemTime <= 0) {
102 |
103 |
104 | IHttpRequestForStations stationsRequest = new TKHttpRequestForStations(getApplicationContext());
105 | stationsRequest.perform(lat, lon, cityId);
106 |
107 | }
108 | }
109 |
110 | private boolean isOnline(int timeOut) { //https://stackoverflow.com/questions/9570237/android-check-internet-connection
111 | InetAddress inetAddress = null;
112 | try {
113 | Future future = Executors.newSingleThreadExecutor().submit(() -> {
114 | try {
115 | URL url = new URL(BuildConfig.BASE_URL);
116 | return InetAddress.getByName(url.getHost());
117 | } catch ( IOException e) {
118 | return null;
119 | }
120 | });
121 | inetAddress = future.get(timeOut, TimeUnit.MILLISECONDS);
122 | future.cancel(true);
123 | } catch (InterruptedException | ExecutionException | TimeoutException e) {
124 | }
125 | return inetAddress!=null && !inetAddress.toString().isEmpty();
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/CityFragment.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui;
2 |
3 | import static org.woheller69.spritpreise.ui.RecycleList.CityAdapter.DETAILS;
4 | import static org.woheller69.spritpreise.ui.RecycleList.CityAdapter.OVERVIEW;
5 | import static org.woheller69.spritpreise.ui.RecycleList.CityAdapter.STATIONS;
6 |
7 | import android.annotation.SuppressLint;
8 | import android.content.Context;
9 | import android.os.Bundle;
10 |
11 | import androidx.annotation.NonNull;
12 | import androidx.annotation.Nullable;
13 | import androidx.fragment.app.Fragment;
14 | import androidx.recyclerview.widget.LinearLayoutManager;
15 | import androidx.recyclerview.widget.RecyclerView;
16 |
17 | import android.view.LayoutInflater;
18 |
19 | import android.view.View;
20 | import android.view.ViewGroup;
21 |
22 | import org.woheller69.spritpreise.R;
23 | import org.woheller69.spritpreise.activities.CityGasPricesActivity;
24 | import org.woheller69.spritpreise.database.Station;
25 | import org.woheller69.spritpreise.ui.RecycleList.CityAdapter;
26 | import org.woheller69.spritpreise.ui.RecycleList.OnSwipeDownListener;
27 | import org.woheller69.spritpreise.ui.updater.IUpdateableCityUI;
28 | import org.woheller69.spritpreise.ui.updater.ViewUpdater;
29 | import org.woheller69.spritpreise.ui.viewPager.CityPagerAdapter;
30 |
31 | import java.util.List;
32 |
33 | //Fragment with the viewholders for a location
34 | public class CityFragment extends Fragment implements IUpdateableCityUI {
35 |
36 | private int mCityId = -1;
37 | private static final int[] mDataSetTypes = {STATIONS}; //Before: {OVERVIEW, DETAILS, STATIONS} OVERVIEW and DETAILS unused at the moment.
38 |
39 | private CityAdapter mAdapter;
40 |
41 | private RecyclerView recyclerView;
42 |
43 | public static CityFragment newInstance(Bundle args)
44 | {
45 | CityFragment cityFragment = new CityFragment();
46 | cityFragment.setArguments(args);
47 | return cityFragment;
48 | }
49 |
50 | public void setAdapter(CityAdapter adapter) {
51 | mAdapter = adapter;
52 |
53 | if (recyclerView != null) {
54 | recyclerView.setAdapter(mAdapter);
55 | recyclerView.setFocusable(false);
56 | }
57 | }
58 |
59 | public void loadData() {
60 |
61 | mAdapter = new CityAdapter(mCityId, mDataSetTypes, getContext());
62 | setAdapter(mAdapter);
63 | }
64 |
65 |
66 | @Override
67 | public void onResume() {
68 | loadData();
69 | super.onResume();
70 | }
71 |
72 | @Override
73 | public void onAttach(@NonNull Context context) {
74 | super.onAttach(context);
75 |
76 | ViewUpdater.addSubscriber(this);
77 | }
78 |
79 | @Override
80 | public void onDetach() {
81 | ViewUpdater.removeSubscriber(this);
82 |
83 | super.onDetach();
84 | }
85 |
86 | @Override
87 | public void onPause() {
88 | mAdapter.removeMyPositionListenerGPS();
89 | super.onPause();
90 | }
91 |
92 | @SuppressLint("ClickableViewAccessibility")
93 | @Override
94 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
95 | final View v = inflater.inflate(R.layout.city_fragment, container, false);
96 |
97 | recyclerView = v.findViewById(R.id.CityRecyclerView);
98 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext()){
99 | public boolean canScrollVertically() { //Make parent recyclerview not scrollable (not needed in this app) and scroll stations instead
100 | return false;
101 | }
102 | });
103 |
104 |
105 | Bundle args = getArguments();
106 | mCityId = args.getInt("city_id");
107 |
108 | return v;
109 | }
110 |
111 | @Override
112 | public void processUpdateStations(List stations, int cityID) {
113 |
114 | if (mAdapter != null && mCityId==cityID) {
115 | mAdapter.updateStationsData(stations);
116 | }
117 | }
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/Help/StringFormatUtils.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.Help;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.text.SpannableString;
6 | import android.text.Spanned;
7 | import android.text.style.ForegroundColorSpan;
8 | import android.text.style.SuperscriptSpan;
9 | import android.text.style.TextAppearanceSpan;
10 |
11 | import androidx.preference.PreferenceManager;
12 | import java.math.RoundingMode;
13 | import java.text.DateFormat;
14 | import java.text.DecimalFormat;
15 | import java.text.SimpleDateFormat;
16 | import java.util.Locale;
17 | import java.util.TimeZone;
18 |
19 | import static java.lang.Boolean.TRUE;
20 |
21 | import org.woheller69.spritpreise.R;
22 |
23 | public final class StringFormatUtils {
24 |
25 | private static final DecimalFormat decimalFormat = new DecimalFormat("0.0");
26 | private static final DecimalFormat intFormat = new DecimalFormat("0");
27 |
28 | public static SpannableString formatPrice(Context context, String prefix, Double price, String suffix){
29 | DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH);
30 | format.applyPattern("0.000");
31 | String pricestring = format.format(price);
32 | SpannableString priceformat = new SpannableString(prefix + pricestring + suffix);
33 | priceformat.setSpan(new TextAppearanceSpan(context, android.R.style.TextAppearance_Small), priceformat.length()-3, priceformat.length()-2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
34 | priceformat.setSpan(new SuperscriptSpan(), priceformat.length()-3, priceformat.length()-2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
35 | priceformat.setSpan(new ForegroundColorSpan(context.getColor(R.color.colorPrimaryDark)), 0, priceformat.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
36 | return priceformat;
37 | }
38 |
39 | public static String formatDecimal(float decimal) {
40 | decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
41 | return removeMinusIfZerosOnly(decimalFormat.format(decimal));
42 | }
43 |
44 | public static String formatInt(float decimal) {
45 | intFormat.setRoundingMode(RoundingMode.HALF_UP);
46 | return removeMinusIfZerosOnly(intFormat.format(decimal));
47 | }
48 |
49 | public static String formatInt(float decimal, String appendix) {
50 | return String.format("%s\u200a%s", removeMinusIfZerosOnly(formatInt(decimal)), appendix); //\u200a adds tiny space
51 | }
52 |
53 | public static String formatDecimal(float decimal, String appendix) {
54 | return String.format("%s\u200a%s", removeMinusIfZerosOnly(formatDecimal(decimal)), appendix);
55 | }
56 |
57 | public static String formatTimeWithoutZone(Context context, long time) {
58 | SharedPreferences sharedPreferences= PreferenceManager.getDefaultSharedPreferences(context);
59 | SimpleDateFormat tf;
60 | java.text.DateFormat df = java.text.DateFormat.getDateInstance(DateFormat.SHORT);
61 | df.setTimeZone(TimeZone.getTimeZone("GMT"));
62 | if (android.text.format.DateFormat.is24HourFormat(context) || sharedPreferences.getBoolean("pref_TimeFormat", true)==TRUE){
63 | tf = new SimpleDateFormat("HH:mm", Locale.getDefault());
64 | tf.setTimeZone(TimeZone.getTimeZone("GMT"));
65 | }else {
66 | tf = new SimpleDateFormat("hh:mm aa", Locale.getDefault());
67 | tf.setTimeZone(TimeZone.getTimeZone("GMT"));
68 | }
69 | return df.format(time)+" "+tf.format(time);
70 | }
71 |
72 |
73 |
74 | public static String removeMinusIfZerosOnly(String string){
75 | // It removes (replaces with "") the minus sign if it's followed by 0-n characters of "0.00000...",
76 | // so this will work for any similar result such as "-0", "-0." or "-0.000000000"
77 | // https://newbedev.com/negative-sign-in-case-of-zero-in-java
78 | return string.replaceAll("^-(?=0(\\.0*)?$)", "");
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/RecycleList/ItemTouchHelperAdapter.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.RecycleList;
2 |
3 | /**
4 | * This interface defines the functionality that can be bound to touch events.
5 | * For the most part it has been taken from
6 | * https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.hmhbe8sku
7 | * as of 2016-08-03
8 | */
9 | public interface ItemTouchHelperAdapter {
10 |
11 | /**
12 | * This method removes an item from an adapter at the specified positin.
13 | *
14 | * @param position The position of the item to remove.
15 | */
16 | void onItemDismiss(int position);
17 |
18 | /**
19 | * This method is required to remove items from the list that is used to display the data
20 | * whenever an item is deleted by swiping.
21 | *
22 | * @param fromPosition The from position.
23 | * @param toPosition The to position.
24 | */
25 | void onItemMove(int fromPosition, int toPosition);
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/RecycleList/ItemViewHolder.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.RecycleList;
2 |
3 | import androidx.recyclerview.widget.RecyclerView;
4 | import android.view.View;
5 | import android.widget.TextView;
6 |
7 | import org.woheller69.spritpreise.R;
8 |
9 | /**
10 | * This class holds instances of items that are to be displayed in the list.
11 | * The idea of this class has been taken from
12 | * https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.hmhbe8sku
13 | * as of 2016-08-03. Parts of the code were copied from that source.
14 | */
15 | public class ItemViewHolder extends RecyclerView.ViewHolder {
16 |
17 | /**
18 | * Member variables
19 | */
20 | private TextView tvInformation;
21 |
22 |
23 | /**
24 | * Constructor.
25 | *
26 | * @param itemView The view that contains the fields that are to be set for each list item.
27 | */
28 | public ItemViewHolder(View itemView) {
29 | super(itemView);
30 | tvInformation = (TextView) itemView.findViewById(R.id.city_overview_list_item_text);
31 | }
32 |
33 | /**
34 | * @return Returns the TextView of the item.
35 | */
36 | public TextView getTvInformation() {
37 | return tvInformation;
38 | }
39 |
40 |
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/RecycleList/OnSwipeDownListener.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.RecycleList;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.view.GestureDetector;
6 | import android.view.MotionEvent;
7 | import android.view.View;
8 |
9 | public class OnSwipeDownListener implements View.OnTouchListener {
10 |
11 | private final GestureDetector gestureDetector;
12 |
13 | public OnSwipeDownListener(Context context) {
14 | gestureDetector = new GestureDetector(context, new GestureListener());
15 | }
16 |
17 | @SuppressLint("ClickableViewAccessibility")
18 | public boolean onTouch(final View view, final MotionEvent motionEvent) {
19 | return gestureDetector.onTouchEvent(motionEvent);
20 | }
21 |
22 | private final class GestureListener extends GestureDetector.SimpleOnGestureListener {
23 |
24 | private static final int SWIPE_THRESHOLD = 120;
25 | private static final int SWIPE_VELOCITY_THRESHOLD = 120;
26 |
27 | @Override
28 | public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
29 | boolean result = false;
30 | try {
31 | float diffY = e2.getY() - e1.getY();
32 | if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
33 | if (diffY > 0) {
34 | onSwipeDown();
35 | }
36 | }
37 | } catch (Exception exception) {
38 | exception.printStackTrace();
39 | }
40 | return result;
41 | }
42 | }
43 |
44 | public void onSwipeDown() { }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/RecycleList/RecyclerItemClickListener.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.RecycleList;
2 |
3 | import android.content.Context;
4 | import androidx.recyclerview.widget.RecyclerView;
5 | import android.view.GestureDetector;
6 | import android.view.MotionEvent;
7 | import android.view.View;
8 |
9 | /**
10 | * Provides the functionality to detect (long) touch events on RecyclerView items.
11 | * The code has been taken from
12 | * http://stackoverflow.com/questions/24471109/recyclerview-onclick (answer of H. Azizkhani) as of
13 | * 2016-08-04.
14 | */
15 |
16 | public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
17 | private OnItemClickListener mListener;
18 |
19 | public interface OnItemClickListener {
20 | void onItemClick(View view, int position);
21 |
22 | void onLongItemClick(View view, int position);
23 |
24 | }
25 |
26 | private GestureDetector mGestureDetector;
27 |
28 | public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
29 | mListener = listener;
30 | mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
31 |
32 | @Override
33 | public boolean onSingleTapUp(MotionEvent e) {
34 | return true;
35 | }
36 |
37 | @Override
38 | public void onLongPress(MotionEvent e) {
39 | View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
40 | if (child != null && mListener != null) {
41 | mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
42 | }
43 | }
44 |
45 | });
46 | }
47 |
48 | @Override
49 | public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
50 | View childView = view.findChildViewUnder(e.getX(), e.getY());
51 | if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
52 | mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
53 | return true;
54 | }
55 | return false;
56 | }
57 |
58 | @Override
59 | public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
60 |
61 | }
62 |
63 | @Override
64 | public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
65 | }
66 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/RecycleList/RecyclerOverviewListAdapter.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.RecycleList;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.recyclerview.widget.RecyclerView;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import org.woheller69.spritpreise.R;
11 | import org.woheller69.spritpreise.database.CityToWatch;
12 | import org.woheller69.spritpreise.database.SQLiteHelper;
13 |
14 | import java.util.Collections;
15 | import java.util.List;
16 |
17 | /**
18 | * This is the adapter for the RecyclerList that is to be used for the overview of added locations.
19 | * For the most part, it has been taken from
20 | * https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.hmhbe8sku
21 | * as of 2016-08-03
22 | */
23 | public class RecyclerOverviewListAdapter extends RecyclerView.Adapter implements ItemTouchHelperAdapter {
24 |
25 | /**
26 | * Member variables
27 | */
28 | private Context context;
29 | private final List cities;
30 |
31 | SQLiteHelper database;
32 |
33 |
34 | /**
35 | * Constructor.
36 | */
37 | public RecyclerOverviewListAdapter(Context context, List cities) {
38 | this.context = context;
39 | this.cities = cities;
40 | this.database = SQLiteHelper.getInstance(context);
41 | }
42 |
43 |
44 | /**
45 | * @see RecyclerView.Adapter#onCreateViewHolder(ViewGroup, int)
46 | * Returns the template for a list item.
47 | */
48 | @Override
49 | public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
50 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_city_list, parent, false);
51 | return new ItemViewHolder(view);
52 | }
53 |
54 | /**
55 | * @see RecyclerView.Adapter#onBindViewHolder(RecyclerView.ViewHolder, int)
56 | * Sets the content of items.
57 | */
58 | @Override
59 | public void onBindViewHolder(ItemViewHolder holder, int position) {
60 | holder.getTvInformation().setText(cities.get(position).getCityName());
61 | }
62 |
63 | /**
64 | * @see RecyclerView.Adapter#getItemCount()
65 | */
66 | @Override
67 | public int getItemCount() {
68 | return cities.size();
69 | }
70 |
71 | /**
72 | * @see ItemTouchHelperAdapter#onItemDismiss(int)
73 | * Removes an item from the list.
74 | */
75 | @Override
76 | public void onItemDismiss(int position) {
77 |
78 | CityToWatch city = cities.get(position);
79 | database.deleteCityToWatch(city);
80 | cities.remove(position);
81 | notifyItemRemoved(position);
82 | }
83 |
84 | /**
85 | * @see ItemTouchHelperAdapter#onItemMove(int, int)
86 | */
87 | @Override
88 | public void onItemMove(int fromPosition, int toPosition) {
89 | // For updating the database records
90 | CityToWatch fromCityToWatch = cities.get(fromPosition);
91 | int fromRank = fromCityToWatch.getRank();
92 | CityToWatch toCityToWatch = cities.get(toPosition);
93 | int toRank = toCityToWatch.getRank();
94 |
95 | fromCityToWatch.setRank(toRank);
96 | toCityToWatch.setRank(fromRank);
97 | database.updateCityToWatch(fromCityToWatch);
98 | database.updateCityToWatch(toCityToWatch);
99 | Collections.swap(cities, fromPosition, toPosition);
100 | notifyItemMoved(fromPosition, toPosition);
101 |
102 | }
103 |
104 | public String getCityName(int position){
105 | CityToWatch cityToWatch = cities.get(position);
106 | return cityToWatch.getCityName();
107 | }
108 |
109 | public void renameCity(int position, String s) {
110 | CityToWatch cityToWatch = cities.get(position);
111 | cityToWatch.setCityName(s);
112 | database.updateCityToWatch(cityToWatch);
113 | notifyItemChanged(position);
114 | }
115 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/RecycleList/SimpleItemTouchHelperCallback.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.RecycleList;
2 |
3 | import androidx.recyclerview.widget.RecyclerView;
4 | import androidx.recyclerview.widget.ItemTouchHelper;
5 |
6 | /**
7 | * To use the ItemTouchHelper we need to create an ItemTouchHelper.Callback which this class is.
8 | * For the most part it has been taken from
9 | * https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.hmhbe8sku
10 | * as of 2016-08-03
11 | */
12 | public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
13 |
14 | private final ItemTouchHelperAdapter adapter;
15 |
16 | /**
17 | * Constructor.
18 | *
19 | * @param adapter The adapter to bind the ItemTouchHelper to.
20 | */
21 | public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
22 | this.adapter = adapter;
23 | }
24 |
25 | /**
26 | * @see ItemTouchHelper.Callback#isLongPressDragEnabled()
27 | * As it is not supported, false will be returned.
28 | */
29 | @Override
30 | public boolean isLongPressDragEnabled() {
31 | return true;
32 | }
33 |
34 | /**
35 | * @see ItemTouchHelper.Callback#isItemViewSwipeEnabled()
36 | * As this feature is supported, true will be returned.
37 | */
38 | @Override
39 | public boolean isItemViewSwipeEnabled() {
40 | return true;
41 | }
42 |
43 | /**
44 | * @see androidx.recyclerview.widget.ItemTouchHelper.Callback#getMovementFlags(RecyclerView, RecyclerView.ViewHolder)
45 | * Sets the swipe flags for start and end.
46 | */
47 | @Override
48 | public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
49 | int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
50 | int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
51 | return makeMovementFlags(dragFlags, swipeFlags);
52 | }
53 |
54 | /**
55 | * @see androidx.recyclerview.widget.ItemTouchHelper.Callback#onMove(RecyclerView, RecyclerView.ViewHolder, RecyclerView.ViewHolder)
56 | */
57 | @Override
58 | public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
59 | adapter.onItemMove(viewHolder.getBindingAdapterPosition(), target.getBindingAdapterPosition());
60 | return true;
61 | }
62 |
63 | /**
64 | * @see androidx.recyclerview.widget.ItemTouchHelper.Callback#onSwiped(RecyclerView.ViewHolder, int)
65 | * On swipe, the corresponding element is removed from the list.
66 | */
67 | @Override
68 | public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
69 | adapter.onItemDismiss(viewHolder.getBindingAdapterPosition());
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/RecycleList/StationAdapter.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.RecycleList;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.core.content.res.ResourcesCompat;
7 | import androidx.preference.PreferenceManager;
8 | import androidx.recyclerview.widget.RecyclerView;
9 |
10 | import android.content.SharedPreferences;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.widget.ImageView;
15 | import android.widget.TextView;
16 |
17 | import org.woheller69.spritpreise.R;
18 | import org.woheller69.spritpreise.database.Station;
19 | import org.woheller69.spritpreise.ui.Help.StringFormatUtils;
20 |
21 | import java.time.Instant;
22 | import java.util.List;
23 | import java.util.TimeZone;
24 |
25 | //**
26 | // * Created by yonjuni on 02.01.17.
27 | // * Adapter for the horizontal listView for course of the day.
28 | // */import java.util.List;
29 |
30 | public class StationAdapter extends RecyclerView.Adapter {
31 |
32 | private final List stationList;
33 | private final Context context;
34 | private int selected = -1;
35 |
36 | //Adapter for Stations recycler view
37 | StationAdapter(List stationList, Context context) {
38 | this.context = context;
39 | this.stationList = stationList;
40 | }
41 |
42 |
43 | @NonNull
44 | @Override
45 | public StationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
46 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_station, parent, false);
47 | return new StationViewHolder(view);
48 | }
49 |
50 | @Override
51 | public void onBindViewHolder(@NonNull StationViewHolder holder, int position) {
52 | SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
53 |
54 |
55 | if (prefManager.getBoolean("prefBrands", false)) { //if preferred brands are defined
56 | String[] brands = prefManager.getString("prefBrandsString", "").split(","); //read comma separated list
57 | for (String brand : brands) {
58 | if (stationList.get(position).getBrand().toLowerCase().contains(brand.toLowerCase().trim())) {
59 | holder.fav.setVisibility(View.VISIBLE);
60 | break;
61 | }
62 | }
63 | }
64 | if (stationList.get(position).getDiesel()>0){
65 | holder.diesel.setText(StringFormatUtils.formatPrice(context, "D: ",stationList.get(position).getDiesel()," €"));
66 | } else holder.diesel.setVisibility(View.GONE);
67 | if (stationList.get(position).getE5()>0){
68 | holder.e5.setText( StringFormatUtils.formatPrice(context, "E5: ",stationList.get(position).getE5()," €"));
69 | } else holder.e5.setVisibility(View.GONE);
70 | if (stationList.get(position).getE10()>0){
71 | holder.e10.setText(StringFormatUtils.formatPrice(context, "E10: ",stationList.get(position).getE10()," €"));
72 | } else holder.e10.setVisibility(View.GONE);
73 | holder.dist.setText(stationList.get(position).getDistance()+" km");
74 | holder.address.setText((stationList.get(position).getAddress1()+", "+stationList.get(position).getAddress2()).toUpperCase());
75 | if (stationList.get(position).isOpen()) {
76 | holder.isOpen.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),R.drawable.ic_local_gas_station_green_24dp, null));
77 | }
78 | else {
79 | holder.isOpen.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),R.drawable.ic_local_gas_station_red_24dp, null));
80 | }
81 |
82 | holder.name.setText(stationList.get(position).getBrand());
83 |
84 | if (position == selected) holder.itemView.setBackground(ResourcesCompat.getDrawable(context.getResources(),R.drawable.rounded_highlight,null));
85 | else holder.itemView.setBackground(ResourcesCompat.getDrawable(context.getResources(),R.drawable.rounded_transparent,null));
86 |
87 | }
88 |
89 | @Override
90 | public int getItemCount() {
91 | return stationList.size();
92 | }
93 |
94 | public void setSelected(int position) {
95 | int oldSelected = selected;
96 | selected = position;
97 | notifyItemChanged(oldSelected);
98 | notifyItemChanged(selected);
99 | }
100 |
101 | public int getPosUUID(String id) {
102 |
103 | for (int i=0;i stations, int cityID);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/updater/ViewUpdater.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.updater;
2 |
3 | import org.woheller69.spritpreise.database.Station;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * Created by chris on 24.01.2017.
10 | */
11 |
12 | public class ViewUpdater {
13 | private static List subscribers = new ArrayList<>();
14 |
15 | public static void addSubscriber(IUpdateableCityUI sub) {
16 | if (!subscribers.contains(sub)) {
17 | subscribers.add(sub);
18 | }
19 | }
20 |
21 | public static void removeSubscriber(IUpdateableCityUI sub) {
22 | subscribers.remove(sub);
23 | }
24 |
25 | public static void updateStations(List stations, int cityID) {
26 | ArrayList subcopy = new ArrayList<>(subscribers);
27 | for (IUpdateableCityUI sub : subcopy) {
28 | sub.processUpdateStations(stations,cityID);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/util/AutoSuggestAdapter.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.util;
2 | /*
3 | * Taken from https://github.com/Truiton/AutoSuggestTextViewAPICall
4 | * Modified by woheller69
5 | */
6 |
7 |
8 | import android.content.Context;
9 |
10 | import android.widget.ArrayAdapter;
11 | import android.widget.Filter;
12 | import android.widget.Filterable;
13 |
14 | import androidx.annotation.NonNull;
15 | import androidx.annotation.Nullable;
16 |
17 | import org.woheller69.spritpreise.database.City;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | public class AutoSuggestAdapter extends ArrayAdapter implements Filterable {
23 | private final List mlistData;
24 | private final List mlistCity;
25 |
26 | public AutoSuggestAdapter(@NonNull Context context, int resource) {
27 | super(context, resource);
28 | mlistData = new ArrayList<>();
29 | mlistCity = new ArrayList<>();
30 | }
31 |
32 | public void setData(List list, List cityList) {
33 | mlistData.clear();
34 | mlistCity.clear();
35 | mlistData.addAll(list);
36 | mlistCity.addAll(cityList);
37 | }
38 |
39 | @Override
40 | public int getCount() {
41 | return mlistData.size();
42 | }
43 |
44 | @Nullable
45 | @Override
46 | public String getItem(int position) {
47 | return mlistData.get(position);
48 | }
49 |
50 | /**
51 | * Used to Return the full object directly from adapter.
52 | *
53 | * @param position
54 | * @return
55 | */
56 | public City getObject(int position) {
57 | return mlistCity.get(position);
58 | }
59 |
60 | @NonNull
61 | @Override
62 | public Filter getFilter() {
63 | Filter dataFilter = new Filter() {
64 | @Override
65 | protected FilterResults performFiltering(CharSequence constraint) {
66 | FilterResults filterResults = new FilterResults();
67 | if (constraint != null) {
68 | filterResults.values = mlistData;
69 | filterResults.count = mlistData.size();
70 | }
71 | return filterResults;
72 | }
73 |
74 | @Override
75 | protected void publishResults(CharSequence constraint, FilterResults results) {
76 | if (results != null && (results.count > 0)) {
77 | notifyDataSetChanged();
78 | } else {
79 | notifyDataSetInvalidated();
80 | }
81 | }
82 | };
83 | return dataFilter;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/util/geocodingApiCall.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.util;
2 |
3 | import android.content.Context;
4 |
5 | import com.android.volley.Request;
6 | import com.android.volley.RequestQueue;
7 | import com.android.volley.Response;
8 | import com.android.volley.toolbox.StringRequest;
9 | import com.android.volley.toolbox.Volley;
10 |
11 | /**
12 | * Created by MG on 04-03-2018.
13 | *
14 | * Taken from https://github.com/Truiton/AutoSuggestTextViewAPICall
15 | * Modified by woheller69
16 | */
17 |
18 | public class geocodingApiCall {
19 | private static geocodingApiCall mInstance;
20 | private RequestQueue mRequestQueue;
21 | private static Context mCtx;
22 |
23 | public geocodingApiCall(Context ctx) {
24 | mCtx = ctx.getApplicationContext();
25 | mRequestQueue = getRequestQueue();
26 | }
27 |
28 | public static synchronized geocodingApiCall getInstance(Context context) {
29 | if (mInstance == null) {
30 | mInstance = new geocodingApiCall(context);
31 | }
32 | return mInstance;
33 | }
34 |
35 | public RequestQueue getRequestQueue() {
36 | if (mRequestQueue == null) {
37 | mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
38 | }
39 | return mRequestQueue;
40 | }
41 |
42 | public void addToRequestQueue(Request req) {
43 | getRequestQueue().add(req);
44 | }
45 |
46 | public static void make(Context ctx, String query, String url, String lang, Response.Listener
47 | listener, Response.ErrorListener errorListener) {
48 | url = url + query+"&language="+lang;
49 | StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
50 | listener, errorListener);
51 | geocodingApiCall.getInstance(ctx).addToRequestQueue(stringRequest);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/org/woheller69/spritpreise/ui/viewPager/CityPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package org.woheller69.spritpreise.ui.viewPager;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import androidx.annotation.NonNull;
7 | import androidx.fragment.app.FragmentManager;
8 | import androidx.lifecycle.Lifecycle;
9 | import androidx.viewpager2.adapter.FragmentStateAdapter;
10 |
11 | import org.woheller69.spritpreise.database.CityToWatch;
12 | import org.woheller69.spritpreise.database.Station;
13 | import org.woheller69.spritpreise.database.SQLiteHelper;
14 | import org.woheller69.spritpreise.services.UpdateDataService;
15 | import org.woheller69.spritpreise.ui.CityFragment;
16 | import org.woheller69.spritpreise.ui.updater.IUpdateableCityUI;
17 |
18 | import java.util.Collections;
19 | import java.util.List;
20 |
21 | import static androidx.core.app.JobIntentService.enqueueWork;
22 | import static org.woheller69.spritpreise.services.UpdateDataService.SKIP_UPDATE_INTERVAL;
23 |
24 | public class CityPagerAdapter extends FragmentStateAdapter implements IUpdateableCityUI {
25 |
26 | private final SQLiteHelper database;
27 |
28 | private List cities;
29 |
30 | //Adapter for the Viewpager switching between different locations
31 | public CityPagerAdapter(Context context, @NonNull FragmentManager supportFragmentManager, @NonNull Lifecycle lifecycle) {
32 | super(supportFragmentManager,lifecycle);
33 | this.database = SQLiteHelper.getInstance(context);
34 | loadCities();
35 | }
36 |
37 | public void loadCities() {
38 | this.cities = database.getAllCitiesToWatch();
39 | Collections.sort(cities, (o1, o2) -> o1.getRank() - o2.getRank());
40 | }
41 |
42 | @NonNull
43 | @Override
44 | public CityFragment createFragment(int position) {
45 | Bundle args = new Bundle();
46 | args.putInt("city_id", cities.get(position).getCityId());
47 |
48 | return CityFragment.newInstance(args);
49 | }
50 |
51 | @Override
52 | public int getItemCount() {
53 | return cities.size();
54 | }
55 |
56 |
57 | public CharSequence getPageTitle(int position) {
58 | return cities.get(position).getCityName();
59 | }
60 |
61 | public static void refreshSingleData(Context context, Boolean asap, int cityId) {
62 | Intent intent = new Intent(context, UpdateDataService.class);
63 | intent.setAction(UpdateDataService.UPDATE_SINGLE_ACTION);
64 | intent.putExtra(SKIP_UPDATE_INTERVAL, asap);
65 | intent.putExtra("cityId",cityId);
66 | enqueueWork(context, UpdateDataService.class, 0, intent);
67 | }
68 |
69 |
70 | @Override
71 | public void processUpdateStations(List stations, int cityID) {
72 |
73 | }
74 |
75 | public int getCityIDForPos(int pos) {
76 | CityToWatch city = cities.get(pos);
77 | return city.getCityId();
78 | }
79 |
80 | public int getPosForCityID(int cityID) {
81 | for (int i = 0; i < cities.size(); i++) {
82 | CityToWatch city = cities.get(i);
83 | if (city.getCityId() == cityID) {
84 | return i;
85 | }
86 | }
87 | return -1; // item not found
88 | }
89 |
90 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/drawable-hdpi/splash_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/drawable-mdpi/splash_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/widget_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/drawable-nodpi/widget_preview.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/drawable-xhdpi/splash_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/drawable-xxhdpi/splash_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/drawable-xxxhdpi/splash_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/app_icon.xml:
--------------------------------------------------------------------------------
1 |
6 |
8 |
13 |
18 |
23 |
24 |
26 |
27 |
29 |
34 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_star_rate_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add_location_alt_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_back_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_direction_32dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_edit_location_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_highlight_32dp.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_info_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
8 |
13 |
14 |
16 |
17 |
19 |
24 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_monochrome.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
13 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_local_gas_station_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_local_gas_station_green_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_local_gas_station_red_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_location_32dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_location_on_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_map_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_playpause.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_rainviewer.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
9 |
12 |
15 |
18 |
21 |
24 |
27 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_refresh_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_skip_next_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_skip_previous_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_south_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_widget_gas_station_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/map_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/drawable/map_back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/recycle_view_line_divider.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_green.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_grey.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_highlight.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_lightred.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_orange.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_red.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_transparent.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_yellow.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/splash_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/star_primary_dark_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/star_yellow_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/transparent_no_margin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/card_stations.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
18 |
19 |
23 |
24 |
30 |
31 |
41 |
42 |
46 |
47 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/about.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
18 |
19 |
27 |
28 |
34 |
35 |
36 |
42 |
43 |
50 |
51 |
52 |
53 |
61 |
62 |
63 |
70 |
71 |
80 |
81 |
89 |
90 |
91 |
98 |
99 |
107 |
108 |
115 |
116 |
124 |
125 |
132 |
133 |
140 |
141 |
150 |
151 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_city_gas_prices.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
17 |
18 |
23 |
24 |
31 |
32 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_manage_locations.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
17 |
18 |
26 |
27 |
32 |
33 |
34 |
35 |
36 |
37 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_tutorial.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
12 |
13 |
21 |
22 |
28 |
29 |
38 |
39 |
40 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/card_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/card_overview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/card_stations.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
18 |
19 |
23 |
24 |
34 |
35 |
39 |
40 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/card_week.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
23 |
24 |
28 |
29 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/city_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_manage_locations.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
24 |
25 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_add_location.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
25 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_group.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_autocomplete.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_city_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
25 |
26 |
27 |
36 |
37 |
38 |
39 |
47 |
48 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_station.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
18 |
19 |
25 |
26 |
33 |
34 |
43 |
44 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
67 |
68 |
79 |
90 |
101 |
102 |
103 |
104 |
116 |
117 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_week_forecast.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
23 |
24 |
27 |
28 |
37 |
38 |
47 |
56 |
57 |
66 |
67 |
76 |
77 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/menu_refresh_action_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/menu_update_location_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
19 |
20 |
26 |
27 |
28 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tutorial_slide1.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
16 |
23 |
24 |
28 |
29 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tutorial_slide2.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
22 |
23 |
27 |
28 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tutorial_slide3.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
22 |
23 |
27 |
28 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tutorial_slide4.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
18 |
19 |
23 |
26 |
27 |
38 |
39 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_city_gas_prices.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #181818
4 | #777777
5 | #a0a0a0
6 | #FFFFFF
7 | #707070
8 | #BBFFFFFF
9 | #2A2A2A
10 | #303030
11 | #d01530
12 | #fa7972
13 | #f8f49f
14 | #fec58e
15 | #c3f5b2
16 | #0274b2
17 | #1382d4
18 | #1b5cd9
19 | #080808
20 | #DD181818
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - @string/settings_interval_5
6 | - @string/settings_interval_10
7 | - @string/settings_interval_15
8 | - @string/settings_interval_30
9 |
10 |
11 |
12 | - 5
13 | - 10
14 | - 15
15 | - 30
16 |
17 |
18 |
19 | - 1 km
20 | - 2 km
21 | - 3 km
22 | - 4 km
23 | - 5 km
24 | - 10 km
25 | - 25 km
26 |
27 |
28 |
29 | - 1
30 | - 2
31 | - 3
32 | - 4
33 | - 5
34 | - 10
35 | - 25
36 |
37 |
38 |
39 | - @string/settings_type_all
40 | - E5
41 | - E10
42 | - Diesel
43 |
44 |
45 |
46 | - all
47 | - e5
48 | - e10
49 | - diesel
50 |
51 |
52 |
53 | #026499
54 |
55 |
56 | #448bb2
57 |
58 |
59 | - @color/dot_light_screen
60 | - @color/dot_light_screen
61 | - @color/dot_light_screen
62 | - @color/dot_light_screen
63 |
64 |
65 |
66 | - @color/dot_dark_screen
67 | - @color/dot_dark_screen
68 | - @color/dot_dark_screen
69 | - @color/dot_dark_screen
70 |
71 |
72 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #024265
4 | #024265
5 | #0274b2
6 | #024265
7 | #5fa1d2
8 | #A8A8A8
9 | #AAFFFFFF
10 | #fafafa
11 | #d01530
12 | #fa7972
13 | #f8f49f
14 | #fec58e
15 | #c3f5b2
16 | #0274b2
17 | #1382d4
18 | #1b5cd9
19 | #6fb1e2
20 | #DD6fb1e2
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 160dp
4 |
5 | 16dp
6 | 16dp
7 | 5dp
8 | 16dp
9 | 10dp
10 |
11 | 120dp
12 | 30dp
13 | 16dp
14 | 40dp
15 |
16 | 30dp
17 | 20dp
18 | 4dp
19 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_general.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
9 |
13 |
14 |
15 |
16 |
17 |
22 |
23 |
30 |
31 |
39 |
40 |
46 |
47 |
54 |
55 |
62 |
63 |
68 |
69 |
74 |
75 |
81 |
82 |
88 |
89 |
90 |
91 |
97 |
102 |
103 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/widget_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | mavenCentral()
6 | maven {
7 | url 'https://maven.google.com/'
8 | name 'Google'
9 | }
10 | maven { url 'https://jitpack.io' }
11 | }
12 | dependencies {
13 | classpath 'com.android.tools.build:gradle:8.2.2'
14 |
15 | // NOTE: Do not place your application dependencies here; they belong
16 | // in the individual module build.gradle files
17 |
18 | }
19 | }
20 |
21 | allprojects {
22 | repositories {
23 | mavenCentral()
24 | maven {
25 | url 'https://maven.google.com/'
26 | name 'Google'
27 | }
28 | maven { url 'https://jitpack.io' }
29 | }
30 | tasks.withType(JavaCompile) {
31 | options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
32 | }
33 | }
34 |
35 | task clean(type: Delete) {
36 | delete rootProject.buildDir
37 | }
38 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/10.txt:
--------------------------------------------------------------------------------
1 | Erste Version
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/11.txt:
--------------------------------------------------------------------------------
1 | Verbessertes Widget
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/12.txt:
--------------------------------------------------------------------------------
1 | Eingabemöglichkeit für bevorzugte Marken
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/13.txt:
--------------------------------------------------------------------------------
1 | Eingabemöglichkeit für bevorzugte Spritsorte
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/14.txt:
--------------------------------------------------------------------------------
1 | Aktualisieren der GPS Position direkt in der App (ohne Widget)
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/15.txt:
--------------------------------------------------------------------------------
1 | API-Key eingefügt
2 | Fehlerbehebung
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/16.txt:
--------------------------------------------------------------------------------
1 | Fehlerbehebung
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/17.txt:
--------------------------------------------------------------------------------
1 | Fehlerbehebung
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/18.txt:
--------------------------------------------------------------------------------
1 | Upgrade auf Android 12 SDK
2 | Fehlerbehebung
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/19.txt:
--------------------------------------------------------------------------------
1 | Fehlerbehebung
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/20.txt:
--------------------------------------------------------------------------------
1 | Design: Icons statt "offen" / "geschlossen"
2 | Option: Suchradius bis 25km
3 | Option: geschlossene Tankstellen ausblenden
4 | Fehlerbehebung
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/21.txt:
--------------------------------------------------------------------------------
1 | Neue Option: Karte mit Tankstellen anzeigen
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/22.txt:
--------------------------------------------------------------------------------
1 | Photon-Geolocation API durch Open-Meteo API ersetzt
2 | Fehlerbehebung
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/23.txt:
--------------------------------------------------------------------------------
1 | Kartenansicht vergrößert
2 | Monochromes Icon hinzugefügt
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/24.txt:
--------------------------------------------------------------------------------
1 | Update auf Android 13 SDK
2 | Ausgewähltes Element in Liste hervorheben anstatt Pop-up
3 | Aktuelle Position auf Karte anzeigen
4 | Optimiertes Layout für Querformat
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/25.txt:
--------------------------------------------------------------------------------
1 | Gestensteuerung anstelle von +/- für Zoom
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/26.txt:
--------------------------------------------------------------------------------
1 | Update auf Android 14 (SDK 34)
2 | Anzeige der eigenen Bewegungsrichtung
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/27.txt:
--------------------------------------------------------------------------------
1 | Fix widget for older devices
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/changelogs/28.txt:
--------------------------------------------------------------------------------
1 | Update auf Android 15 (SDK 35)
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/full_description.txt:
--------------------------------------------------------------------------------
1 | Spritpreise stellt die Preise, die die Tankstellen in Deutschland an die Markttransparenzstelle melden, zur Verfügung.
2 | Sie können Ihre eigenen Standorte auswählen und erhalten aktuelle Spritpreise.
3 | Durch Klicken auf eine Tankstelle in der Liste oder auf das Symbol im Widget wird die Tankstelle in einer Kartenanwendung angezeigt.
4 | Sie können der App auch erlauben, GPS zu verwenden. Wenn Sie dies tun und das App-Widget installiert haben, wird die Position von Zeit zu Zeit aktualisiert und der erste Tab in der App und das Widget zeigen Tankstellen für Ihren aktuellen Standort an. (Dadurch wird die Stadt in Ihrem ersten Tab überschrieben.)
5 | Sie können Ihre bevorzugten Marken auch in den Einstellungen eintragen. In diesem Fall markiert die Liste in der App Ihre bevorzugten Marken
6 | mit einem Stern und das Widget zeigt die nächstgelegene Station einer dieser Marken an, sofern im Suchradius verfügbar.
7 | Sie können die bevorzugte Spritsorte einstellen. In diesem Fall ist dann auch eine Sortierung nach Preis möglich.
8 |
9 | Die Daten werden über die Tankerkönig API unter Creative-Commons-Lizenz “CC BY 4.0” von www.tankerkönig.de bereitgestellt.
10 |
11 | Minimale Berechtigungen:
12 | Spritpreise benötigt nur ein Minimum an Berechtigungen, nämlich nur die INTERNET-Berechtigung. Diese ist nötig, um HTTP-Anfragen an entfernte Server zu stellen, um Spritpreise zu erhalten.
13 | Optional: Berechtigung für GPS.
14 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/short_description.txt:
--------------------------------------------------------------------------------
1 | Spritpreise zeigt die aktuellen Preise an den Tankstellen in Deutschland
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/title.txt:
--------------------------------------------------------------------------------
1 | Spritpreise
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/10.txt:
--------------------------------------------------------------------------------
1 | Initial release
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/11.txt:
--------------------------------------------------------------------------------
1 | Improved widget
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/12.txt:
--------------------------------------------------------------------------------
1 | Added option to define favourite brands
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/13.txt:
--------------------------------------------------------------------------------
1 | Added option to set preferred fuel type
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/14.txt:
--------------------------------------------------------------------------------
1 | Added option to update GPS location in app (without widget)
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/15.txt:
--------------------------------------------------------------------------------
1 | API key included
2 | Bugfixes
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/16.txt:
--------------------------------------------------------------------------------
1 | Bugfixes
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/17.txt:
--------------------------------------------------------------------------------
1 | Bugfixes
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/18.txt:
--------------------------------------------------------------------------------
1 | Upgrade to Android 12 SDK
2 | Bugfixes
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/19.txt:
--------------------------------------------------------------------------------
1 | Bugfixes
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/20.txt:
--------------------------------------------------------------------------------
1 | UI: Icons instead of "open" / "closed"
2 | Option: Search radius up to 25km
3 | Option: hide closed stations
4 | Bug fixes
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/21.txt:
--------------------------------------------------------------------------------
1 | New option: Show map with stations
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/22.txt:
--------------------------------------------------------------------------------
1 | Photon geolocation API replaced with Open-Meteo API
2 | Bugfixes
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/23.txt:
--------------------------------------------------------------------------------
1 | Increased map size
2 | Added monochrome icon
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/24.txt:
--------------------------------------------------------------------------------
1 | Update for Android 13 SDK
2 | Highlight selected element in list instead of showing pop-up
3 | Show current position on map
4 | Optimized layout for landscape mode
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/25.txt:
--------------------------------------------------------------------------------
1 | Multi touch control instead of +/- for zoom
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/26.txt:
--------------------------------------------------------------------------------
1 | Update for Android 14 (SDK 34)
2 | Show movement direction
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/27.txt:
--------------------------------------------------------------------------------
1 | Fix widget for older devices
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/28.txt:
--------------------------------------------------------------------------------
1 | Update for Android 15 (SDK 35)
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | Gas Prices Germany provides the prices that the petrol stations report to the market transparency office.
2 | You can choose your own locations and get current gas prices.
3 | Clicking on a gas station in the list or on the icon in the widget shows the gas station in an external map application.
4 | You can also allow the app to use GPS. If you do so and have the app widget installed the position will be updated from time to time and the first tab in the app and the widget will show gas stations for your current location. (This will overwrite the city in your first tab.)
5 | You can also enter your favourite brands in settings. In this case the list in the app will mark your favourite brands
6 | with a star and the widget will show the closest station of one of these brands if available in the search radius.
7 | You can set your preferred fuel type. In this case it is also possible to sort results by price.
8 |
9 | The data is provided via the Tankerkönig API under the Creative Commons license “CC BY 4.0” from www.tankerkönig.de.
10 |
11 | Minimum permissions:
12 | Gas Prices only requires the minimum amount of permission, namely only the INTERNET permission. This permission is necessary to make HTTP requests to remote servers for retrieving gas prices.
13 | Optional: authorization for GPS.
14 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/fastlane/metadata/android/en-US/images/icon.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | Gas Prices shows the current prices at petrol stations in Germany
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/title.txt:
--------------------------------------------------------------------------------
1 | Gas Prices
2 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
10 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | org.gradle.jvmargs=-Xmx2048M
16 | android.useAndroidX=true
17 | android.enableJetifier=true
18 | prop1=OTgxMjBmODAtNzYwNy0zOTQxLTI3NGUtMDE5MGI0NDg2NmZh
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woheller69/spritpreise/1e752d920f569b6b66069015c9ede2709880b7da/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionSha256Sum=9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 | # Determine the Java command to use to start the JVM.
86 | if [ -n "$JAVA_HOME" ] ; then
87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
88 | # IBM's JDK on AIX uses strange locations for the executables
89 | JAVACMD="$JAVA_HOME/jre/sh/java"
90 | else
91 | JAVACMD="$JAVA_HOME/bin/java"
92 | fi
93 | if [ ! -x "$JAVACMD" ] ; then
94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
95 |
96 | Please set the JAVA_HOME variable in your environment to match the
97 | location of your Java installation."
98 | fi
99 | else
100 | JAVACMD="java"
101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
102 |
103 | Please set the JAVA_HOME variable in your environment to match the
104 | location of your Java installation."
105 | fi
106 |
107 | # Increase the maximum file descriptors if we can.
108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
109 | MAX_FD_LIMIT=`ulimit -H -n`
110 | if [ $? -eq 0 ] ; then
111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
112 | MAX_FD="$MAX_FD_LIMIT"
113 | fi
114 | ulimit -n $MAX_FD
115 | if [ $? -ne 0 ] ; then
116 | warn "Could not set maximum file descriptor limit: $MAX_FD"
117 | fi
118 | else
119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
120 | fi
121 | fi
122 |
123 | # For Darwin, add options to specify how the application appears in the dock
124 | if $darwin; then
125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
126 | fi
127 |
128 | # For Cygwin or MSYS, switch paths to Windows format before running java
129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
132 | JAVACMD=`cygpath --unix "$JAVACMD"`
133 |
134 | # We build the pattern for arguments to be converted via cygpath
135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
136 | SEP=""
137 | for dir in $ROOTDIRSRAW ; do
138 | ROOTDIRS="$ROOTDIRS$SEP$dir"
139 | SEP="|"
140 | done
141 | OURCYGPATTERN="(^($ROOTDIRS))"
142 | # Add a user-defined pattern to the cygpath arguments
143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
145 | fi
146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
147 | i=0
148 | for arg in "$@" ; do
149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
151 |
152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
154 | else
155 | eval `echo args$i`="\"$arg\""
156 | fi
157 | i=`expr $i + 1`
158 | done
159 | case $i in
160 | 0) set -- ;;
161 | 1) set -- "$args0" ;;
162 | 2) set -- "$args0" "$args1" ;;
163 | 3) set -- "$args0" "$args1" "$args2" ;;
164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
170 | esac
171 | fi
172 |
173 | # Escape application args
174 | save () {
175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
176 | echo " "
177 | }
178 | APP_ARGS=`save "$@"`
179 |
180 | # Collect all arguments for the java command, following the shell quoting and substitution rules
181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
182 |
183 | exec "$JAVACMD" "$@"
184 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
34 |
35 | @rem Find java.exe
36 | if defined JAVA_HOME goto findJavaFromJavaHome
37 |
38 | set JAVA_EXE=java.exe
39 | %JAVA_EXE% -version >NUL 2>&1
40 | if "%ERRORLEVEL%" == "0" goto init
41 |
42 | echo.
43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
44 | echo.
45 | echo Please set the JAVA_HOME variable in your environment to match the
46 | echo location of your Java installation.
47 |
48 | goto fail
49 |
50 | :findJavaFromJavaHome
51 | set JAVA_HOME=%JAVA_HOME:"=%
52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
53 |
54 | if exist "%JAVA_EXE%" goto init
55 |
56 | echo.
57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
58 | echo.
59 | echo Please set the JAVA_HOME variable in your environment to match the
60 | echo location of your Java installation.
61 |
62 | goto fail
63 |
64 | :init
65 | @rem Get command-line arguments, handling Windows variants
66 |
67 | if not "%OS%" == "Windows_NT" goto win9xME_args
68 |
69 | :win9xME_args
70 | @rem Slurp the command line arguments.
71 | set CMD_LINE_ARGS=
72 | set _SKIP=2
73 |
74 | :win9xME_args_slurp
75 | if "x%~1" == "x" goto execute
76 |
77 | set CMD_LINE_ARGS=%*
78 |
79 | :execute
80 | @rem Setup the command line
81 |
82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
83 |
84 | @rem Execute Gradle
85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
86 |
87 | :end
88 | @rem End local scope for the variables with windows NT shell
89 | if "%ERRORLEVEL%"=="0" goto mainEnd
90 |
91 | :fail
92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
93 | rem the _cmd.exe /c_ return code!
94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
95 | exit /b 1
96 |
97 | :mainEnd
98 | if "%OS%"=="Windows_NT" endlocal
99 |
100 | :omega
101 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------