Repository: itsMelo/AndroidSocket
Branch: master
Commit: 525513e25e8c
Files: 50
Total size: 73.8 KB
Directory structure:
gitextract_wfs9muuq/
├── .gitignore
├── AppSocket/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── melo/
│ │ └── com/
│ │ └── androidsocket/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── melo/
│ │ │ └── com/
│ │ │ └── androidsocket/
│ │ │ ├── bean/
│ │ │ │ └── Users.java
│ │ │ ├── common/
│ │ │ │ └── Config.java
│ │ │ ├── listener/
│ │ │ │ ├── OnConnectionStateListener.java
│ │ │ │ └── OnMessageReceiveListener.java
│ │ │ ├── socket/
│ │ │ │ ├── SocketManager.java
│ │ │ │ ├── tcp/
│ │ │ │ │ └── TCPSocket.java
│ │ │ │ └── udp/
│ │ │ │ └── UDPSocket.java
│ │ │ └── utils/
│ │ │ ├── DeviceUtil.java
│ │ │ ├── HeartbeatTimer.java
│ │ │ └── WifiUtil.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── ic_launcher_background.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test/
│ └── java/
│ └── melo/
│ └── com/
│ └── androidsocket/
│ └── ExampleUnitTest.java
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── melo/
│ │ └── com/
│ │ └── app/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── melo/
│ │ │ └── com/
│ │ │ └── app/
│ │ │ └── MainActivity.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── ic_launcher_background.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ └── content_main.xml
│ │ ├── menu/
│ │ │ └── menu_main.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test/
│ └── java/
│ └── melo/
│ └── com/
│ └── app/
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
================================================
FILE: AppSocket/.gitignore
================================================
/build
================================================
FILE: AppSocket/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
}
================================================
FILE: AppSocket/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: AppSocket/src/androidTest/java/melo/com/androidsocket/ExampleInstrumentedTest.java
================================================
package melo.com.androidsocket;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see Testing documentation
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("melo.com.androidsocket", appContext.getPackageName());
}
}
================================================
FILE: AppSocket/src/main/AndroidManifest.xml
================================================
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/bean/Users.java
================================================
package melo.com.androidsocket.bean;
public class Users {
private int softVersion;
private int romVersion;
private String imei;
private String device;
private String ip;
private String loginTime;
public int getSoftVersion() {
return softVersion;
}
public void setSoftVersion(int softVersion) {
this.softVersion = softVersion;
}
public int getRomVersion() {
return romVersion;
}
public void setRomVersion(int romVersion) {
this.romVersion = romVersion;
}
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
public String getDevice() {
return device;
}
public void setDevice(String device) {
this.device = device;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getLoginTime() {
return loginTime;
}
public void setLoginTime(String loginTime) {
this.loginTime = loginTime;
}
}
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/common/Config.java
================================================
package melo.com.androidsocket.common;
/**
* Created by melo on 2017/11/27.
*/
public class Config {
public static final String MSG = "msg";
public static final String HEARTBREAK = "heartbreak";
public static final String PING = "ping";
public static final String TCP_IP = "ip";
public static final String TCP_PORT = "port";
// 单个CPU线程池大小
public static final int POOL_SIZE = 5;
/**
* 错误处理
*/
public static class ErrorCode {
public static final int CREATE_TCP_ERROR = 1;
public static final int PING_TCP_TIMEOUT = 2;
}
}
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/listener/OnConnectionStateListener.java
================================================
package melo.com.androidsocket.listener;
/**
* Created by melo on 2017/11/29.
*/
public interface OnConnectionStateListener {
void onSuccess();
void onFailed(int errorCode);
}
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/listener/OnMessageReceiveListener.java
================================================
package melo.com.androidsocket.listener;
/**
* Created by melo on 2017/11/27.
*/
public interface OnMessageReceiveListener {
void onMessageReceived(String message);
}
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/socket/SocketManager.java
================================================
package melo.com.androidsocket.socket;
import android.content.Context;
import android.text.TextUtils;
import org.json.JSONException;
import org.json.JSONObject;
import melo.com.androidsocket.common.Config;
import melo.com.androidsocket.listener.OnConnectionStateListener;
import melo.com.androidsocket.listener.OnMessageReceiveListener;
import melo.com.androidsocket.socket.tcp.TCPSocket;
import melo.com.androidsocket.socket.udp.UDPSocket;
/**
* Created by melo on 2017/11/27.
*/
public class SocketManager {
private static volatile SocketManager instance = null;
private UDPSocket udpSocket;
private TCPSocket tcpSocket;
private Context mContext;
private SocketManager(Context context) {
mContext = context.getApplicationContext();
}
public static SocketManager getInstance(Context context) {
// if already inited, no need to get lock everytime
if (instance == null) {
synchronized (SocketManager.class) {
if (instance == null) {
instance = new SocketManager(context);
}
}
}
return instance;
}
public void startUdpConnection() {
if (udpSocket == null) {
udpSocket = new UDPSocket(mContext);
}
// 注册接收消息的接口
udpSocket.addOnMessageReceiveListener(new OnMessageReceiveListener() {
@Override
public void onMessageReceived(String message) {
handleUdpMessage(message);
}
});
udpSocket.startUDPSocket();
}
/**
* 处理 udp 收到的消息
*
* @param message
*/
private void handleUdpMessage(String message) {
try {
JSONObject jsonObject = new JSONObject(message);
String ip = jsonObject.optString(Config.TCP_IP);
String port = jsonObject.optString(Config.TCP_PORT);
if (!TextUtils.isEmpty(ip) && !TextUtils.isEmpty(port)) {
startTcpConnection(ip, port);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* 开始 TCP 连接
*
* @param ip
* @param port
*/
private void startTcpConnection(String ip, String port) {
if (tcpSocket == null) {// 保证收到消息后,只创建一次
tcpSocket = new TCPSocket(mContext);
tcpSocket.startTcpSocket(ip, port);
tcpSocket.setOnConnectionStateListener(new OnConnectionStateListener() {
@Override
public void onSuccess() {// tcp 创建成功
udpSocket.stopHeartbeatTimer();
}
@Override
public void onFailed(int errorCode) {// tcp 异常处理
switch (errorCode) {
case Config.ErrorCode.CREATE_TCP_ERROR:
break;
case Config.ErrorCode.PING_TCP_TIMEOUT:
udpSocket.startHeartbeatTimer();
tcpSocket = null;
break;
}
}
});
}
}
public void stopSocket() {
udpSocket.stopUDPSocket();
tcpSocket.stopTcpConnection();
if (udpSocket != null) {
udpSocket = null;
}
if (tcpSocket != null) {
tcpSocket = null;
}
}
}
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/socket/tcp/TCPSocket.java
================================================
package melo.com.androidsocket.socket.tcp;
import android.content.Context;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import melo.com.androidsocket.common.Config;
import melo.com.androidsocket.listener.OnConnectionStateListener;
import melo.com.androidsocket.utils.HeartbeatTimer;
/**
* Created by melo on 2017/11/28.
*/
public class TCPSocket {
private static final String TAG = "TCPSocket";
private Context mContext;
private ExecutorService mThreadPool;
private Socket mSocket;
private BufferedReader br;
private PrintWriter pw;
private HeartbeatTimer timer;
private long lastReceiveTime = 0;
private OnConnectionStateListener mListener;
private static final long TIME_OUT = 15 * 1000;
private static final long HEARTBEAT_MESSAGE_DURATION = 2 * 1000;
public TCPSocket(Context context) {
this.mContext = context;
int cpuNumbers = Runtime.getRuntime().availableProcessors();
// 根据CPU数目初始化线程池
mThreadPool = Executors.newFixedThreadPool(cpuNumbers * Config.POOL_SIZE);
// 记录创建对象时的时间
lastReceiveTime = System.currentTimeMillis();
}
public void startTcpSocket(final String ip, final String port) {
mThreadPool.execute(new Runnable() {
@Override
public void run() {
if (startTcpConnection(ip, Integer.valueOf(port))) {// 尝试建立 TCP 连接
if (mListener != null) {
mListener.onSuccess();
}
startReceiveTcpThread();
startHeartbeatTimer();
} else {
if (mListener != null) {
mListener.onFailed(Config.ErrorCode.CREATE_TCP_ERROR);
}
}
}
});
}
public void setOnConnectionStateListener(OnConnectionStateListener listener) {
this.mListener = listener;
}
/**
* 创建接收线程
*/
private void startReceiveTcpThread() {
mThreadPool.execute(new Runnable() {
@Override
public void run() {
String line = "";
try {
while ((line = br.readLine()) != null) {
handleReceiveTcpMessage(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
/**
* 处理 tcp 收到的消息
*
* @param line
*/
private void handleReceiveTcpMessage(String line) {
Log.d(TAG, "接收 tcp 消息:" + line);
lastReceiveTime = System.currentTimeMillis();
}
private void sendTcpMessage(String json) {
pw.println(json);
Log.d(TAG, "tcp 消息发送成功...");
}
/**
* 启动心跳
*/
private void startHeartbeatTimer() {
if (timer == null) {
timer = new HeartbeatTimer();
}
timer.setOnScheduleListener(new HeartbeatTimer.OnScheduleListener() {
@Override
public void onSchedule() {
Log.d(TAG, "timer is onSchedule...");
long duration = System.currentTimeMillis() - lastReceiveTime;
Log.d(TAG, "duration:" + duration);
if (duration > TIME_OUT) {//若超过十五秒都没收到我的心跳包,则认为对方不在线。
Log.d(TAG, "tcp ping 超时,对方已经下线");
stopTcpConnection();
if (mListener != null) {
mListener.onFailed(Config.ErrorCode.PING_TCP_TIMEOUT);
}
} else if (duration > HEARTBEAT_MESSAGE_DURATION) {//若超过两秒他没收到我的心跳包,则重新发一个。
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put(Config.MSG, Config.PING);
} catch (JSONException e) {
e.printStackTrace();
}
sendTcpMessage(jsonObject.toString());
}
}
});
timer.startTimer(0, 1000 * 2);
}
public void stopHeartbeatTimer() {
if (timer != null) {
timer.exit();
timer = null;
}
}
/**
* 尝试建立tcp连接
*
* @param ip
* @param port
*/
private boolean startTcpConnection(final String ip, final int port) {
try {
if (mSocket == null) {
mSocket = new Socket(ip, port);
mSocket.setKeepAlive(true);
mSocket.setTcpNoDelay(true);
mSocket.setReuseAddress(true);
}
InputStream is = mSocket.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
OutputStream os = mSocket.getOutputStream();
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os)), true);
Log.d(TAG, "tcp 创建成功...");
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public void stopTcpConnection() {
try {
stopHeartbeatTimer();
if (br != null) {
br.close();
}
if (pw != null) {
pw.close();
}
if (mThreadPool != null) {
mThreadPool.shutdown();
mThreadPool = null;
}
if (mSocket != null) {
mSocket.close();
mSocket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/socket/udp/UDPSocket.java
================================================
package melo.com.androidsocket.socket.udp;
import android.content.Context;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import melo.com.androidsocket.bean.Users;
import melo.com.androidsocket.common.Config;
import melo.com.androidsocket.listener.OnMessageReceiveListener;
import melo.com.androidsocket.utils.DeviceUtil;
import melo.com.androidsocket.utils.HeartbeatTimer;
import melo.com.androidsocket.utils.WifiUtil;
/**
* Created by melo on 2017/9/20.
*/
public class UDPSocket {
private static final String TAG = "UDPSocket";
private static final int BUFFER_LENGTH = 1024;
private byte[] receiveByte = new byte[BUFFER_LENGTH];
private static String BROADCAST_IP = "192.168.43.255";
// 端口号,飞鸽协议默认端口2425
public static final int CLIENT_PORT = 2425;
private boolean isThreadRunning = false;
private Context mContext;
private DatagramSocket client;
private DatagramPacket receivePacket;
private long lastReceiveTime = 0;
private static final long TIME_OUT = 120 * 1000;
private static final long HEARTBEAT_MESSAGE_DURATION = 5 * 1000;
private ExecutorService mThreadPool;
private Thread clientThread;
private HeartbeatTimer timer;
private Users localUser;
private Users remoteUser;
private final List messageReceiveList;
public UDPSocket(Context context) {
this.mContext = context;
int cpuNumbers = Runtime.getRuntime().availableProcessors();
// 根据CPU数目初始化线程池
mThreadPool = Executors.newFixedThreadPool(cpuNumbers * Config.POOL_SIZE);
// 记录创建对象时的时间
lastReceiveTime = System.currentTimeMillis();
messageReceiveList = new ArrayList<>();
Log.d(TAG, "创建 UDP 对象");
// createUser();
}
public void addOnMessageReceiveListener(OnMessageReceiveListener listener) {
messageReceiveList.add(listener);
}
/**
* 创建本地用户信息
*/
private void createUser() {
if (localUser == null) {
localUser = new Users();
}
if (remoteUser == null) {
remoteUser = new Users();
}
localUser.setImei(DeviceUtil.getDeviceId(mContext));
localUser.setSoftVersion(DeviceUtil.getPackageVersionCode(mContext));
if (WifiUtil.getInstance(mContext).isWifiApEnabled()) {// 判断当前是否是开启热点方
localUser.setIp("192.168.43.1");
} else {// 当前是开启 wifi 方
localUser.setIp(WifiUtil.getInstance(mContext).getLocalIPAddress());
remoteUser.setIp(WifiUtil.getInstance(mContext).getServerIPAddress());
}
}
public void startUDPSocket() {
if (client != null) return;
try {
// 表明这个 Socket 在设置的端口上监听数据。
client = new DatagramSocket(CLIENT_PORT);
client.setReuseAddress(true);
if (receivePacket == null) {
// 创建接受数据的 packet
receivePacket = new DatagramPacket(receiveByte, BUFFER_LENGTH);
}
startSocketThread();
} catch (SocketException e) {
e.printStackTrace();
}
}
/**
* 开启接收数据的线程
*/
private void startSocketThread() {
clientThread = new Thread(new Runnable() {
@Override
public void run() {
receiveMessage();
}
});
isThreadRunning = true;
clientThread.start();
Log.d(TAG, "开启 UDP 数据接收线程");
startHeartbeatTimer();
}
/**
* 处理接受到的消息
*/
private void receiveMessage() {
while (isThreadRunning) {
try {
if (client != null) {
client.receive(receivePacket);
}
lastReceiveTime = System.currentTimeMillis();
Log.d(TAG, "receive packet success...");
} catch (IOException e) {
Log.e(TAG, "UDP数据包接收失败!线程停止");
stopUDPSocket();
e.printStackTrace();
return;
}
if (receivePacket == null || receivePacket.getLength() == 0) {
Log.e(TAG, "无法接收UDP数据或者接收到的UDP数据为空");
continue;
}
String strReceive = new String(receivePacket.getData(), receivePacket.getOffset(), receivePacket.getLength());
Log.d(TAG, strReceive + " from " + receivePacket.getAddress().getHostAddress() + ":" + receivePacket.getPort());
//解析接收到的 json 信息
notifyMessageReceive(strReceive);
// 每次接收完UDP数据后,重置长度。否则可能会导致下次收到数据包被截断。
if (receivePacket != null) {
receivePacket.setLength(BUFFER_LENGTH);
}
}
}
/**
* 将消息通过接口发送到每个页面
*
* @param strReceive
*/
private void notifyMessageReceive(String strReceive) {
for (OnMessageReceiveListener listener : messageReceiveList) {
if (listener != null) {
listener.onMessageReceived(strReceive);
}
}
}
public void stopUDPSocket() {
isThreadRunning = false;
receivePacket = null;
stopHeartbeatTimer();
if (clientThread != null) {
clientThread.interrupt();
}
if (mThreadPool != null) {
mThreadPool.shutdown();
}
if (client != null) {
client.close();
client = null;
}
if (timer != null) {
timer.exit();
}
}
/**
* 启动心跳,timer 间隔十秒
*/
public void startHeartbeatTimer() {
if (timer == null) {
timer = new HeartbeatTimer();
}
timer.setOnScheduleListener(new HeartbeatTimer.OnScheduleListener() {
@Override
public void onSchedule() {
Log.d(TAG, "timer is onSchedule...");
long duration = System.currentTimeMillis() - lastReceiveTime;
Log.d(TAG, "duration:" + duration);
if (duration > TIME_OUT) {//若超过两分钟都没收到我的心跳包,则认为对方不在线。
Log.d(TAG, "超时,对方已经下线");
// 刷新时间,重新进入下一个心跳周期
lastReceiveTime = System.currentTimeMillis();
} else if (duration > HEARTBEAT_MESSAGE_DURATION) {//若超过十秒他没收到我的心跳包,则重新发一个。
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put(Config.MSG, Config.HEARTBREAK);
} catch (JSONException e) {
e.printStackTrace();
}
sendMessage(jsonObject.toString());
}
}
});
timer.startTimer(0, 1000 * 5);
}
public void stopHeartbeatTimer() {
if (timer != null) {
timer.exit();
timer = null;
}
}
/**
* 发送心跳包
*
* @param message
*/
public void sendMessage(final String message) {
mThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
BROADCAST_IP = WifiUtil.getBroadcastAddress();
Log.d(TAG, "BROADCAST_IP:" + BROADCAST_IP);
InetAddress targetAddress = InetAddress.getByName(BROADCAST_IP);
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.length(), targetAddress, CLIENT_PORT);
client.send(packet);
// 数据发送事件
Log.d(TAG, "数据发送成功");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/utils/DeviceUtil.java
================================================
package melo.com.androidsocket.utils;
import android.app.Service;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.PowerManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
/**
* 获取设备的信息
*
* @author melo
*/
public final class DeviceUtil {
/**
*
IMEI.
Returns the unique device ID, for example, the IMEI for GSM and the MEID
* or ESN for CDMA phones. Return null if device ID is not available.
*
* Requires Permission: READ_PHONE_STATE
*
* @param context
* @return
*/
public synchronized static String getDeviceId(Context context) {
if (context == null) {
return "";
}
String imei = "";
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (tm == null || TextUtils.isEmpty(tm.getDeviceId())) {
// 双卡双待需要通过phone1和phone2获取imei,默认取phone1的imei。
tm = (TelephonyManager) context.getSystemService("phone1");
}
if (tm != null) {
imei = tm.getDeviceId();
}
} catch (SecurityException e) {
e.printStackTrace();
}
return imei;
}
/**
* Returns the serial number of the SIM, if applicable. Return null if it is
* unavailable.
*
* Requires Permission: READ_PHONE_STATE
*
* @param context
* @return
*/
public synchronized static String getSimSerialNumber(Context context) {
if (context == null) {
return "";
}
final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.getSimSerialNumber();
}
/**
* A 64-bit number (as a hex string) that is randomly generated on the
* device's first boot and should remain constant for the lifetime of the
* device. (The value may change if a factory reset is performed on the
* device.)
*
* @param context
* @return
*/
public synchronized static String getAndroidID(Context context) {
return Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ANDROID_ID);
}
/**
* 操作系统版本
*
* @return
*/
public static String getOSversion() {
return android.os.Build.VERSION.RELEASE;
}
/**
* 设备商
*
* @return
*/
public static String getManufacturer() {
return android.os.Build.MANUFACTURER;
}
/**
* 设备型号
*
* @return
*/
public static String getModel() {
return android.os.Build.MODEL;
}
/**
* 序列号
*
* @return
*/
public static String getSerialNumber() {
String serial = null;
try {
Class> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
} catch (Exception ignored) {
}
return serial;
}
/**
* SD CARD ID
*
* @return
*/
public static synchronized String getSDcardID() {
try {
String sdCid = null;
String[] memBlkArray = new String[]{"/sys/block/mmcblk0", "/sys/block/mmcblk1", "/sys/block/mmcblk2"};
for (String memBlk : memBlkArray) {
File file = new File(memBlk);
if (file.exists() && file.isDirectory()) {
Process cmd = Runtime.getRuntime().exec("cat " + memBlk + "/device/cid");
BufferedReader br = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
sdCid = br.readLine();
if (!TextUtils.isEmpty(sdCid)) {
return sdCid;
}
}
}
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
/**
* 获取mac地址
*
* @param context
* @return
*/
public static String getMac(Context context) {
if (context == null) {
return "";
}
String mac = null;
try {
final WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (wifi != null) {
WifiInfo info = wifi.getConnectionInfo();
if (null != info && info.getMacAddress() != null) {
mac = info.getMacAddress();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return mac;
}
/**
* 获取mac地址
* 可以突破android6.0的限制
*
* @return
*/
public static String getWifiMacAddress() {
try {
String interfaceName = "wlan0";
List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
if (!intf.getName().equalsIgnoreCase(interfaceName)) {
continue;
}
byte[] mac = intf.getHardwareAddress();
if (mac == null) {
return "";
}
StringBuilder buf = new StringBuilder();
for (byte aMac : mac) {
buf.append(String.format("%02X:", aMac));
}
if (buf.length() > 0) {
buf.deleteCharAt(buf.length() - 1);
}
return buf.toString();
}
} catch (Exception ex) {
} // for now eat exceptions
return "";
}
/**
* 获取IMSI
*
* @param context
* @return
*/
public static String getIMSI(Context context) {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
return tm.getSubscriberId();
}
/**
* get sim serial number
*/
public static String getSimSerialNum(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
return tm.getSimSerialNumber();
}
/**
* 获取屏幕的分辨率
*
* @param context
* @return int array with 2 items. The first item is width, and the second is height.
*/
public static int[] getScreenResolution(Context context) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
int[] resolution = new int[2];
resolution[0] = dm.widthPixels;
resolution[1] = dm.heightPixels;
return resolution;
}
/**
* 获取WIFI的Mac地址
*
* @param context
* @return Wifi的BSSID即mac地址
*/
public static String getWifiBSSID(Context context) {
if (context == null) {
return null;
}
String mac = null;
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wm.getConnectionInfo();
if (info != null) {
mac = info.getBSSID();// 获得本机的MAC地址
}
return mac;
}
public static String getPackageVersion(Context context) {
PackageManager packageManager = context.getPackageManager();
PackageInfo packInfo;
try {
packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
return packInfo.versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
public static int getPackageVersionCode(Context context) {
PackageManager packageManager = context.getPackageManager();
PackageInfo packInfo;
try {
packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
return packInfo.versionCode;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return 0;
}
/**
* 获取系统休眠时间。
*
* @return
*/
public static int getScreenOffTimeOut(Context context) {
int sleepTime;
try {
sleepTime = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT);
} catch (SettingNotFoundException e) {
e.printStackTrace();
sleepTime = 15 * 1000;
}
return sleepTime;
}
public static boolean isScreenOn(Context context) {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
return powerManager.isScreenOn();
}
/**
* Gets the number of cores available in this device, across all processors.
* Requires: Ability to peruse the filesystem at "/sys/devices/system/cpu"
*
* @return The number of cores, or 1 if failed to get result
*/
public static int getCPUNumCores() {
try {
//Get directory containing CPU info
File dir = new File("/sys/devices/system/cpu/");
//Filter to only list the devices we care about
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
//Check if filename is "cpu", followed by a single digit number
if (Pattern.matches("cpu[0-9]", pathname.getName())) {
return true;
}
return false;
}
});
//Return the number of cores (virtual CPU devices)
return files.length;
} catch (Exception e) {
return 1;
}
}
/**
* 获取系统参数
*
* @param configName
* @return
*/
public static String getSystemConf(String configName) {
try {
Process process = Runtime.getRuntime().exec("getprop " + configName);
InputStreamReader ir = new InputStreamReader(process.getInputStream());
BufferedReader input = new BufferedReader(ir);
String value = input.readLine();
input.close();
ir.close();
process.destroy();
return value;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 获取硬件版本
*
* @return
*/
public static String getHardwareVersion() {
return getSystemConf("ro.hardware");
}
/**
* 获取rom版本
*/
public static String getRomVersion() {
return getSystemConf("ro.mediatek.version.release");
}
/**
* 获取hq rom版本
*/
private static String gethqRomVersion() {
return getSystemConf("ro.huaqin.version.release");
}
public static String getShowhqRomVersion() {
String showHq = "hq";
String hqRomVer = gethqRomVersion();
if (TextUtils.isEmpty(hqRomVer) == false) {
String[] s = hqRomVer.split("_");
if (s != null && s.length >= 3) {
showHq = s[2];
}
}
return showHq;
}
/**
* 获取installed apk版本
*/
public static PackageInfo getInstalledAppInfo(Context context, String pname) {
try {
List packages = context.getPackageManager().getInstalledPackages(0);
if (packages != null) {
for (PackageInfo pinfo : packages) {
if (pinfo != null && pinfo.packageName.equals(pname)) {
return pinfo;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/utils/HeartbeatTimer.java
================================================
package melo.com.androidsocket.utils;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by melo on 2017/9/21.
*/
public class HeartbeatTimer {
private Timer timer;
private TimerTask task;
private OnScheduleListener mListener;
public HeartbeatTimer() {
timer = new Timer();
}
public void startTimer(long delay, long period) {
task = new TimerTask() {
@Override
public void run() {
if (mListener != null) {
mListener.onSchedule();
}
}
};
timer.schedule(task, delay, period);
}
public void exit() {
if (task != null) {
task.cancel();
}
if (timer != null) {
timer.cancel();
}
}
public interface OnScheduleListener {
void onSchedule();
}
public void setOnScheduleListener(OnScheduleListener listener) {
this.mListener = listener;
}
}
================================================
FILE: AppSocket/src/main/java/melo/com/androidsocket/utils/WifiUtil.java
================================================
package melo.com.androidsocket.utils;
import android.content.Context;
import android.net.DhcpInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
/**
* Created by melo on 2017/9/23.
*/
public class WifiUtil {
private static final String TAG = "LocationUtils";
private static volatile WifiUtil instance = null;
private WifiManager mWifiManager;
private Context mContext;
private WifiUtil(Context context) {
mContext = context;
mWifiManager = (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
}
public static WifiUtil getInstance(Context context) {
if (instance == null) {
synchronized (WifiUtil.class) {
if (instance == null) {
instance = new WifiUtil(context);
}
}
}
return instance;
}
public boolean isWifiApEnabled() {
try {
Method method = mWifiManager.getClass().getMethod("isWifiApEnabled");
method.setAccessible(true);
return (Boolean) method.invoke(mWifiManager);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public String getLocalIPAddress() {
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
return intToIp(wifiInfo.getIpAddress());
}
public String getServerIPAddress() {
DhcpInfo mDhcpInfo = mWifiManager.getDhcpInfo();
return intToIp(mDhcpInfo.gateway);
}
private static String intToIp(int i) {
return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF) + "."
+ ((i >> 24) & 0xFF);
}
/**
* @return 优先获取网卡地址
*/
public static String getBroadcastAddress() {
String broadcast = getBroadcastAddress("p2p");
if (broadcast == null) {
return getBroadcastAddress("wlan0");
}
return broadcast;
}
/**
* @param netCardName 网卡名称
* @return 获取的广播地址
*/
public static String getBroadcastAddress(String netCardName) {
try {
Enumeration eni = NetworkInterface
.getNetworkInterfaces();
while (eni.hasMoreElements()) {
NetworkInterface networkCard = eni.nextElement();
if (networkCard.getDisplayName().startsWith(netCardName)) {
List ncAddrList = networkCard
.getInterfaceAddresses();
Iterator ncAddrIterator = ncAddrList.iterator();
while (ncAddrIterator.hasNext()) {
InterfaceAddress networkCardAddress = ncAddrIterator.next();
InetAddress address = networkCardAddress.getAddress();
if (!address.isLoopbackAddress()) {
String hostAddress = address.getHostAddress();
if (hostAddress.indexOf(":") > 0) {
// case : ipv6
continue;
} else {
// case : ipv4
String broadcastAddress = networkCardAddress.getBroadcast().getHostAddress();
return broadcastAddress;
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
================================================
FILE: AppSocket/src/main/res/drawable/ic_launcher_background.xml
================================================
================================================
FILE: AppSocket/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
================================================
FILE: AppSocket/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
================================================
FILE: AppSocket/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
================================================
FILE: AppSocket/src/main/res/values/colors.xml
================================================
#3F51B5#303F9F#FF4081
================================================
FILE: AppSocket/src/main/res/values/strings.xml
================================================
AndroidSocket
================================================
FILE: AppSocket/src/main/res/values/styles.xml
================================================
================================================
FILE: AppSocket/src/test/java/melo/com/androidsocket/ExampleUnitTest.java
================================================
package melo.com.androidsocket;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see Testing documentation
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: README.md
================================================
# AndroidSocket
项目介绍地址:
http://www.jianshu.com/p/61de9478c9aa
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "melo.com.app"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation project(':AppSocket')
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: app/src/androidTest/java/melo/com/app/ExampleInstrumentedTest.java
================================================
package melo.com.app;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see Testing documentation
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("melo.com.app", appContext.getPackageName());
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
================================================
FILE: app/src/main/java/melo/com/app/MainActivity.java
================================================
package melo.com.app;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import melo.com.androidsocket.socket.SocketManager;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.fab)
FloatingActionButton fab;
private SocketManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
manager = SocketManager.getInstance(this);
manager.startUdpConnection();
}
@OnClick(R.id.fab)
public void onViewClicked() {
}
@Override
protected void onDestroy() {
super.onDestroy();
manager.stopSocket();
}
}
================================================
FILE: app/src/main/res/drawable/ic_launcher_background.xml
================================================
================================================
FILE: app/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
================================================
FILE: app/src/main/res/layout/content_main.xml
================================================
================================================
FILE: app/src/main/res/menu/menu_main.xml
================================================
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
================================================
FILE: app/src/main/res/values/colors.xml
================================================
#3F51B5#303F9F#FF4081
================================================
FILE: app/src/main/res/values/dimens.xml
================================================
16dp
================================================
FILE: app/src/main/res/values/strings.xml
================================================
AppSettings
================================================
FILE: app/src/main/res/values/styles.xml
================================================
================================================
FILE: app/src/test/java/melo/com/app/ExampleUnitTest.java
================================================
package melo.com.app;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see Testing documentation
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
// ButterKnife
classpath 'com.jakewharton:butterknife-gradle-plugin:8.5.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Nov 27 10:59:32 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: settings.gradle
================================================
include ':AppSocket', ':app'