Skip to content

Commit 8edee90

Browse files
author
davidgraeff
committed
Flash group in green color if activated: Sleep a few ms between udp packets
Fix: Don't show window on shortcut activation if not explicitly required Fix: Avoid flash while updaing outlet states in outletlist;
1 parent bf6100d commit 8edee90

File tree

12 files changed

+178
-92
lines changed

12 files changed

+178
-92
lines changed

AndroidManifest.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<activity
1616
android:name="oly.netpowerctrl.main.NetpowerctrlActivity"
1717
android:label="@string/app_name"
18+
android:launchMode="singleInstance"
1819
android:configChanges="keyboardHidden|orientation|screenSize"
1920
android:theme="@style/Theme.CustomLightTheme">
2021
<intent-filter>
@@ -48,7 +49,11 @@
4849
android:name="oly.netpowerctrl.service.ShortcutExecutionActivity"
4950
android:label="@string/app_name"
5051
android:icon="@drawable/netpowerctrl"
52+
android:theme="@style/Theme.Transparent"
5153
android:exported="true">
54+
<intent-filter>
55+
<action android:name="android.intent.action.MAIN"/>
56+
</intent-filter>
5257
</activity>
5358

5459
<activity android:name="oly.netpowerctrl.widget.WidgetConfig">

res/layout/shortcut_activity.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414

1515
</ListView>
1616

17+
<Switch
18+
android:id="@+id/shortcut_show_mainwindow"
19+
android:layout_width="match_parent"
20+
android:layout_height="wrap_content"
21+
android:layout_marginBottom="5dp"
22+
android:layout_marginTop="5dp"
23+
android:text="@string/shortcut_show_mainwindow" />
24+
25+
1726
<LinearLayout
1827
style="?android:attr/buttonBarStyle"
1928
android:layout_width="match_parent"

res/values-de/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979

8080
<string name="groupname">Gruppename</string>
8181
<string name="groupname_long">Bitte geben Sie einen neuen Gruppennamen ein</string>
82+
<string name="shortcut_show_mainwindow">Zeige Hauptfenster</string>
8283

8384
<string name="off">Aus</string>
8485
<string name="on">An</string>

res/values-en/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979

8080
<string name="groupname">Group name</string>
8181
<string name="groupname_long">Please enter a new group name</string>
82+
<string name="shortcut_show_mainwindow">Show mainwindow on execution</string>
8283

8384
<string name="off">Off</string>
8485
<string name="on">On</string>

res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979

8080
<string name="groupname">Group name</string>
8181
<string name="groupname_long">Please enter a new group name</string>
82+
<string name="shortcut_show_mainwindow">Show mainwindow on execution</string>
8283

8384
<string name="off">Off</string>
8485
<string name="on">On</string>

res/values/theme.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33
<style name="Theme.CustomLightTheme" parent="android:Theme.Light" />
4+
5+
<style name="Theme.Transparent" parent="android:Theme">
6+
<item name="android:windowIsTranslucent">true</item>
7+
<item name="android:windowBackground">@android:color/transparent</item>
8+
<item name="android:windowContentOverlay">@null</item>
9+
<item name="android:windowNoTitle">true</item>
10+
<item name="android:windowIsFloating">true</item>
11+
<item name="android:backgroundDimEnabled">false</item>
12+
</style>
413
</resources>
Lines changed: 5 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package oly.netpowerctrl.listadapter;
22

3-
import java.util.ArrayList;
43
import java.util.List;
5-
import java.util.Locale;
64
import java.util.UUID;
75

86
import oly.netpowerctrl.R;
@@ -15,34 +13,29 @@
1513
import android.view.View.OnClickListener;
1614
import android.view.ViewGroup;
1715
import android.widget.BaseAdapter;
18-
import android.widget.Filter;
19-
import android.widget.Filterable;
2016
import android.widget.ImageButton;
2117
import android.widget.TextView;
2218

