Skip to content

Commit 2e7fd29

Browse files
author
davidgraeff
committed
Crash fix, Optimization, Smoothness
* Drag & Drop of Scenes and Outlets in ListViews (not Gridviews atm) * Polished UI, more feedback, wifi state changes, Reachability * Fix: 8th Outlet can be toggled in scenes now * Plugins: Find by Broadcast
1 parent 2389d10 commit 2e7fd29

File tree

69 files changed

+1938
-919
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1938
-919
lines changed

.idea/workspace.xml

Lines changed: 362 additions & 530 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<uses-permission android:name="android.permission.NFC" />
1414
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
1515
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
16+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1617
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
1718

1819
<permission

app/src/main/java/oly/netpowerctrl/anelservice/DeviceQuery.java

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
import java.net.DatagramPacket;
77
import java.net.DatagramSocket;
88
import java.net.InetAddress;
9+
import java.net.InterfaceAddress;
10+
import java.net.NetworkInterface;
11+
import java.net.SocketException;
12+
import java.nio.ByteBuffer;
913
import java.util.ArrayList;
1014
import java.util.Collection;
15+
import java.util.Enumeration;
1116
import java.util.Iterator;
1217

1318
import oly.netpowerctrl.R;
@@ -31,25 +36,30 @@ public class DeviceQuery {
3136
public void run() {
3237
for (DeviceInfo di : devices_to_observe)
3338
target.onDeviceTimeout(di);
34-
freeSelf();
39+
target.onDeviceQueryFinished(devices_to_observe.size());
40+
NetpowerctrlApplication.instance.removeUpdateDeviceState(DeviceQuery.this);
3541
}
3642
};
3743

