我写了一个Android应用程序,它使我可以通过局域网内的wifi启动和关闭车库中的服务器。
局域网唤醒功能与运行Android 7.0(牛轧糖)的旧三星Galaxy A5完美配合,现在,运行Android 8.0(奥利奥)的Samsung Galaxy A6 +不再运行。
我已经用运行Android 9.0(Pie)的Samsung Galaxy S9对它进行了不成功的测试。
尽管使用JSch的shutdown now
仍然运行良好。
我从http://www.jibble.org/wake-on-lan/那里获得了Java Wake on Lan的代码
OLD Wakeup.java
:
package ch.serversquare.archcontrolmobile.archcontrolmobile;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Wakeup {
private String MAC;
private String IPBroad;
public Wakeup() {
}
public String getMAC() {
return MAC;
}
public String getIPBorad() {
return IPBroad;
}
public static final int PORT = 9;
public void wakeup(String MAC, String IPBroad) {
this.IPBroad = IPBroad;
this.MAC = MAC;
try {
byte[] macBytes = getMacBytes(MAC);
byte[] bytes = new byte[6 + 16 * macBytes.length];
for(int i = 0; i < 6; i++) {
bytes[i] = (byte) 0xff;
}
for(int i = 6; i < bytes.length; i+= macBytes.length) {
System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
}
InetAddress address = InetAddress.getByName(IPBroad);
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, PORT);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] getMacBytes(String macStr) throws IllegalArgumentException {
byte[] bytes = new byte[6];
String[] hex = macStr.split("(\\:|\\-)");
if(hex.length != 6) {
throw new IllegalArgumentException("Invalid MAC address.");
}
try {
for(int i = 0; i<6;i++) {
bytes[i] = (byte) Integer.parseInt(hex[i], 16);
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid hex digit in MAC address.");
}
return bytes;
}
}
在我的MainActivity
内看起来像这样:
package ch.serversquare.archcontrolmobile.archcontrolmobile;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(isWiifConnected(MainActivity.this) == true) {
setContentView(R.layout.activity_main);
final Button btnWakeup = (findViewById(R.id.btnWakeup));
final Button btnShutdown = (findViewById(R.id.btnShutdown));
final TextView count = (findViewById(R.id.count));
final TextView status = (findViewById(R.id.status));
checkConnToServer(status, btnWakeup, btnShutdown);
btnWakeup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(v == btnWakeup) {
Wakeup wol = new Wakeup();
wol.wakeup("00:0b:0e:0f:00:ed", "192.168.200.255");
btnWakeup.setEnabled(false);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
btnShutdown.setEnabled(true);
checkConnToServer(status, btnWakeup, btnShutdown);
}
}, 60000);
new CountDownTimer(60000, 1000) {
public void onTick(long millisUntilFinished) {
count.setText("Shutdown available in: " + millisUntilFinished / 1000);
}
public void onFinish() {
count.setText("");
}
}.start();
}
}
});
(这不是整个MainActivity
。它只是从顶部到唤醒按钮。)
您可能会问是否有任何错误。 简单的问题,简单的答案:不,没有。
如果有错误,我会在这里寻找答案,而不是在这里问:D
您中的某些人可能会对我的AndroidManifest
中的内容感兴趣。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.co.serversquare.archcontrolmobile.archcontrolmobile">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity" android:configChanges="orientation" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".About" android:configChanges="orientation" android:screenOrientation="portrait"></activity>
</application>
(只需稍微清理一下,ACCESS_NETWORK_STATE
,ACCESS_WIFI_STATE
,CHANGE_WIFI_STATE
在这里检查是否启用并连接了wifi,如果没有启用,则会弹出一个对话框,说您应该激活wifi。但这对这个问题并不重要。)
我希望有人可以帮助我解决这个问题。 (对不起,我的英语知识很差:D)
如果缺少任何重要信息,请回答此主题,我将使用所需信息编辑该主题。
编辑:
编辑过的Wakeup.java
package uk.co.serversquare.archcontrolmobile.archcontrolmobile;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import android.os.Handler;
public class Wakeup {
private String MAC;
private String IPBroad;
public Wakeup() {
}
public String getMAC() {
return MAC;
}
public String getIPBorad() {
return IPBroad;
}
public static final int PORT = 9;
public void wakeup(String MAC, String IPBroad) {
this.IPBroad = IPBroad;
this.MAC = MAC;
try {
byte[] macBytes = getMacBytes(MAC);
byte[] bytes = new byte[6 + 16 * macBytes.length];
for(int i = 0; i < 6; i++) {
bytes[i] = (byte) 0xff;
}
for(int i = 6; i < bytes.length; i+= macBytes.length) {
System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
}
InetAddress address = InetAddress.getByName(IPBroad);
final DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, PORT);
final DatagramSocket socket = new DatagramSocket();
for(int i = 0; i<3;i++) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try {
socket.send(packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 300);
}
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] getMacBytes(String macStr) throws IllegalArgumentException {
byte[] bytes = new byte[6];
String[] hex = macStr.split("(\\:|\\-)");
if(hex.length != 6) {
throw new IllegalArgumentException("Invalid MAC address.");
}
try {
for(int i = 0; i<6;i++) {
bytes[i] = (byte) Integer.parseInt(hex[i], 16);
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid hex digit in MAC address.");
}
return bytes;
}
}
编辑,共1/3/19
再次编辑Wakeup.java
package uk.co.serversquare.archcontrolmobile.archcontrolmobile;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import android.os.Handler;
public class Wakeup {
private String MAC;
private String IPBroad;
public Wakeup() {
}
public String getMAC() {
return MAC;
}
public String getIPBorad() {
return IPBroad;
}
public static final int PORT = 9;
public void wakeup(String MAC, String IPBroad) {
this.IPBroad = IPBroad;
this.MAC = MAC;
try {
byte[] macBytes = getMacBytes(MAC);
byte[] bytes = new byte[6 + 16 * macBytes.length];
for(int i = 0; i < 6; i++) {
bytes[i] = (byte) 0xff;
}
for(int i = 6; i < bytes.length; i+= macBytes.length) {
System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
}
InetAddress address = InetAddress.getByName(IPBroad);
final DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, PORT);
final DatagramSocket socket = new DatagramSocket();
socket.send(packet); //directly
for(int i = 0; i<2;i++) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try {
socket.send(packet); //after 300 & 600 ms
} catch (Exception e) {
e.printStackTrace();
}
}
}, 300);
}
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try {
socket.send(packet); //afer 1000ms (1s)
} catch (Exception e) {
e.printStackTrace();
}
}
}, 1000);
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] getMacBytes(String macStr) throws IllegalArgumentException {
byte[] bytes = new byte[6];
String[] hex = macStr.split("(\\:|\\-)");
if(hex.length != 6) {
throw new IllegalArgumentException("Invalid MAC address.");
}
try {
for(int i = 0; i<6;i++) {
bytes[i] = (byte) Integer.parseInt(hex[i], 16);
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid hex digit in MAC address.");
}
return bytes;
}
}