Skip to content

Commit 876e536

Browse files
author
Michael Ritchie
committed
* More layout tweaks for smaller device screens
* Added check and request dialog for location for weather * Updated launcher icon
1 parent c59e860 commit 876e536

27 files changed

+396
-184
lines changed

app/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ apply plugin: 'com.neenbedankt.android-apt'
2121

2222
def versionMajor = 0
2323
def versionMinor = 3
24-
def versionPatch = 0
24+
def versionPatch = 1
2525
def versionBuild = 0 // bump for dog food builds, public betas, etc.
2626

2727
android {

app/src/main/java/com/thanksmister/iot/mqtt/alarmpanel/BaseActivity.java

+59
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,20 @@
2121
import android.content.Context;
2222
import android.content.DialogInterface;
2323
import android.graphics.Rect;
24+
import android.os.Build;
2425
import android.os.Bundle;
2526
import android.os.Handler;
2627
import android.support.annotation.Nullable;
2728
import android.support.v7.app.AlertDialog;
2829
import android.support.v7.app.AppCompatActivity;
2930
import android.text.Html;
31+
import android.util.DisplayMetrics;
3032
import android.view.LayoutInflater;
3133
import android.view.Menu;
3234
import android.view.MenuItem;
3335
import android.view.View;
3436
import android.view.Window;
37+
import android.view.WindowManager;
3538
import android.widget.TextView;
3639

3740
import com.thanksmister.iot.mqtt.alarmpanel.data.stores.StoreManager;
@@ -54,10 +57,12 @@ abstract public class BaseActivity extends AppCompatActivity {
5457
private AlertDialog dialog;
5558
private AlertDialog screenSaverDialog;
5659
private Handler inactivityHandler = new Handler();
60+
private View decorView;
5761

5862
@Override
5963
protected void onCreate(@Nullable Bundle savedInstanceState) {
6064
super.onCreate(savedInstanceState);
65+
decorView = getWindow().getDecorView();
6166
}
6267

6368
@Override
@@ -83,6 +88,34 @@ protected void onDestroy() {
8388
}
8489
}
8590

91+
@Override
92+
public void onWindowFocusChanged(boolean hasFocus) {
93+
super.onWindowFocusChanged(hasFocus);
94+
if (hasFocus) {
95+
int visibility;
96+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
97+
visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
98+
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
99+
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
100+
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
101+
| View.SYSTEM_UI_FLAG_FULLSCREEN
102+
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
103+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
104+
visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
105+
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
106+
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
107+
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
108+
| View.SYSTEM_UI_FLAG_FULLSCREEN;
109+
110+
} else {
111+
visibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
112+
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
113+
WindowManager.LayoutParams.FLAG_FULLSCREEN);
114+
}
115+
decorView.setSystemUiVisibility(visibility);
116+
}
117+
}
118+
86119
private Runnable inactivityCallback = new Runnable() {
87120
@Override
88121
public void run() {
@@ -198,6 +231,20 @@ public void showArmOptionsDialog(ArmOptionsView.ViewListener armListener) {
198231
hideDialog();
199232
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
200233
View view = inflater.inflate(R.layout.dialog_alarm_options, null, false);
234+
Rect displayRectangle = new Rect();
235+
Window window = getWindow();
236+
window.getDecorView().getWindowVisibleDisplayFrame(displayRectangle);
237+
int density= getResources().getDisplayMetrics().densityDpi;
238+
if(density == DisplayMetrics.DENSITY_TV ) {
239+
view.setMinimumWidth((int) (displayRectangle.width() * 0.6f));
240+
view.setMinimumHeight((int) (displayRectangle.height() * 0.7f));
241+
} else if (density == DisplayMetrics.DENSITY_MEDIUM) {
242+
view.setMinimumWidth((int) (displayRectangle.width() * 0.5f));
243+
view.setMinimumHeight((int) (displayRectangle.height() * 0.6f));
244+
} else {
245+
view.setMinimumWidth((int)(displayRectangle.width() * 0.7f));
246+
view.setMinimumHeight((int)(displayRectangle.height() * 0.8f));
247+
}
201248
final ArmOptionsView optionsView = view.findViewById(R.id.armOptionsView);
202249
optionsView.setListener(armListener);
203250
dialog = new AlertDialog.Builder(BaseActivity.this)
@@ -227,6 +274,18 @@ public void showExtendedForecastDialog(Daily daily) {
227274
hideDialog();
228275
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
229276
View view = inflater.inflate(R.layout.dialog_extended_forecast, null, false);
277+
Rect displayRectangle = new Rect();
278+
Window window = getWindow();
279+
window.getDecorView().getWindowVisibleDisplayFrame(displayRectangle);
280+
view.setMinimumWidth((int)(displayRectangle.width() * 0.7f));
281+
282+
int density= getResources().getDisplayMetrics().densityDpi;
283+
if(density == DisplayMetrics.DENSITY_TV ) {
284+
} else if (density == DisplayMetrics.DENSITY_MEDIUM) {
285+
view.setMinimumHeight((int) (displayRectangle.height() * 0.6f));
286+
} else {
287+
view.setMinimumHeight((int)(displayRectangle.height() * 0.8f));
288+
}
230289
final ExtendedForecastView extendedForecastView = view.findViewById(R.id.extendedForecastView);
231290
extendedForecastView.setExtendedForecast(daily, getConfiguration().getWeatherUnits());
232291
dialog = new AlertDialog.Builder(BaseActivity.this)

app/src/main/java/com/thanksmister/iot/mqtt/alarmpanel/ui/activities/MainActivity.java

-36
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,10 @@
2020

2121
import android.content.DialogInterface;
2222
import android.content.Intent;
23-
import android.os.Build;
2423
import android.os.Bundle;
2524
import android.view.Menu;
2625
import android.view.MenuItem;
2726
import android.view.View;
28-
import android.view.Window;
29-
import android.view.WindowManager;
3027
import android.widget.Toast;
3128

3229
import com.thanksmister.iot.mqtt.alarmpanel.BaseActivity;
@@ -87,16 +84,11 @@ void buttonSleep() {
8784

8885
private SubscriptionDataTask subscriptionDataTask;
8986
private MqttAndroidClient mqttAndroidClient;
90-
private View decorView;
9187

9288
@Override
9389
protected void onCreate(Bundle savedInstanceState) {
9490

9591
super.onCreate(savedInstanceState);
96-
97-
decorView = getWindow().getDecorView();
98-
99-
requestWindowFeature(Window.FEATURE_NO_TITLE);
10092

10193
setContentView(R.layout.activity_main);
10294

@@ -137,34 +129,6 @@ protected void onDestroy() {
137129
}
138130
}
139131

140-
@Override
141-
public void onWindowFocusChanged(boolean hasFocus) {
142-
super.onWindowFocusChanged(hasFocus);
143-
if (hasFocus) {
144-
int visibility;
145-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
146-
visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
147-
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
148-
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
149-
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
150-
| View.SYSTEM_UI_FLAG_FULLSCREEN
151-
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
152-
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
153-
visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
154-
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
155-
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
156-
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
157-
| View.SYSTEM_UI_FLAG_FULLSCREEN;
158-
159-
} else {
160-
visibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
161-
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
162-
WindowManager.LayoutParams.FLAG_FULLSCREEN);
163-
}
164-
decorView.setSystemUiVisibility(visibility);
165-
}
166-
}
167-
168132
@Override
169133
public boolean onCreateOptionsMenu(Menu menu) {
170134
getMenuInflater().inflate(R.menu.global, menu);

app/src/main/java/com/thanksmister/iot/mqtt/alarmpanel/ui/fragments/WeatherSettingsFragment.java

+98-3
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,29 @@
1818

1919
package com.thanksmister.iot.mqtt.alarmpanel.ui.fragments;
2020

21+
import android.Manifest;
2122
import android.content.Context;
23+
import android.content.DialogInterface;
24+
import android.content.Intent;
2225
import android.content.SharedPreferences;
26+
import android.content.pm.PackageManager;
2327
import android.location.Criteria;
2428
import android.location.Location;
2529
import android.location.LocationListener;
2630
import android.location.LocationManager;
31+
import android.os.Build;
2732
import android.os.Bundle;
33+
import android.os.Handler;
34+
import android.support.annotation.NonNull;
35+
import android.support.v4.app.ActivityCompat;
36+
import android.support.v7.app.AlertDialog;
2837
import android.support.v7.preference.CheckBoxPreference;
2938
import android.support.v7.preference.EditTextPreference;
3039
import android.support.v7.preference.PreferenceFragmentCompat;
3140
import android.text.TextUtils;
41+
import android.view.Menu;
42+
import android.view.MenuInflater;
43+
import android.view.MenuItem;
3244
import android.view.View;
3345
import android.widget.Toast;
3446

@@ -44,6 +56,7 @@
4456
public class WeatherSettingsFragment extends PreferenceFragmentCompat
4557
implements SharedPreferences.OnSharedPreferenceChangeListener {
4658

59+
private static final int REQUEST_PERMISSIONS = 6;
4760
private static final long HOUR_MILLIS = 60 * 60 * 1000;
4861
private static final int METERS_MIN = 500;
4962

@@ -54,22 +67,42 @@ public class WeatherSettingsFragment extends PreferenceFragmentCompat
5467
private EditTextPreference weatherLongitude;
5568
private Configuration configuration;
5669
private LocationManager locationManager;
70+
private Handler locationHandler;
5771

5872
@Override
5973
public void onCreate(Bundle savedInstanceState) {
6074
super.onCreate(savedInstanceState);
75+
setHasOptionsMenu(true);
6176
addPreferencesFromResource(preferences_weather);
6277
}
6378

6479
@Override
6580
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
66-
81+
}
82+
83+
@Override
84+
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
85+
inflater.inflate(R.menu.search, menu);
86+
super.onCreateOptionsMenu(menu, inflater);
87+
}
88+
89+
@Override
90+
public boolean onOptionsItemSelected(MenuItem item) {
91+
switch (item.getItemId()) {
92+
case R.id.action_location:
93+
checkLocationEnabled();
94+
return true;
95+
}
96+
return false;
6797
}
6898

6999
@Override
70100
public void onResume() {
71101
super.onResume();
72102
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
103+
if(TextUtils.isEmpty(configuration.getLongitude()) || TextUtils.isEmpty(configuration.getLatitude()) ) {
104+
checkLocationEnabled(); // check that we have location permissions
105+
}
73106
}
74107

75108
@Override
@@ -81,6 +114,9 @@ public void onPause() {
81114
@Override
82115
public void onDestroyView() {
83116
super.onDestroyView();
117+
if(locationHandler != null) {
118+
locationHandler.removeCallbacks(locationRunnable);
119+
}
84120
}
85121

86122
@Override
@@ -128,6 +164,40 @@ public void onViewCreated(View view, Bundle savedInstanceState) {
128164
weatherLongitude.setEnabled(configuration.showWeatherModule());
129165
}
130166

167+
public void checkLocationEnabled() {
168+
if (isAdded() && getActivity() != null) {
169+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
170+
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
171+
&& ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
172+
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_PERMISSIONS);
173+
return;
174+
}
175+
}
176+
setUpLocationMonitoring();
177+
}
178+
}
179+
180+
@Override
181+
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
182+
switch (requestCode) {
183+
case REQUEST_PERMISSIONS: {
184+
if (grantResults.length > 0) {
185+
boolean permissionsDenied = false;
186+
for (int permission : grantResults) {
187+
if (permission != PackageManager.PERMISSION_GRANTED) {
188+
permissionsDenied = true;
189+
break;
190+
}
191+
}
192+
if (!permissionsDenied) {
193+
setUpLocationMonitoring();
194+
}
195+
}
196+
}
197+
}
198+
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
199+
}
200+
131201
@Override
132202
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
133203

