diff --git a/app/build.gradle b/app/build.gradle index ab97dd6b..14478670 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,12 @@ android { } ndkVersion '25.1.8937393' + + packagingOptions { + exclude 'META-INF/INDEX.LIST' + exclude 'META-INF/io.netty.versions.properties' + exclude 'META-INF/DEPENDENCIES' + } } dependencies { @@ -66,6 +72,7 @@ dependencies { // implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' +// implementation 'androidx.camera:camera-video:1.2.3' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' @@ -76,5 +83,8 @@ dependencies { // implementation project(path: ':opencv') implementation files('libs/devapi.aar') - +// implementation group: 'io.netty', name: 'netty-all', version: '4.1.96.Final' +// implementation 'io.netty:netty-all:4.1.23.Final' +// implementation 'org.apache.logging.log4j:log4j-api:2.14.0' +// implementation 'org.apache.logging.log4j:log4j-core:2.14.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index eb66fe2b..bc51bfd4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,7 +9,6 @@ - @@ -34,6 +33,7 @@ + {@code false}: 否 + */ + public static boolean isGpsEnabled(Context context) { + LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + return lm.isProviderEnabled(LocationManager.GPS_PROVIDER); + } + + /** + * 判断定位是否可用 + * + * @return {@code true}: 是
{@code false}: 否 + */ + public static boolean isLocationEnabled(Context context) { + LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + return lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER) || lm.isProviderEnabled(LocationManager.GPS_PROVIDER); + } + + /** + * 打开Gps设置界面 + */ + public static void openGpsSettings(Context context) { + Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + + /** + * 注册 + *

使用完记得调用{@link #unregister()}

+ *

需添加权限 {@code }

+ *

需添加权限 {@code }

+ *

需添加权限 {@code }

+ *

如果{@code minDistance}为0,则通过{@code minTime}来定时更新;

+ *

{@code minDistance}不为0,则以{@code minDistance}为准;

+ *

两者都为0,则随时刷新。

+ * + * @param minTime 位置信息更新周期(单位:毫秒) + * @param minDistance 位置变化最小距离:当位置距离变化超过此值时,将更新位置信息(单位:米) + * @param listener 位置刷新的回调接口 + * @return {@code true}: 初始化成功
{@code false}: 初始化失败 + */ + public static boolean register(Context context, long minTime, long minDistance, OnLocationChangeListener listener) { + if (listener == null) return false; + mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + mListener = listener; + if (!isLocationEnabled(context)) { + Toast.makeText(context, "无法定位,请打开定位服务", Toast.LENGTH_SHORT).show(); + return false; + } + String provider = mLocationManager.getBestProvider(getCriteria(), true); + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return false; + } + Location location = mLocationManager.getLastKnownLocation(provider); + + if (location != null) listener.getLastKnownLocation(location); + if (myLocationListener == null) myLocationListener = new MyLocationListener(); + mLocationManager.requestLocationUpdates(provider, minTime, minDistance, myLocationListener); + return true; + } + + + /** + * 注销 + */ + public static void unregister() { + if (mLocationManager != null) { + if (myLocationListener != null) { + mLocationManager.removeUpdates(myLocationListener); + myLocationListener = null; + } + mLocationManager = null; + } + } + + /** + * 设置定位参数 + * + * @return {@link Criteria} + */ + private static Criteria getCriteria() { + Criteria criteria = new Criteria(); + //设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细 + criteria.setAccuracy(Criteria.ACCURACY_FINE); + //设置是否要求速度 + criteria.setSpeedRequired(false); + // 设置是否允许运营商收费 + criteria.setCostAllowed(false); + //设置是否需要方位信息 + criteria.setBearingRequired(false); + //设置是否需要海拔信息 + criteria.setAltitudeRequired(false); + // 设置对电源的需求 + criteria.setPowerRequirement(Criteria.POWER_LOW); + return criteria; + } + + /** + * 根据经纬度获取地理位置 + * + * @param context 上下文 + * @param latitude 纬度 + * @param longitude 经度 + * @return {@link Address} + */ + public static Address getAddress(Context context, double latitude, double longitude) { + Geocoder geocoder = new Geocoder(context, Locale.getDefault()); + try { + List
addresses = geocoder.getFromLocation(latitude, longitude, 1); + if (addresses.size() > 0) return addresses.get(0); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 根据经纬度获取所在国家 + * + * @param context 上下文 + * @param latitude 纬度 + * @param longitude 经度 + * @return 所在国家 + */ + public static String getCountryName(Context context, double latitude, double longitude) { + Address address = getAddress(context, latitude, longitude); + return address == null ? "unknown" : address.getCountryName(); + } + + /** + * 根据经纬度获取所在地 + * + * @param context 上下文 + * @param latitude 纬度 + * @param longitude 经度 + * @return 所在地 + */ + public static String getLocality(Context context, double latitude, double longitude) { + Address address = getAddress(context, latitude, longitude); + return address == null ? "unknown" : address.getLocality(); + } + + /** + * 根据经纬度获取所在街道 + * + * @param context 上下文 + * @param latitude 纬度 + * @param longitude 经度 + * @return 所在街道 + */ + public static String getStreet(Context context, double latitude, double longitude) { + Address address = getAddress(context, latitude, longitude); + return address == null ? "unknown" : address.getAddressLine(0); + } + + private static class MyLocationListener implements LocationListener { + /** + * 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 + * + * @param location 坐标 + */ + @Override + public void onLocationChanged(Location location) { + if (mListener != null) { + mListener.onLocationChanged(location); + } + } + + /** + * provider的在可用、暂时不可用和无服务三个状态直接切换时触发此函数 + * + * @param provider 提供者 + * @param status 状态 + * @param extras provider可选包 + */ + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + if (mListener != null) { + mListener.onStatusChanged(provider, status, extras); + } + switch (status) { + case LocationProvider.AVAILABLE: + Log.e("onStatusChanged", "当前GPS状态为可见状态"); + break; + case LocationProvider.OUT_OF_SERVICE: + Log.e("onStatusChanged", "当前GPS状态为服务区外状态"); + break; + case LocationProvider.TEMPORARILY_UNAVAILABLE: + Log.e("onStatusChanged", "当前GPS状态为暂停服务状态"); + break; + } + } + + /** + * provider被enable时触发此函数,比如GPS被打开 + */ + @Override + public void onProviderEnabled(String provider) { + System.out.println("dsaf"); + } + + /** + * provider被disable时触发此函数,比如GPS被关闭 + */ + @Override + public void onProviderDisabled(String provider) { + System.out.println("dsaf"); + } + } + + public interface OnLocationChangeListener { + + /** + * 获取最后一次保留的坐标 + * + * @param location 坐标 + */ + void getLastKnownLocation(Location location); + + /** + * 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 + * + * @param location 坐标 + */ + void onLocationChanged(Location location); + + /** + * provider的在可用、暂时不可用和无服务三个状态直接切换时触发此函数 + * + * @param provider 提供者 + * @param status 状态 + * @param extras provider可选包 + */ + void onStatusChanged(String provider, int status, Bundle extras);//位置状态发生改变 + } +} diff --git a/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java b/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java index 19e0e831..98279642 100644 --- a/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java +++ b/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java @@ -8,6 +8,10 @@ import android.content.pm.PackageManager; import android.graphics.Path; import android.graphics.SurfaceTexture; import android.hardware.Camera; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.media.MediaRecorder; import android.os.Build; import android.os.Environment; import android.os.Handler; @@ -25,9 +29,12 @@ import android.util.Log; import android.view.Display; import android.view.View; import android.view.WindowManager; +import android.widget.Toast; import com.dowse.camera.client.DSCameraManager; import com.xinyingpower.microphoto.databinding.ActivityMainBinding; +//import com.xinyingpower.microphoto.request.INettyMessageListener; +//import com.xinyingpower.microphoto.request.NettyChatClient; import java.io.BufferedReader; import java.io.File; @@ -55,18 +62,22 @@ public class MainActivity extends AppCompatActivity { static { System.loadLibrary("microphoto"); } + private ActivityMainBinding binding; private int defaultDataSubId; + @Override protected void onDestroy() { super.onDestroy(); } + protected class AppConfig { public String cmdid; public String server; public int port; public int protocol; } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -95,14 +106,9 @@ public class MainActivity extends AppCompatActivity { @Override public void onClick(View view) { - String[] accessPermissions = new String[]{ - Manifest.permission.CAMERA, - Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.FOREGROUND_SERVICE, - Manifest.permission.READ_PHONE_STATE, + String[] accessPermissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.FOREGROUND_SERVICE, Manifest.permission.READ_PHONE_STATE, /*Manifest.permission.PACKAGE_USAGE_STATS,*/ - /*Manifest.permission.SET_TIME,*/ - }; + /*Manifest.permission.SET_TIME,*/}; boolean needRequire = false; for (String access : accessPermissions) { int curPermission = ActivityCompat.checkSelfPermission(MainActivity.this, access); @@ -112,10 +118,7 @@ public class MainActivity extends AppCompatActivity { } } if (needRequire) { - ActivityCompat.requestPermissions( - MainActivity.this, - accessPermissions, - MY_PERMISSIONS_REQUEST_FOREGROUND_SERVICE); + ActivityCompat.requestPermissions(MainActivity.this, accessPermissions, MY_PERMISSIONS_REQUEST_FOREGROUND_SERVICE); return; } @@ -212,6 +215,51 @@ public class MainActivity extends AppCompatActivity { } }); + binding.gps.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// gpsTake(); + startLocate(); +// LocationUtils.unregister(); + } + }); + + + binding.netgps.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// startLocate(); + boolean gpsEnabled = LocationUtils.isGpsEnabled(MainActivity.this); + System.out.printf("g" + gpsEnabled); + LocationUtils.register(MainActivity.this, 0, 0, new LocationUtils.OnLocationChangeListener() { + @Override + public void getLastKnownLocation(Location location) { + Log.e("xyh", "onLocationChanged: " + location.getLatitude()); + } + + @Override + public void onLocationChanged(Location location) { + //位置信息变化时触发 + Log.e("xyh", "定位方式:" + location.getProvider()); + Log.e("xyh", "纬度:" + location.getLatitude()); + Log.e("xyh", "经度:" + location.getLongitude()); + Log.e("xyh", "海拔:" + location.getAltitude()); + Log.e("xyh", "时间:" + location.getTime()); + Log.e("xyh", "国家:" + LocationUtils.getCountryName(MainActivity.this, location.getLatitude(), location.getLongitude())); + Log.e("xyh", "获取地理位置:" + LocationUtils.getAddress(MainActivity.this, location.getLatitude(), location.getLongitude())); + Log.e("xyh", "所在地:" + LocationUtils.getLocality(MainActivity.this, location.getLatitude(), location.getLongitude())); + Log.e("xyh", "所在街道:" + LocationUtils.getStreet(MainActivity.this, location.getLatitude(), location.getLongitude())); + + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + System.out.println("dfsad"); + } + }); + } + }); + if (!TextUtils.isEmpty(appConfig.cmdid) && !TextUtils.isEmpty(appConfig.server) && appConfig.port != 0) { Handler handler = new Handler(); Runnable runnable = new Runnable() { @@ -225,6 +273,63 @@ public class MainActivity extends AppCompatActivity { handler.postDelayed(runnable, 5000); } + binding.tcpudp.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// initSocket(); + } + }); + binding.tcpudpsend.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// byte[] bytes = {(byte) 0xA5, 0x5A, 0x04, 0x00, 0x58, 0x59, 0x49, 0x47, 0x51, 0x31, 0x30, 0x44, 0x32, 0x32, 0x31, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x07, (byte) 0xE7, 0x37, (byte) 0x86, (byte) 0x96, (byte) 0xD4, 0x64, (byte) 0xB5, (byte) 0xFB, (byte) 0x96}; + byte[] bytes = {(byte) 0xA5, 0x5A, 0x04, 0x00, 0x58, 0x59, 0x49, 0x47, 0x51, 0x31, 0x30, 0x44, 0x32, 0x32, 0x31, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x07, (byte) 0xE6, (byte) 0xEA, 0x52, (byte) 0xB7, (byte) 0xD4, 0x64, 0x5C, 0x7E, (byte) 0x96}; +// NettyChatClient.getInstance().sendByteMessage(bytes); + + } + }); + + binding.video.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +//方法1 + +// mediaRecorder = new MediaRecorder(); +// +// //设置视频和音频的来源 +// mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); +// mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); +// // +// mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); +// //设置录制视频的编码格式 +// mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); +// //设置音频的编码格式 +// mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB); +// //设置视频的帧率:每秒切换图片的次数 +// mediaRecorder.setVideoFrameRate(20); +// //视频的分辨率 +// mediaRecorder.setVideoSize(176, 144); +// +//// mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface()); +// +// mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/111.mp4"); +// try { +// mediaRecorder.prepare(); +// } catch (Exception e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// mediaRecorder.start(); + + } + }); + binding.video2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { +// mediaRecorder.stop(); + } + }); + } private void setDefaultDataSubId(int subId) { @@ -252,7 +357,7 @@ public class MainActivity extends AppCompatActivity { BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String line; StringBuilder stringBuilder = new StringBuilder(); - while((line = bufferedReader.readLine()) != null) { + while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line); } bufferedReader.close(); @@ -268,8 +373,7 @@ public class MainActivity extends AppCompatActivity { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); - } - finally { + } finally { if (inputStreamReader != null) { try { inputStreamReader.close(); @@ -303,8 +407,7 @@ public class MainActivity extends AppCompatActivity { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); - } - finally { + } finally { if (outputStreamWriter != null) { try { outputStreamWriter.close(); @@ -447,4 +550,123 @@ public class MainActivity extends AppCompatActivity { public native String stringFromJNI(); public native boolean takePhoto(int channel, int preset, String path, String fileName); + + + private void gpsTake() { + LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + +// 注册位置监听器 + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); + Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + if (lastKnownLocation != null) { + double latitude = lastKnownLocation.getLatitude(); + double longitude = lastKnownLocation.getLongitude(); + // 处理最新位置信息 + System.out.printf("gps" + latitude + "fds:" + longitude); + } + } + + LocationListener locationListener = new LocationListener() { + @Override + public void onLocationChanged(Location location) { + // 处理位置更新事件 + double latitude = location.getLatitude(); + double longitude = location.getLongitude(); + // ... + + Log.e("xyh", "定位方式:" + location.getProvider()); + Log.e("xyh", "纬度:" + location.getLatitude()); + Log.e("xyh", "经度:" + location.getLongitude()); + Log.e("xyh", "海拔:" + location.getAltitude()); + Log.e("xyh", "时间:" + location.getTime()); + Log.e("xyh", "国家:" + LocationUtils.getCountryName(MainActivity.this, location.getLatitude(), location.getLongitude())); + Log.e("xyh", "获取地理位置:" + LocationUtils.getAddress(MainActivity.this, location.getLatitude(), location.getLongitude())); + Log.e("xyh", "所在地:" + LocationUtils.getLocality(MainActivity.this, location.getLatitude(), location.getLongitude())); + Log.e("xyh", "所在街道:" + LocationUtils.getStreet(MainActivity.this, location.getLatitude(), location.getLongitude())); + + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + // 处理位置状态变化事件 + System.out.printf("fsdaf"); + } + + @Override + public void onProviderEnabled(String provider) { + // 处理位置提供者启用事件 + System.out.printf("fsdaf"); + } + + @Override + public void onProviderDisabled(String provider) { + + // 处理位置提供者禁用事件 + System.out.printf("fsdaf"); + } + }; + + + private void startLocate() { + LocationManager mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + boolean providerEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + if (providerEnabled) { //GPS已开启 + /** + * 绑定监听 + * 参数1,设备:有GPS_PROVIDER和NETWORK_PROVIDER两种,前者是GPS,后者是GPRS以及WIFI定位 + * 参数2,位置信息更新周期.单位是毫秒 + * 参数3,位置变化最小距离:当位置距离变化超过此值时,将更新位置信息 + * 参数4,监听 + * 备注:参数2和3,如果参数3不为0,则以参数3为准;参数3为0,则通过时间来定时更新;两者为0,则随时刷新 + */ + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return; + } + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); + } else { + Toast.makeText(this, "请打开GPS", Toast.LENGTH_SHORT).show(); + } + } + +// private void initSocket() { +// NettyChatClient nettyChatClient = NettyChatClient.newInstance("47.96.238.157", 6891); +//// NettyChatClient nettyChatClient = NettyChatClient.newInstance("180.166.218.222", 40032); +// nettyChatClient.init(new INettyMessageListener() { +// @Override +// public void onReceive(String message) { +//// for (INettyMessageListener nettyMessageListener : mIMessageListenerList) { +//// nettyMessageListener.onReceive(message); +//// } +// System.out.println("dsfa"); +// } +// +// @Override +// public void onConnectSuccess() { +//// for (INettyMessageListener nettyMessageListener : mIMessageListenerList) { +//// nettyMessageListener.onConnectSuccess(); +//// } +// System.out.println("dsfa"); +// } +// +// @Override +// public void onError() { +//// for (INettyMessageListener nettyMessageListener : mIMessageListenerList) { +//// nettyMessageListener.onError(); +//// } +// System.out.println("dsfa"); +// } +// }); +// nettyChatClient.connect(); +// } + } \ No newline at end of file diff --git a/app/src/main/java/com/xinyingpower/microphoto/request/ExponentialBackOffRetry.java b/app/src/main/java/com/xinyingpower/microphoto/request/ExponentialBackOffRetry.java new file mode 100644 index 00000000..e9084895 --- /dev/null +++ b/app/src/main/java/com/xinyingpower/microphoto/request/ExponentialBackOffRetry.java @@ -0,0 +1,52 @@ +//package com.xinyingpower.microphoto.request; +// +//import java.util.Random; +// +///** +// *

Retry policy that retries a set number of times with increasing sleep time between retries

+// */ +//public class ExponentialBackOffRetry implements RetryPolicy { +// +// private static final int MAX_RETRIES_LIMIT = 29; +// private static final int DEFAULT_MAX_SLEEP_MS = Integer.MAX_VALUE; +// +// private final Random random = new Random(); +// private final long baseSleepTimeMs; +// private final int maxRetries; +// private final int maxSleepMs; +// +// public ExponentialBackOffRetry(int baseSleepTimeMs, int maxRetries) { +// this(baseSleepTimeMs, maxRetries, DEFAULT_MAX_SLEEP_MS); +// } +// +// public ExponentialBackOffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs) { +// this.maxRetries = maxRetries; +// this.baseSleepTimeMs = baseSleepTimeMs; +// this.maxSleepMs = maxSleepMs; +// } +// +// @Override +// public boolean allowRetry(int retryCount) { +// if (retryCount < maxRetries) { +// return true; +// } +// return false; +// } +// +// @Override +// public long getSleepTimeMs(int retryCount) { +// if (retryCount < 0) { +// throw new IllegalArgumentException("retries count must greater than 0."); +// } +// if (retryCount > MAX_RETRIES_LIMIT) { +//// LogUtil.e(String.format("maxRetries too large (%d). Pinning to %d", maxRetries, MAX_RETRIES_LIMIT)); +// retryCount = MAX_RETRIES_LIMIT; +// } +// long sleepMs = baseSleepTimeMs * Math.max(1, random.nextInt(1 << retryCount)); +// if (sleepMs > maxSleepMs) { +//// LogUtil.e(String.format("Sleep extension too large (%d). Pinning to %d", sleepMs, maxSleepMs)); +// sleepMs = maxSleepMs; +// } +// return sleepMs; +// } +//} diff --git a/app/src/main/java/com/xinyingpower/microphoto/request/INettyMessageListener.java b/app/src/main/java/com/xinyingpower/microphoto/request/INettyMessageListener.java new file mode 100644 index 00000000..1fb65f2f --- /dev/null +++ b/app/src/main/java/com/xinyingpower/microphoto/request/INettyMessageListener.java @@ -0,0 +1,9 @@ +//package com.xinyingpower.microphoto.request; +// +//public interface INettyMessageListener { +// void onReceive(String message); +// +// void onConnectSuccess(); +// +// void onError(); +//} \ No newline at end of file diff --git a/app/src/main/java/com/xinyingpower/microphoto/request/NettyChatClient.java b/app/src/main/java/com/xinyingpower/microphoto/request/NettyChatClient.java new file mode 100644 index 00000000..3c67a632 --- /dev/null +++ b/app/src/main/java/com/xinyingpower/microphoto/request/NettyChatClient.java @@ -0,0 +1,116 @@ +//package com.xinyingpower.microphoto.request; +// +//import java.nio.charset.StandardCharsets; +//import java.util.concurrent.TimeUnit; +// +//import io.netty.bootstrap.Bootstrap; +//import io.netty.buffer.ByteBuf; +//import io.netty.buffer.Unpooled; +//import io.netty.channel.Channel; +//import io.netty.channel.ChannelFuture; +//import io.netty.channel.ChannelFutureListener; +//import io.netty.channel.ChannelInitializer; +//import io.netty.channel.ChannelOption; +//import io.netty.channel.ChannelPipeline; +//import io.netty.channel.EventLoopGroup; +//import io.netty.channel.nio.NioEventLoopGroup; +//import io.netty.channel.socket.SocketChannel; +//import io.netty.channel.socket.nio.NioSocketChannel; +//import io.netty.handler.codec.bytes.ByteArrayDecoder; +//import io.netty.handler.codec.bytes.ByteArrayEncoder; +//import io.netty.handler.codec.string.StringDecoder; +//import io.netty.handler.codec.string.StringEncoder; +//import io.netty.handler.timeout.IdleStateHandler; +// +//public class NettyChatClient { +// private static NettyChatClient mNettyChatClient; +// private static String mServerIp; +// private static int mPort; +// private Channel mChannel; +// /** +// * 重连策略 +// */ +// private RetryPolicy mRetryPolicy; +// private Bootstrap mBootstrap; +// +// public void init(INettyMessageListener messageListener) { +// mRetryPolicy = new ExponentialBackOffRetry(3000, Integer.MAX_VALUE, 3 * 1000); +// EventLoopGroup group = new NioEventLoopGroup();//初始化线程组 +// // bootstrap 可重用, 只需在TcpClient实例化的时候初始化即可. +// mBootstrap = new Bootstrap(); +// mBootstrap.group(group) +// .option(ChannelOption.TCP_NODELAY, true) +// .channel(NioSocketChannel.class) +// .handler(new ClientHandlersInitializer()); +// +// } +// +// public static NettyChatClient newInstance(String serverIp, int port) { +// if (mNettyChatClient == null) { +// mNettyChatClient = new NettyChatClient(); +// mServerIp = serverIp; +// mPort = port; +// } +// return mNettyChatClient; +// } +// +// public static NettyChatClient getInstance() { +// return mNettyChatClient; +// } +// +// /** +// * 向远程TCP服务器请求连接 +// */ +// public void connect() { +// synchronized (mBootstrap) { +// ChannelFuture future = mBootstrap.connect(mServerIp, mPort); +// future.addListener(getConnectionListener()); +// this.mChannel = future.channel(); +// } +// } +// +// private ChannelFutureListener getConnectionListener() { +// return future -> { +// if (!future.isSuccess()) { +// future.channel().pipeline().fireChannelInactive(); +// } +// }; +// } +// +// private class ClientHandlersInitializer extends ChannelInitializer { +// +// @Override +// protected void initChannel(SocketChannel ch) { +// ChannelPipeline pipeline = ch.pipeline(); +// pipeline.addLast(new ByteArrayDecoder()); +// pipeline.addLast(new ByteArrayEncoder()); +// pipeline.addLast(new IdleStateHandler(100, 100, 0, TimeUnit.SECONDS)); +// pipeline.addLast(new ReconnectHandler(mNettyChatClient)); +// } +// +// } +// +// +// public RetryPolicy getRetryPolicy() { +// return mRetryPolicy; +// } +// +// public void sendMessage(String content) { +// if (mChannel != null) { +// mChannel.writeAndFlush(content); +// } +// } +// +// public void sendByteMessage(byte[] content) { +// ByteBuf bb = Unpooled.wrappedBuffer((content)); +// if (mChannel != null) { +// mChannel.writeAndFlush(bb).addListener(new ChannelFutureListener() { +// @Override +// public void operationComplete(ChannelFuture future) throws Exception { +// System.out.println("dfsa"); +// } +// }); +// } +// } +//} +// diff --git a/app/src/main/java/com/xinyingpower/microphoto/request/ReconnectHandler.java b/app/src/main/java/com/xinyingpower/microphoto/request/ReconnectHandler.java new file mode 100644 index 00000000..f79a65b9 --- /dev/null +++ b/app/src/main/java/com/xinyingpower/microphoto/request/ReconnectHandler.java @@ -0,0 +1,165 @@ +//package com.xinyingpower.microphoto.request; +// +//import android.annotation.SuppressLint; +// +//import com.dowse.base.log.ByteTools; +// +//import java.io.ByteArrayOutputStream; +//import java.io.IOException; +//import java.io.ObjectOutputStream; +//import java.util.concurrent.TimeUnit; +// +//import io.netty.buffer.ByteBuf; +//import io.netty.buffer.Unpooled; +//import io.netty.channel.ChannelHandler; +//import io.netty.channel.ChannelHandlerContext; +//import io.netty.channel.EventLoop; +//import io.netty.channel.SimpleChannelInboundHandler; +//import io.netty.channel.socket.DatagramPacket; +//import io.netty.handler.codec.MessageToByteEncoder; +//import io.netty.handler.timeout.IdleStateEvent; +// +//@ChannelHandler.Sharable +//public class ReconnectHandler extends SimpleChannelInboundHandler { +// private int retries = 0; +// private RetryPolicy mRetryPolicy; +// private NettyChatClient mNettyChatClient; +// +// public ReconnectHandler(NettyChatClient nettyChatClient) { +// this.mNettyChatClient = nettyChatClient; +// } +// +// @Override +// public void channelActive(ChannelHandlerContext ctx) throws Exception { +//// LogUtil.e("Successfully established a connection to the server."); +// retries = 0; +// ctx.fireChannelActive(); +// } +// +// @SuppressLint("DefaultLocale") +// @Override +// public void channelInactive(ChannelHandlerContext ctx) throws Exception { +// if (retries == 0) { +//// LogUtil.e("Lost the TCP connection with the server."); +// ctx.close(); +// } +// boolean allowRetry = getRetryPolicy().allowRetry(retries); +// if (allowRetry) { +// long sleepTimeMs = getRetryPolicy().getSleepTimeMs(retries); +//// LogUtil.e(String.format("Try to reconnect to the server after %dms. Retry count: %d.", sleepTimeMs, ++retries)); +// final EventLoop eventLoop = ctx.channel().eventLoop(); +// eventLoop.schedule(() -> { +// System.out.println("Reconnecting ..."); +// mNettyChatClient.connect(); +// }, sleepTimeMs, TimeUnit.MILLISECONDS); +// } +// ctx.fireChannelInactive(); +// } +// +// /** +// * 心跳监测 +// * +// * @param ctx +// * @param evt +// * @throws Exception +// */ +// @Override +// public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { +// if (evt instanceof IdleStateEvent) { +// IdleStateEvent event = (IdleStateEvent) evt; +// String eventType = null; +// switch (event.state()) { +// case READER_IDLE: +// ctx.close(); +// eventType = "读空闲"; +// break; +// case WRITER_IDLE: +// eventType = "写空闲"; +// break; +// case ALL_IDLE: +// eventType = "读写空闲"; +// break; +// default: +// } +//// LogUtil.e(ctx.channel().remoteAddress() + " " + eventType); +// } +// } +// +// +// /** +// * 收到消息后调用 +// */ +// +// @Override +// public void channelRead0(ChannelHandlerContext ctx, Object message) { +//// LogUtil.e("======================"); +//// LogUtil.e("收到消息" + message); +// +// +// byte[] message1 = (byte[]) message; +// bytesW(message1); +// +//// ByteBuf in = (ByteBuf) message; +//// StringBuffer msgObj = new StringBuffer(); +//// for (int i = in.readerIndex(); i < in.writerIndex(); i++) { +//// String hexString = Integer.toHexString((int) in.getByte(i)); +//// if (hexString.length() == 0) { +//// hexString = "00"; +//// } +//// hexString = hexString.toUpperCase().replace("FFFFFF", ""); +//// msgObj.append(hexString.length() == 1 ? "0" + hexString : hexString); +//// } +//// System.out.println(msgObj.toString().replace(" ", "")); +//// bytesW(((String) message).getBytes()); +//// System.out.println("d423432432f"); +// +// +// try(ByteArrayOutputStream bos = new ByteArrayOutputStream(); +// ObjectOutputStream oos = new ObjectOutputStream(bos)) { +// oos.writeObject(message); +// oos.flush(); +// bytesW(bos.toByteArray()); +// +// } catch (IOException e) { +// throw new RuntimeException(e); +// } finally { +// +// } +// } +// +// +// private RetryPolicy getRetryPolicy() { +// if (this.mRetryPolicy == null) { +// this.mRetryPolicy = mNettyChatClient.getRetryPolicy(); +// } +// return this.mRetryPolicy; +// } +// +// public void decode(ByteBuf buf) { +// try { +// byte[] b = new byte[buf.readableBytes()]; +// buf.readBytes(b); +// +// String curMsg = new String(b, "UTF-8").trim(); +//// Log.i("Log", "curMsg == " + curMsg); +// System.out.println(curMsg); +// +// //数据处理的业务逻辑(根据与后端开发人员约定的规则对数据进行处理) +// //... +// +// } catch (Exception e) { +//// Log.i("netty exception", e.toString()); +// } +// } +// +// public static void bytesW( byte[] data) { +// if (data == null || data.length <= 0) { +// return; +// } +// String str = " " + ByteTools.byteToHexStr(data); +// if (str != null && str.length() > 400) { +// str = str.substring(0, 400) + " ...."; +// } +// System.out.println(str); +// } +//} \ No newline at end of file diff --git a/app/src/main/java/com/xinyingpower/microphoto/request/RetryPolicy.java b/app/src/main/java/com/xinyingpower/microphoto/request/RetryPolicy.java new file mode 100644 index 00000000..0b3bf3f3 --- /dev/null +++ b/app/src/main/java/com/xinyingpower/microphoto/request/RetryPolicy.java @@ -0,0 +1,22 @@ +//package com.xinyingpower.microphoto.request; +// +//public interface RetryPolicy { +// +// +// /** +// * Called when an operation has failed for some reason. This method should return +// * true to make another attempt. +// * +// * @param retryCount the number of times retried so far (0 the first time) +// * @return true/false +// */ +// boolean allowRetry(int retryCount); +// +// /** +// * get sleep time in ms of current retry count. +// * +// * @param retryCount current retry count +// * @return the time to sleep +// */ +// long getSleepTimeMs(int retryCount); +//} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 194944ea..f3378c95 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -38,7 +38,7 @@ app:layout_constraintLeft_toRightOf="@+id/cmdid" app:layout_constraintRight_toRightOf="parent" - app:layout_constraintTop_toTopOf="@+id/cmdid" /> + app:layout_constraintTop_toTopOf="@+id/cmdid" /> +