38-
public DeviceQuery(Context context, DeviceUpdateStateOrTimeout target, DeviceInfo device_to_observe) {
44+
public DeviceQuery(Context context, DeviceUpdateStateOrTimeout target, DeviceInfo device_to_observe, boolean rangeCheck) {
3945
this.target = target;
4046
this.devices_to_observe = new ArrayList<DeviceInfo>();
4147
devices_to_observe.add(device_to_observe);
4248

4349
// Register on main application object to receive device updates
4450
NetpowerctrlApplication.instance.addUpdateDeviceState(this);
4551

46-
timeoutHandler.postDelayed(timeoutRunnable, 1200);
52+
4753
// Send out broadcast
48-
sendQuery(context, device_to_observe.HostName, device_to_observe.SendPort);
54+
if (!sendQuery(context, device_to_observe.HostName, device_to_observe.SendPort, rangeCheck)) {
55+
// Device not in range, immediately timeout
56+
timeoutHandler.postDelayed(timeoutRunnable, 0);
57+
} else
58+
timeoutHandler.postDelayed(timeoutRunnable, 1200);
4959
}
5060

5161
public DeviceQuery(Context context, DeviceUpdateStateOrTimeout target,
52-
Collection<DeviceInfo> devices_to_observe, boolean queryForNewDevices) {
62+
Collection<DeviceInfo> devices_to_observe, boolean queryForNewDevices, boolean rangeCheck) {
5363
this.target = target;
5464
this.devices_to_observe = new ArrayList<DeviceInfo>(devices_to_observe);
5565

@@ -63,10 +73,16 @@ public DeviceQuery(Context context, DeviceUpdateStateOrTimeout target,
6373
sendBroadcastQuery(context);
6474
else
6575
for (DeviceInfo di : devices_to_observe)
66-
sendQuery(context, di.HostName, di.SendPort);
76+
sendQuery(context, di.HostName, di.SendPort, rangeCheck);
6777
}
6878

69-
public void notifyAndRemove(DeviceInfo received_data) {
79+
/**
80+
* Return true if all devices responded and this DeviceQuery object
81+
* have to be removed.
82+
*
83+
* @param received_data
84+
*/
85+
public boolean notifyObservers(DeviceInfo received_data) {
7086
Iterator<DeviceInfo> it = devices_to_observe.iterator();
7187
while (it.hasNext()) {
7288
DeviceInfo device_to_observe = it.next();
@@ -77,13 +93,10 @@ public void notifyAndRemove(DeviceInfo received_data) {
7793
}
7894
if (devices_to_observe.isEmpty()) {
7995
timeoutHandler.removeCallbacks(timeoutRunnable);
80-
freeSelf();
96+
target.onDeviceQueryFinished(devices_to_observe.size());
97+
return true;
8198
}
82-
}
83-
84-
private void freeSelf() {
85-
target.onDeviceQueryFinished(devices_to_observe.size());
86-
NetpowerctrlApplication.instance.removeUpdateDeviceState(this);
99+
return false;
87100
}
88101

89102
/**
@@ -94,10 +107,21 @@ private void freeSelf() {
94107
* @param device_command
95108
*/
96109
static void sendQuery(final Context context, DeviceCommand device_command) {
97-
sendQuery(context, device_command.dest.getHostAddress(), device_command.port);
110+
sendQuery(context, device_command.dest.getHostAddress(), device_command.port, false);
98111
}
99112

100-
private static void sendQuery(final Context context, final String hostname, final int port) {
113+
private static boolean sendQuery(final Context context, final String hostname, final int port, boolean rangeCheck) {
114+
if (rangeCheck) {
115+
try {
116+
if (!isIPinNetworkAddressPool(InetAddress.getByName(hostname))) {
117+
ShowToast.FromOtherThread(context, context.getResources().getString(R.string.error_not_in_range) + ": " + hostname);
118+
return false;
119+
}
120+
} catch (final Exception e) {
121+
ShowToast.FromOtherThread(context, context.getResources().getString(R.string.error_not_in_range) + ": " + hostname);
122+
return false;
123+
}
124+
}
101125
new Thread(new Runnable() {
102126
public void run() {
103127
try {
@@ -115,10 +139,35 @@ public void run() {
115139
}
116140
}
117141
}).start();
142+
return true;
118143
}
119144

120145
private static void sendBroadcastQuery(final Context context) {
121146
for (int port : NetpowerctrlApplication.instance.getAllSendPorts())
122-
sendQuery(context, "255.255.255.255", port);
147+
sendQuery(context, "255.255.255.255", port, false);
148+
}
149+
150+
static private boolean isIPinNetworkAddressPool(InetAddress ip) throws SocketException {
151+
byte[] ipAddressBytes = ip.getAddress();
152+
// Iterate all NICs (network interface cards)...
153+
for (Enumeration networkInterfaceEnumerator = NetworkInterface.getNetworkInterfaces(); networkInterfaceEnumerator.hasMoreElements(); ) {
154+
NetworkInterface networkInterface = (NetworkInterface) networkInterfaceEnumerator.nextElement();
155+
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
156+
InetAddress interfaceIPAddress = interfaceAddress.getAddress();
157+
byte[] interfaceIPBytes = interfaceIPAddress.getAddress();
158+
if (ipAddressBytes.length != interfaceIPBytes.length)
159+
continue; // different ip versions
160+
161+
byte[] subNetMaskBytes = ByteBuffer.allocate(4).putInt(interfaceAddress.getNetworkPrefixLength()).array();
162+
// check each byte of both addresses while applying the subNet mask
163+
for (int i = 0; i < interfaceIPBytes.length; ++i) {
164+
if ((ipAddressBytes[i] & subNetMaskBytes[i]) !=
165+
(interfaceIPBytes[i] & subNetMaskBytes[i]))
166+
continue; // byte not identical, the ip is not for this network interface
167+
}
168+
return true;
169+
}
170+
}
171+
return false;
123172
}
124173
}

app/src/main/java/oly/netpowerctrl/anelservice/DiscoveryThread.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ void parsePacket(final String message, int receive_port) {
7373
di.HostName = msg[2];
7474
di.MacAddress = msg[5];
7575
di.ReceivePort = receive_port;
76+
di.reachable = true;
7677

7778
int disabledOutlets = 0;
7879
int numOutlets = 8; // normally, the device sends info for 8 outlets no matter how many are actually equipped

app/src/main/java/oly/netpowerctrl/datastructure/DeviceCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public DeviceCommand(DeviceInfo di) {
4343
}
4444

4545
public boolean getIsOn(int outletNumber) {
46-
return ((data & ((byte) (1 << outletNumber - 1))) > 0);
46+
return ((data & ((byte) (1 << (outletNumber - 1)))) != 0);
4747
}
4848

4949
private void switchOn(int outletNumber) {
@@ -55,7 +55,7 @@ private void switchOff(int outletNumber) {
5555
}
5656

5757
private void toggle(int outletNumber) {
58-
if ((data & ((byte) (1 << outletNumber - 1))) > 0) {
58+
if (getIsOn(outletNumber)) {
5959
switchOff(outletNumber);
6060
} else {
6161
switchOn(outletNumber);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package oly.netpowerctrl.dragdrop;
2+
3+
public interface DragDropEnabled {
4+
void setDragDropEnabled(boolean d);
5+
6+
boolean isDragDropEnabled();
7+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (C) 2010 Eric Harlow
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package oly.netpowerctrl.dragdrop;
18+
19+
import android.view.View;
20+
21+
/**
22+
* Implement to handle an item being dragged.
23+
*
24+
* @author Eric Harlow
25+
*/
26+
public interface DragListener {
27+
/**
28+
* Called when a drag starts.
29+
*
30+
* @param itemView - the view of the item to be dragged i.e. the drag view
31+
*/
32+
void onStartDrag(View itemView);
33+
34+
/**
35+
* Called when a drag stops.
36+
* Any changes in onStartDrag need to be undone here
37+
* so that the view can be used in the list again.
38+
*
39+
* @param itemView - the view of the item to be dragged i.e. the drag view
40+
*/
41+
void onStopDrag(View itemView);
42+
}

0 commit comments

Comments
 (0)