@@ -179,19 +249,20 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
179249

180250
private void setUpLocationMonitoring() {
181251

252+
Timber.d("setUpLocationMonitoring");
182253
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
183-
184254
Criteria criteria = new Criteria();
185255
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
186256

187257
try {
188-
LocationListener locationListener = new LocationListener() {
258+
final LocationListener locationListener = new LocationListener() {
189259
@Override
190260
public void onLocationChanged(Location location) {
191261
if (location != null) {
192262
String latitude = String.valueOf(location.getLatitude());
193263
String longitude = String.valueOf(location.getLongitude());
194264
if(LocationUtils.coordinatesValid(latitude, longitude)){
265+
Timber.d("setUpLocationMonitoring complete");
195266
configuration.setLat(String.valueOf(location.getLatitude()));
196267
configuration.setLon(String.valueOf(location.getLongitude()));
197268
weatherLatitude.setSummary(String.valueOf(configuration.getLatitude()));
@@ -217,6 +288,8 @@ public void onProviderEnabled(String provider) {
217288
@Override
218289
public void onProviderDisabled(String provider) {
219290
Timber.d("onProviderDisabled");
291+
locationHandler = new Handler();
292+
locationHandler.postDelayed(locationRunnable, 500);
220293
}
221294
};
222295
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, HOUR_MILLIS, 0, locationListener);
@@ -225,4 +298,26 @@ public void onProviderDisabled(String provider) {
225298
Toast.makeText(getActivity(), R.string.toast_invalid_provider, Toast.LENGTH_SHORT).show();
226299
}
227300
}
301+
302+
private Runnable locationRunnable = new Runnable() {
303+
@Override
304+
public void run() {
305+
if (isAdded()) { // Without this in certain cases application will show ANR
306+
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
307+
builder.setMessage(R.string.string_location_services_disabled).setCancelable(false).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
308+
public void onClick(DialogInterface dialog, int id) {
309+
Intent gpsOptionsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
310+
startActivity(gpsOptionsIntent);
311+
}
312+
});
313+
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
314+
public void onClick(DialogInterface dialog, int id) {
315+
dialog.cancel();
316+
}
317+
});
318+
AlertDialog alert = builder.create();
319+
alert.show();
320+
}
321+
}
322+
};
228323
}

app/src/main/java/com/thanksmister/iot/mqtt/alarmpanel/ui/views/ExtendedForecastView.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import android.support.v7.widget.LinearLayoutManager;
2424
import android.support.v7.widget.RecyclerView;
2525
import android.util.AttributeSet;
26-
import android.widget.FrameLayout;
26+
import android.widget.LinearLayout;
2727

2828
import com.thanksmister.iot.mqtt.alarmpanel.R;
2929
import com.thanksmister.iot.mqtt.alarmpanel.network.model.Daily;
@@ -32,7 +32,7 @@
3232
import butterknife.Bind;
3333
import butterknife.ButterKnife;
3434

35-
public class ExtendedForecastView extends FrameLayout {
35+
public class ExtendedForecastView extends LinearLayout {
3636

3737
@Bind(R.id.recycleView)
3838
RecyclerView recycleView;
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)