23-
public class DeviceListAdapter extends BaseAdapter implements Filterable, OnClickListener {
19+
public class DeviceListAdapter extends BaseAdapter implements OnClickListener {
2420

2521
private DeviceConfigureEvent deviceConfigureEvent = null;
2622

2723
private List<DeviceInfo> all_devices;
28-
private List<DeviceInfo> visible_devices;
2924
private LayoutInflater inflater;
30-
private DeviceFilter filter = null;
3125
private Context context = null;
3226

3327
public DeviceListAdapter(Context context, List<DeviceInfo> devices) {
3428
this.context = context;
3529
inflater = LayoutInflater.from(context);
3630
all_devices = devices;
37-
visible_devices = new ArrayList<DeviceInfo>(devices);
3831
}
3932

4033
public int getCount() {
41-
return visible_devices.size();
34+
return all_devices.size();
4235
}
4336

4437
public Object getItem(int position) {
45-
return visible_devices.get(position);
38+
return all_devices.get(position);
4639
}
4740

4841
public long getItemId(int position) {
@@ -63,7 +56,7 @@ public View getView(int position, View convertView, ViewGroup parent) {
6356
if (convertView == null)
6457
convertView = inflater.inflate(R.layout.device_list_item, null);
6558

66-
DeviceInfo di = visible_devices.get(position);
59+
DeviceInfo di = all_devices.get(position);
6760
TextView tvName = (TextView) convertView.findViewById(R.id.device_name);
6861
tvName.setText(di.DeviceName);
6962

@@ -103,53 +96,8 @@ public void onClick(View v) {
10396
}
10497
}
10598

106-
107-
public Filter getFilter() {
108-
if (filter == null) {
109-
filter = new DeviceFilter();
110-
}
111-
return filter;
112-
}
113-
114-
private class DeviceFilter extends Filter
115-
{
116-
117-
@Override
118-
protected FilterResults performFiltering(CharSequence constraint) {
119-
FilterResults results = new FilterResults();
120-
ArrayList<DeviceInfo> list;
121-
122-
if (constraint == null || constraint.length() == 0) {
123-
list = new ArrayList<DeviceInfo>(all_devices);
124-
} else {
125-
list = new ArrayList<DeviceInfo>();
126-
String match = constraint.toString().toLowerCase(Locale.US);
127-
for (DeviceInfo item : all_devices) {
128-
if (item.DeviceName.toLowerCase(Locale.US).contains(match))
129-
list.add(item);
130-
}
131-
132-
}
133-
results.values = list;
134-
results.count = list.size();
135-
return results;
136-
}
137-
138-
@SuppressWarnings("unchecked")
139-
@Override
140-
protected void publishResults(CharSequence constraint, FilterResults results) {
141-
visible_devices = (List<DeviceInfo>)results.values;
142-
if (results.count > 0) {
143-
notifyDataSetChanged();
144-
} else {
145-
notifyDataSetInvalidated();
146-
}
147-
}
148-
149-
}
150-
15199
public void update() {
152-
getFilter().filter("");
100+
notifyDataSetChanged();
153101
}
154102

155103
}

src/oly/netpowerctrl/listadapter/GroupListAdapter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.ArrayList;
44

55
import oly.netpowerctrl.R;
6+
import oly.netpowerctrl.utils.GreenFlasher;
67
import oly.netpowerctrl.utils.OutletCommandGroup;
78
import oly.netpowerctrl.utils.SharedPrefs;
89
import oly.netpowerctrl.utils.UDPSendToDevice;
@@ -64,6 +65,7 @@ public long getItemId(int position) {
6465
@Override
6566
public void onClick(View v) {
6667
int position = (Integer) v.getTag();
68+
GreenFlasher.flashBgColor(v);
6769
OutletCommandGroup og = (OutletCommandGroup) getItem(position);
6870
UDPSendToDevice.sendOutlet(context, og);
6971
}

src/oly/netpowerctrl/main/NetpowerctrlActivity.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import android.content.IntentFilter;
3131
import android.os.Bundle;
3232
import android.support.v4.content.LocalBroadcastManager;
33+
import android.util.Log;
3334
import android.view.Menu;
3435
import android.view.MenuInflater;
3536
import android.view.MenuItem;
@@ -93,9 +94,49 @@ public void onCreate(Bundle savedInstanceState) {
9394
}
9495

9596
private void clearNonConfiguredDevices() {
96-
alDevices = SharedPrefs.ReadConfiguredDevices(this);
97-
adpDevices.setDevices(alDevices);
98-
adpOutlets.setDevices(alDevices);
97+
ArrayList<DeviceInfo> newEntries = SharedPrefs.ReadConfiguredDevices(this);
98+
// This is somehow a more complicated way of alDevices := newEntries
99+
// because with an assignment we would lose the outlet states which are not stored in the SharedPref
100+
// and only with the next UDP update those states are restored. This
101+
// induces a flicker where we can first observe all outlets set to off and
102+
// within a fraction of a second the actual values are applied.
103+
// Therefore we update by hand without touching outlet states.
104+
Iterator<DeviceInfo> oldEntriesIt = alDevices.iterator();
105+
while (oldEntriesIt.hasNext()) {
106+
// remove devices not existing anymore
107+
DeviceInfo old_di = oldEntriesIt.next();
108+
DeviceInfo new_di = null;
109+
for (int i=0;i<newEntries.size();++i) {
110+
if (newEntries.get(i).MacAddress.equals(old_di.MacAddress)) {
111+
new_di = newEntries.get(i);
112+
break;
113+
}
114+
}
115+
if (new_di == null) {
116+
oldEntriesIt.remove();
117+
} else if (old_di.Outlets.size() != new_di.Outlets.size()) {
118+
// Number of outlets have changed. This is a reason to forget about
119+
// outlet states and replace the old device with the new one.
120+
old_di = new_di;
121+
}
122+
}
123+
// add new devices
124+
Iterator<DeviceInfo> newEntriesIt = newEntries.iterator();
125+
while (newEntriesIt.hasNext()) {
126+
DeviceInfo new_di = newEntriesIt.next();
127+
DeviceInfo old_di = null;
128+
for (int i=0;i<alDevices.size();++i) {
129+
if (alDevices.get(i).MacAddress.equals(new_di.MacAddress)) {
130+
old_di = newEntries.get(i);
131+
break;
132+
}
133+
}
134+
if (old_di == null) {
135+
alDevices.add(new_di);
136+
}
137+
}
138+
adpDevices.update();
139+
adpOutlets.update();
99140
}
100141

101142
@Override
@@ -166,6 +207,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
166207
return true;
167208
} else if (th.getCurrentTabTag().equals("groups")) {
168209
Intent it = new Intent(this, ShortcutCreatorActivity.class);
210+
it.putExtra("groups", true);
169211
startActivityForResult(it, ACTIVITY_REQUEST_ADDGROUP);
170212
return true;
171213
}

src/oly/netpowerctrl/service/ShortcutCreatorActivity.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@
1616
import android.view.View;
1717
import android.widget.Button;
1818
import android.widget.ListView;
19+
import android.widget.Switch;
1920

2021
public class ShortcutCreatorActivity extends Activity
2122
{
2223
ArrayList<DeviceInfo> alDevices;
2324
OutledListAdapter adpOutlets;
2425
ListView lvOutletSelect;
26+
Switch show_mainwindow;
2527
final Activity that = this;
2628

2729
@Override
@@ -31,19 +33,31 @@ protected void onCreate(final Bundle savedInstanceState)
3133
setResult(RESULT_CANCELED,null);
3234
setContentView(R.layout.shortcut_activity);
3335
setTitle(R.string.choose_shortcut_outlets);
36+
37+
boolean isForGroups = false;
38+
Intent it = getIntent();
39+
if (it != null) {
40+
Bundle extra = it.getExtras();
41+
if (extra != null) {
42+
Object o = extra.get("groups");
43+
if (o != null) {
44+
isForGroups = (Boolean) o;
45+
}
46+
}
47+
}
3448

3549
alDevices = SharedPrefs.ReadConfiguredDevices(this);
3650
adpOutlets = new OutledListAdapter(this, alDevices);
51+
show_mainwindow = (Switch)findViewById(R.id.shortcut_show_mainwindow);
52+
if (isForGroups)
53+
show_mainwindow.setVisibility(View.GONE);
3754

3855
lvOutletSelect = (ListView)findViewById(R.id.lvOutletSelect);
3956
lvOutletSelect.setAdapter(adpOutlets);
4057

4158
((Button)findViewById(R.id.btnAcceptShortcut)).setOnClickListener(new View.OnClickListener() {
4259
@Override
4360
public void onClick(View v) {
44-
// Create shortcut intent
45-
Intent shortcutIntent=new Intent(that, oly.netpowerctrl.service.ShortcutExecutionActivity.class);
46-
4761
// Generate list of checked items
4862
List<OutletCommand> commands = adpOutlets.getCheckedItems();
4963
if (commands.isEmpty()) {
@@ -54,9 +68,20 @@ public void onClick(View v) {
5468
for (OutletCommand c: commands) {
5569
og.add(c);
5670
}
71+
72+
// Determine default name
5773
Calendar t = Calendar.getInstance();
5874
og.groupname = DateFormat.getMediumDateFormat(that).format(t.getTime()) + " - " + DateFormat.getTimeFormat(that).format(t.getTime());
75+
76+
// Create shortcut intent
77+
Intent shortcutIntent=new Intent(that, oly.netpowerctrl.service.ShortcutExecutionActivity.class);
5978
shortcutIntent.putExtra("commands", og.toString());
79+
shortcutIntent.setClass(that, oly.netpowerctrl.service.ShortcutExecutionActivity.class);
80+
shortcutIntent.setAction(Intent.ACTION_MAIN);
81+
82+
if (show_mainwindow.isChecked()) {
83+
shortcutIntent.putExtra("show_mainwindow", true);
84+
}
6085

6186
// Return result
6287
// Shortcut name is "app_name (9)" where 9 is the amount of commands

0 commit comments

Comments
 (0)