[change] 添加路由器管理页面,完善长时间后台运行权限申请

This commit is contained in:
xinfengkun
2022-06-22 12:01:45 +08:00
parent 246530c61f
commit 36dc2c85b0
32 changed files with 690 additions and 564 deletions

View File

@@ -69,8 +69,8 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation rootProject.ext.dependencies.gson
implementation project(':libraries:mogo-adas')
implementation project(':libraries:mogo-adas-backgrounder-permission')
// implementation 'com.zhidao.support.adas:high:2.6.6.0'
implementation project(':libraries:mogo-adas-other')
// implementation 'com.zhidao.support.adas:high:2.7.0.0'
// implementation 'com.zhjt.mogo.adas.data:adas-data:2.6.6.0'
compileOnly project(':core:mogo-core-data')
implementation project(':core:mogo-core-utils')

View File

@@ -309,22 +309,23 @@ public class AutopilotConfigActivity extends BaseActivity {
}
private void onBack() {
new AlertDialog.Builder(this)
.setTitle("退出提示")
.setMessage("是否配置页面")
.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.setPositiveButton("确认",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
finish();
}
}).show();
finish();
// new AlertDialog.Builder(this)
// .setTitle("退出提示")
// .setMessage("是否配置页面")
// .setNegativeButton("取消",
// new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// dialog.cancel();
// }
// })
// .setPositiveButton("确认",
// new DialogInterface.OnClickListener() {
// public void onClick(DialogInterface dialog, int whichButton) {
// finish();
// }
// }).show();
}
//返回键处理

View File

@@ -89,6 +89,9 @@ import com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS;
import com.zhidao.support.adas.high.common.CupidLogUtils;
import com.zhidao.support.adas.high.common.ProtocolStatus;
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
import com.zhidao.support.adas.high.other.permission.BackgrounderPermission;
import com.zhidao.support.adas.high.other.permission.OnAdasPermissionListener;
import com.zhidao.support.adas.high.other.router.RouterActivity;
import java.net.Inet4Address;
import java.net.InetAddress;
@@ -282,7 +285,12 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
tvConnectState = findViewById(R.id.tv_connect_state);
ipcIp = findViewById(R.id.ipc_ip);
localIp = findViewById(R.id.local_ip);
findViewById(R.id.btn_router).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RouterActivity.newInstance(MainActivity.this, false);
}
});
role.setSelected(BuildConfig.IS_CLIENT);
if (BuildConfig.IS_CLIENT) {
@@ -527,21 +535,25 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
}
});
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// String str = "后台运行:" + (AdasManager.getInstance().isPermissionLongBackgroundRunning(this) ? "<font color='red'>已优化</font>" : "<font color='red'>未优化</font>");
// background.setText(Html.fromHtml(str, Html.FROM_HTML_MODE_LEGACY));
// background.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
//
//// Permission.requestAddDataSaverWhite(MainActivity.this);
//// AdasManager.getInstance().requestIgnoreBatteryOptimizations(MainActivity.this);
// AdasManager.getInstance().showPermissionLongBackgroundRunningDialog(MainActivity.this);
// }
// });
// } else {
// background.setVisibility(View.GONE);
// }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
String str = "后台运行:" + (BackgrounderPermission.getInstance().isPermissionLongBackgroundRunning(this) ? "<font color='red'>已优化</font>" : "<font color='red'>未优化</font>");
background.setText(Html.fromHtml(str, Html.FROM_HTML_MODE_LEGACY));
background.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BackgrounderPermission.getInstance().showPermissionLongBackgroundRunningDialog(MainActivity.this);
}
});
BackgrounderPermission.getInstance().setListener(new OnAdasPermissionListener() {
@Override
public void onBackgrounderPermission(boolean isAllow) {
String str = "后台运行:" + (isAllow ? "<font color='red'>已优化</font>" : "<font color='red'>未优化</font>");
background.setText(Html.fromHtml(str, Html.FROM_HTML_MODE_LEGACY));
}
});
} else {
background.setVisibility(View.GONE);
}
}
private void showListPopupWindow() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_dev_status_net_disable" android:state_pressed="true" />
<item android:drawable="@drawable/icon_dev_status_net_enable" />
</selector>

View File

@@ -283,6 +283,14 @@
android:layout_marginStart="-42dp"
android:scaleType="centerInside"
android:src="@drawable/selector_history_ip" />
<ImageView
android:id="@+id/btn_router"
android:layout_width="40dp"
android:layout_gravity="center_vertical"
android:layout_height="40dp"
android:layout_marginStart="18dp"
android:src="@drawable/selector_router" />
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>

View File

@@ -1,463 +0,0 @@
#### 说明
# ADAS LIB
## 与工控机交互LIB
# 使用方法参见【app_ipc_monitoring】中的代码
## 可用接口
~~~java
/**
* 设置多设备监听
*
* @param l 监听
*/
AdasManager.getInstance().setOnMultiDeviceListener(OnMultiDeviceListener l);
~~~
~~~java
/**
* 设置工控机数据监听
*
* @param l 监听
*/
AdasManager.getInstance().setOnAdasListener(OnAdasListener l);
~~~
~~~java
/**
* 创建一个连接
*
* @param options 连接参数
* @param onAdasConnectStatusListener 连接状态监听
*/
AdasManager.getInstance().create(AdasOptions options, OnAdasConnectStatusListener onAdasConnectStatusListener);
~~~
~~~java
/**
* ADAS LIB 版本
*
* @return 版本
*/
AdasManager.getInstance().getAdasVersion();
~~~
~~~java
/**
* 获取协议版本
*
* @return 版本
*/
AdasManager.getInstance().getProtocolVersion();
~~~
~~~java
/**
* 获取工控机配置信息
*
* @return 配置信息 未连接为null 断开连接会清空
*/
AdasManager.getInstance().getCarConfig();
~~~
~~~java
/**
* 连接工控机
*/
AdasManager.getInstance().connect();
~~~
~~~java
/**
* 与工控机断开连接
*/
AdasManager.getInstance().disconnect();
~~~
~~~java
/**
* 获取当前工控机的链接状态
*
* @return {@link Constants.IPC_CONNECTION_STATUS}
*/
AdasManager.getInstance().getIpcConnectionStatus();
~~~
~~~java
/**
* Log是否开启打印
*/
AdasManager.getInstance().setEnableLog(boolean isEnableLog);
~~~
~~~java
/**
* 系统命令请求, 比如系统重启,启用新镜像
*
* @param type SystemCmdType。SYSTEMCMD_REBOOT 重启所有节点
* SystemCmdType。SYSTEMCMD_EMPLOY_NEW_IMAGE 使用新镜像(推镜像)
* SystemCmdType。SYSTEMCMD_SHUT_DOWN 关机
* @return boolean
*/
AdasManager.getInstance().sendSystemCmdReq(@NonNull MessagePad.SystemCmdType type);
~~~
~~~java
/**
* 解析工控机发送过来的数据
* 多设备时使用
*
* @param bytes 数据
*/
AdasManager.getInstance().parseIPCData(byte[] bytes);
~~~
~~~java
/**
* 获取工控机链接配置
*
* @return 工控机链接参数
*/
AdasManager.getInstance().getAdasOptions();
~~~
~~~java
/**
* 获取已经链接成功的工控机IP 未连接为null
*
* @return ip null:表示未连接
*/
AdasManager.getInstance().getIpcConnectedIp();
~~~
~~~java
/**
* 获取已经链接成功的工控机端口
*
* @return 端口 未连接为默认端口
*/
AdasManager.getInstance().getIpcConnectedPort();
~~~
~~~java
/**
* 自动驾驶设备基础信息应答
*
* @param sn SN
* @param environment 1: 研发环境, 2:测试环境, 3:生产环境 4:演示环境
* @return
*/
AdasManager.getInstance().sendBasicInfoResp(@NonNull String sn, int environment);
~~~
~~~java
/**
* 设置自动驾驶模式 启动自动驾驶
*
* @param mode 1: enter autopilot mode, 0: quit autopilot mode
* @param source 命令来源: 0: pad模拟(模拟时routeInfo传null), 1: AICloud业务
* @param routeInfo 自动驾驶路径信息
* @return
*/
AdasManager.getInstance().sendAutoPilotModeReq(int mode, int source, MessagePad.RouteInfo routeInfo);
~~~
~~~java
/**
* 设置演示模式
*
* @param enable 1: enable, 0: disable
* @return
*/
AdasManager.getInstance().sendDemoModeReq(int enable);
~~~
~~~java
/**
* 车机基础信息请求
*
* @return
*/
AdasManager.getInstance().sendCarConfigReq();
~~~
~~~java
/**
* 记录人工接管原因
*
* @param key bag key 唯一标识
* @param filename 文件路径
* @param reasonID 接管原因id
* @param reason 接管原因
* @return
*/
AdasManager.getInstance().sendRecordCause(long key, @NonNull String filename, @NonNull String reasonID, @NonNull String reason);
~~~
~~~java
/**
* 同下
*
* @param id
* @param type
* @return
*/
AdasManager.getInstance().startRecordPackage(int id, int type);
~~~
~~~java
/**
* 同下
*
* @param id
* @param type
* @return
*/
AdasManager.getInstance().startRecordPackage(int id, int duration, int type);
~~~
~~~java
/**
* 同下
*
* @param id
* @param type
* @return
*/
AdasManager.getInstance().stopRecordPackage(int id, int type);
~~~
~~~java
/**
* 数据采集请求 主动录制Bag包
*
* @param id 采集id
* @param duration 采集时间长
* @param type 采集类型, 1:badcase, 2: map; 3: rests
* @param isRecord 采集指令, true: 采集, false: 停止采集
* @param sustain 是否持续采集
* @return
*/
AdasManager.getInstance().sendRecordData(int id, int duration, int type, boolean isRecord);
~~~
~~~java
/**
* 设置自动驾驶最大速度
*
* @param speedLimit 最大车辆速度 m/s
* @return
*/
AdasManager.getInstance().sendAutopilotSpeedReq(double speedLimit);
~~~
~~~java
/**
* 发送红绿灯数据到工控机
*
* @param crossID roadID
* @param latitude
* @param longitude
* @param heading 红绿灯方向
* @param direction 路的航向角
* @param lightId 红绿灯ID
* @param laneNo 车道号
* @param arrowNo 当前车道对应地面要素转向
* @param flashYellow 黄灯总时间
* @param laneDetail 灯态具体信息
* @return
*/
AdasManager.getInstance().sendTrafficLightData(@NonNull String crossID, double latitude, double longitude, @NonNull String heading, @NonNull String direction, int lightId, int laneNo, int arrowNo, int flashYellow, MessagePad.TrafficLightDetail laneDetail);
~~~
~~~java
/**
* 自动驾驶路径请求
*
* @return
*/
AdasManager.getInstance().sendGlobalPathReq();
~~~
~~~java
/**
* 获取工控机固定IP列表
*
* @return 返回默认工控机IP列表
*/
AdasManager.getInstance().getIPCFixationIPList(Context context);
~~~
~~~java
/**
* 增加工控机固定IP
*
* @param ipcIP IP
*/
AdasManager.getInstance().addIPCFixationIP(Context context, String ipcIP);
~~~
~~~java
/**
* 删除指定的工控机固定IP
*
* @param ipcIP IP
*/
AdasManager.getInstance().delIPCFixationIP(Context context, String ipcIP);
~~~
~~~java
/**
* 删除所有工控机固定IP
*/
AdasManager.getInstance().delIPCFixationIP(Context context);
~~~
## OnAdasListener
### 工控机数据回调
#### 回调中对象的字段详情参见各个proto文件
~~~java
/**
* 自动驾驶局部轨迹 前车引导线
*
* @param header 头
* @param trajectory 数据
*/
void onTrajectory(MessagePad.Header header, MessagePad.Trajectory trajectory);
~~~
~~~java
/**
* 障碍物 他车数据
*
* @param header 头
* @param trackedObjects 数据
*/
void onTrackedObjects(MessagePad.Header header, MessagePad.TrackedObjects trackedObjects);
~~~
~~~java
/**
* 惯导信息
*
* @param header 头
* @param gnssInfo 数据
*/
void onGnssInfo(MessagePad.Header header, MessagePad.GnssInfo gnssInfo);
~~~
~~~java
/**
* 底盘信息, 透传底盘状态pb参考底盘
*
* @param header 头
* @param vehicleState 数据
*/
void onVehicleState(MessagePad.Header header, VehicleStateOuterClass.VehicleState vehicleState);
~~~
~~~java
/**
* 自动驾驶状态
*
* @param header 头
* @param autopilotState 数据
*/
void onAutopilotState(MessagePad.Header header, MessagePad.AutopilotState autopilotState);
~~~
~~~java
/**
* 监控事件报告
*
* @param header 头
* @param mogoReportMessage 数据
*/
void onReportMessage(MessagePad.Header header, MogoReportMsg.MogoReportMessage mogoReportMessage);
~~~
~~~java
/**
* 感知红绿灯
*
* @param header 头
* @param trafficLights 感知红绿灯
*/
void onPerceptionTrafficLight(MessagePad.Header header, TrafficLightOuterClass.TrafficLights trafficLights);
~~~
~~~java
/**
* 他车轨迹预测
*
* @param header 头
* @param predictionObjects 他车轨迹预测数据
*/
void onPredictionObstacleTrajectory(MessagePad.Header header, Prediction.mPredictionObjects predictionObjects);
~~~
~~~java
/**
* 自动驾驶设备基础信息请求
*
* @param header 头
* @param basicInfoReq 数据 目前没有任何参数
*/
void onBasicInfoReq(MessagePad.Header header, MessagePad.BasicInfoReq basicInfoReq);
~~~
~~~java
/**
* 车机基础信息应答
*
* @param header 头
* @param carConfigResp 数据
*/
void onCarConfigResp(MessagePad.Header header, MessagePad.CarConfigResp carConfigResp);
~~~
~~~java
/**
* 数据采集结果
*
* @param header 头
* @param recordPanel 数据
*/
void onRecordResult(MessagePad.Header header, RecordPanelOuterClass.RecordPanel recordPanel);
~~~
~~~java
/**
* 自动驾驶路径应答
*
* @param header 头
* @param globalPathResp 数据
*/
void onGlobalPathResp(MessagePad.Header header, MessagePad.GlobalPathResp globalPathResp);
~~~
~~~java
/**
* 报警信息
* 暂时保留,目前没有使用
*
* @param header 头
* @param warn 数据
*/
@Deprecated
void onWarn(MessagePad.Header header, MessagePad.Warn warn);
~~~
~~~java
/**
* 到站提醒 自动驾驶站点
*
* @param header 头
* @param arrivalNotification 数据
*/
void onArrivalNotification(MessagePad.Header header, MessagePad.ArrivalNotification arrivalNotification);
~~~
~~~java
/**
* 向IPC发送命令返回结果
*
* @param info
*/
void onSSHResult(SSHResult info);
~~~
~~~java
/**
* 数据错误
*
* @param status 错误原因
* @param bytes 原始数据
*/
void onError(ProtocolStatus status, byte[] bytes);
~~~
## OnAdasConnectStatusListener
### 连接状态监听
~~~java
/**
* 与工控机链接状态变化
*
* @param ipcConnectionStatus {@link Constants.IPC_CONNECTION_STATUS}
* @param reason 连接信息 需要判null
* 如果ipcConnectionStatus==Constants.IPC_CONNECTION_STATUS.DISCONNECTED&&reason==null 表示主动断开连接
*/
void onConnectionIPCStatus(@Define.IPCConnectionStatus int ipcConnectionStatus, @Nullable String reason);
~~~
## OnMultiDeviceListener
### 多设备链接监听
~~~java
/**
* 转发工控机消息
* 如果是客户端此回调不会被调用
*
* @param bytes 数据
*/
void onForwardingIPCMessage(byte[] bytes);
~~~

View File

@@ -1,41 +0,0 @@
package com.zhidao.support.adas.high.permission.dialog;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.zhidao.support.adas.high.permission.R;
/**
* 数据用量及电池优化 权限申请
* 高版本Android系统会针对熄屏、休眠或后台 对电池WiFi等进行优化长时间网络可能会断开连接
*/
public class PermissionLongBackgroundRunningDialog extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.dialog_in, R.anim.dialog_out);
setContentView(R.layout.dialog_adas_permission_long_background_running);
// //设置弹出窗口与屏幕对齐
// Window win = this.getWindow();
// int density = (int) (getResources().getDisplayMetrics().density + 0.5f);
////设置内边距这里设置为10dp
// win.getDecorView().setPadding(10 * density, 10 * density, 10 * density, 10 * density);
// WindowManager.LayoutParams lp = win.getAttributes();
////设置窗口宽度
// lp.width = WindowManager.LayoutParams.MATCH_PARENT;
////设置窗口高度
// lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
////设置Dialog位置
// lp.gravity = Gravity.TOP;
// win.setAttributes(lp);
}
@Override
public void finish() {
super.finish();
//在此时设置转场动画
overridePendingTransition(R.anim.dialog_out, R.anim.dialog_in);
}
}

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_adas_dialog"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="由于系统默认启动了电池优化功能,此功会影响熄屏或休眠后网络连接"
android:textColor="#000000" />
</LinearLayout>

View File

@@ -0,0 +1,7 @@
#### 说明
# ADAS LIB 其他功能
## 与工控机交互LIB
# 申请后台运行权限《关闭电池优化》
# 路由器管理

View File

@@ -32,5 +32,6 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.material
}

View File

@@ -1,14 +1,19 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zhidao.support.adas.high.permission">
package="com.zhidao.support.adas.high.other">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application>
<application
android:usesCleartextTraffic="true">
<activity
android:name=".dialog.PermissionLongBackgroundRunningDialog"
android:name=".permission.PermissionLongBackgroundRunningDialog"
android:theme="@style/PermissionLongBackgroundRunningDialogStyle" />
<activity
android:name=".router.RouterActivity"
android:theme="@style/NoActionBar" />
</application>
</manifest>

View File

@@ -1,22 +1,43 @@
package com.zhidao.support.adas.high.permission;
package com.zhidao.support.adas.high.other.permission;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;
import com.zhidao.support.adas.high.permission.dialog.PermissionLongBackgroundRunningDialog;
import androidx.annotation.RequiresApi;
/**
* 长时间后台运行权限检查
*/
@RequiresApi(api = Build.VERSION_CODES.N)
public class BackgrounderPermission {
private static volatile BackgrounderPermission INSTANCE;
private OnAdasPermissionListener listener;
private BackgrounderPermission() {
}
public static BackgrounderPermission getInstance() {
if (INSTANCE == null) {
synchronized (BackgrounderPermission.class) {
if (INSTANCE == null) {
INSTANCE = new BackgrounderPermission();
}
}
}
return INSTANCE;
}
public void setListener(OnAdasPermissionListener listener) {
this.listener = listener;
}
public void showPermissionLongBackgroundRunningDialog(Context context) {
Intent intent = new Intent(context, PermissionLongBackgroundRunningDialog.class);
@@ -24,6 +45,12 @@ public class BackgrounderPermission {
}
void onBackgrounderPermission(boolean isBackgrounderPermission) {
if (listener != null) {
listener.onBackgrounderPermission(isBackgrounderPermission);
}
}
/**
* 获取当前是否开启电池优化
@@ -31,7 +58,7 @@ public class BackgrounderPermission {
* @param context 上下文
* @return 否在设备的电源白名单上 true 表示未优化
*/
public boolean isIgnoringBatteryOptimizations(Context context) {
boolean isIgnoringBatteryOptimizations(Context context) {
boolean isIgnoring = false;
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (powerManager != null) {
@@ -45,10 +72,11 @@ public class BackgrounderPermission {
*
* @param context
*/
public void requestIgnoreBatteryOptimizations(Context context) {
void requestIgnoreBatteryOptimizations(Activity context) {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);
context.startActivityForResult(intent, PermissionLongBackgroundRunningDialog.REQUEST_CODE_BATTERY_OPTIMIZATIONS);
}
/**
@@ -59,7 +87,7 @@ public class BackgrounderPermission {
* @return
*/
public boolean isIgnoringMeteredNetworkRestrictions(Context context) {
private boolean isIgnoringMeteredNetworkRestrictions(Context context) {
ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
// 检查设备是否在计费网络
// if (connMgr.isActiveNetworkMetered()) {
@@ -90,7 +118,7 @@ public class BackgrounderPermission {
/**
* 除非应用的核心功能受到不利影响否则 Google Play 政策禁止应用请求直接豁免 Android 6.0+ 中的电源管理功能低电耗模式和应用待机模式
*/
public static void requestAddDataSaverWhite(Context context) {
private static void requestAddDataSaverWhite(Context context) {
// ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
// if (connMgr != null && connMgr.getRestrictBackgroundStatus() == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED) {
Intent intent = new Intent(Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS);
@@ -101,11 +129,15 @@ public class BackgrounderPermission {
/**
* 是否允许长时间后台运行
* 目前测试得出电池优化会影响后台运行
*
* @param context 上下文
* @return
*/
public boolean isPermissionLongBackgroundRunning(Context context) {
return isIgnoringBatteryOptimizations(context) && isIgnoringMeteredNetworkRestrictions(context);
// return isIgnoringBatteryOptimizations(context) && isIgnoringMeteredNetworkRestrictions(context);
return isIgnoringBatteryOptimizations(context);
}
}

View File

@@ -0,0 +1,10 @@
package com.zhidao.support.adas.high.other.permission;
public interface OnAdasPermissionListener {
/**
* 是否允许后台运行
* 目前只检查了是否关闭电池优化
* @param isAllow 是否允许后台运行
*/
void onBackgrounderPermission(boolean isAllow);
}

View File

@@ -0,0 +1,87 @@
package com.zhidao.support.adas.high.other.permission;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import com.zhidao.support.adas.high.other.R;
/**
* 数据用量及电池优化 权限申请
* 高版本Android系统会针对熄屏、休眠或后台 对电池WiFi等进行优化长时间网络可能会断开连接
*/
@RequiresApi(api = Build.VERSION_CODES.N)
public class PermissionLongBackgroundRunningDialog extends AppCompatActivity {
public static final int REQUEST_CODE_BATTERY_OPTIMIZATIONS = 0x01;
private TextView hint_battery;
private Button btn_close_battery_optimizations;
private BackgrounderPermission listener;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.dialog_in, R.anim.dialog_out);
setContentView(R.layout.dialog_adas_permission_long_background_running);
initView();
setBatteryHint();
// //设置弹出窗口与屏幕对齐
// Window win = this.getWindow();
// int density = (int) (getResources().getDisplayMetrics().density + 0.5f);
////设置内边距这里设置为10dp
// win.getDecorView().setPadding(10 * density, 10 * density, 10 * density, 10 * density);
// WindowManager.LayoutParams lp = win.getAttributes();
////设置窗口宽度
// lp.width = WindowManager.LayoutParams.MATCH_PARENT;
////设置窗口高度
// lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
////设置Dialog位置
// lp.gravity = Gravity.TOP;
// win.setAttributes(lp);
}
private void initView() {
hint_battery = findViewById(R.id.hint_battery);
btn_close_battery_optimizations = findViewById(R.id.btn_close_battery_optimizations);
btn_close_battery_optimizations.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BackgrounderPermission.getInstance().requestIgnoreBatteryOptimizations(PermissionLongBackgroundRunningDialog.this);
}
});
}
private boolean setBatteryHint() {
boolean isIgnoringBatteryOptimizations = BackgrounderPermission.getInstance().isIgnoringBatteryOptimizations(this);
btn_close_battery_optimizations.setVisibility(isIgnoringBatteryOptimizations ? View.INVISIBLE : View.VISIBLE);
String str = "电池优化:" + (isIgnoringBatteryOptimizations ? "<font color='green'>不优化</font>" : "<font color='red'>优化</font>");
hint_battery.setText(Html.fromHtml(str, Html.FROM_HTML_MODE_LEGACY));
return isIgnoringBatteryOptimizations;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CODE_BATTERY_OPTIMIZATIONS) {
BackgrounderPermission.getInstance().onBackgrounderPermission(setBatteryHint());
}
}
}
@Override
public void finish() {
super.finish();
//在此时设置转场动画
overridePendingTransition(R.anim.dialog_out, R.anim.dialog_in);
}
}

View File

@@ -0,0 +1,190 @@
package com.zhidao.support.adas.high.other.router;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import com.zhidao.support.adas.high.other.R;
/**
* A placeholder fragment containing a simple view.
*/
public class PlaceholderFragment extends Fragment {
private static final String TAG = PlaceholderFragment.class.getSimpleName();
private static final String ROUTER_URL = "router_url";
private static final String ROUTER_COOKIE = "router_cookie";
private String url;
private ProgressBar progressBar;
private WebView webView;
private CookieManager cookieManager;
private SharedPreferences sharedPreferences;
public static PlaceholderFragment newInstance(String url) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle bundle = new Bundle();
bundle.putString(ROUTER_URL, url);
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
url = getArguments().getString(ROUTER_URL);
}
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_router, container, false);
webView = view.findViewById(R.id.web_view);
progressBar = view.findViewById(R.id.progressbar);//进度条
if (getActivity() != null)
sharedPreferences = getActivity().getSharedPreferences("adas_config", Context.MODE_PRIVATE);
cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
initWebView();
return view;
}
public void onRefresh() {
webView.reload();
}
private void initWebView() {
String cokkie = null;
if (sharedPreferences != null)
cokkie = sharedPreferences.getString(ROUTER_COOKIE, null);
if (cokkie != null && cokkie.length() > 0 && cokkie.contains(url)) {
int index = cokkie.indexOf("##");
cookieManager.setCookie(this.url, cokkie.substring(index));
}
webView.loadUrl(url);//加载url
webView.addJavascriptInterface(this, "android");//添加js监听 这样html就能调用客户端
webView.setWebChromeClient(webChromeClient);
webView.setWebViewClient(webViewClient);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);//允许使用js
/**
* LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
* LOAD_DEFAULT: 默认根据cache-control决定是否从网络上取数据。
* LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
* LOAD_CACHE_ELSE_NETWORK只要本地有无论是否过期或者no-cache都使用缓存中的数据。
*/
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//不使用缓存,只从网络获取数据.
//支持屏幕缩放
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
//不显示webview缩放按钮
webSettings.setDisplayZoomControls(false);
// webSettings.setUseWideViewPort(true);//自适应屏幕
webSettings.setLoadWithOverviewMode(true);
webSettings.setAllowFileAccess(true);
webSettings.setAppCacheEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setDatabaseEnabled(true);
}
//WebViewClient主要帮助WebView处理各种通知、请求事件
private final WebViewClient webViewClient = new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {//页面加载完成
progressBar.setVisibility(View.GONE);
String oldCookie = cookieManager.getCookie(url);
if (!TextUtils.isEmpty(oldCookie)) {
String cokkie = null;
if (sharedPreferences != null)
cokkie = sharedPreferences.getString(ROUTER_COOKIE, null);
if (!TextUtils.equals(cokkie, oldCookie)) {
sharedPreferences.edit().putString(url + "##" + ROUTER_COOKIE, oldCookie).apply();
}
}
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {//页面开始加载
progressBar.setVisibility(View.VISIBLE);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//返回true 拦截
return super.shouldOverrideUrlLoading(view, url);
}
};
//WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
private final WebChromeClient webChromeClient = new WebChromeClient() {
//不支持js的alert弹窗需要自己监听然后通过dialog弹窗
@Override
public boolean onJsAlert(WebView webView, String url, String message, JsResult result) {
AlertDialog.Builder localBuilder = new AlertDialog.Builder(webView.getContext());
localBuilder.setMessage(message).setPositiveButton("确定", null);
localBuilder.setCancelable(false);
localBuilder.create().show();
//注意:
//必须要这一句代码:result.confirm()表示:
//处理结果为确定状态同时唤醒WebCore线程
//否则不能继续点击按钮
result.confirm();
return true;
}
//获取网页标题
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
Log.i(TAG, "网页标题:" + title);
}
//加载进度回调
@Override
public void onProgressChanged(WebView view, int newProgress) {
progressBar.setProgress(newProgress);
}
};
public boolean onKeyDownChild(int keyCode) {
Log.i(TAG, "是否有上一个页面:" + webView.canGoBack());
if (webView.canGoBack() && keyCode == KeyEvent.KEYCODE_BACK) {//点击返回按钮的时候判断有没有上一页
webView.goBack(); // goBack()表示返回webView的上一页面
return true;
}
return false;
}
@Override
public void onDestroyView() {
super.onDestroyView();
//释放资源
webView.destroy();
webView = null;
}
}

View File

@@ -0,0 +1,108 @@
package com.zhidao.support.adas.high.other.router;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.zhidao.support.adas.high.other.R;
public class RouterActivity extends AppCompatActivity {
private static final String[] TAB_TITLES = new String[]{"Bus", "Taxi"};
private boolean isBus;
private int currentPosition = 0;//默认选中bus
public static void newInstance(Context context, boolean isBus) {
Intent intent = new Intent(context, RouterActivity.class);
intent.putExtra("is_bus", isBus);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_router);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, TAB_TITLES);
ViewPager2 viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
viewPager.setOffscreenPageLimit(1);
TabLayoutMediator mediator = new TabLayoutMediator(tabs, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(TAB_TITLES[position]);
}
});
mediator.attach();
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
currentPosition = position;
Log.i("dddd", "当前 Pos=" + currentPosition);
}
});
findViewById(R.id.close).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!isClose(KeyEvent.KEYCODE_BACK))
finish();
}
});
findViewById(R.id.refresh).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PlaceholderFragment fragment = (PlaceholderFragment) getViewPagerFragment(currentPosition);
if (fragment != null) {
fragment.onRefresh();
}
}
});
Intent intent = getIntent();
if (intent != null) {
isBus = intent.getBooleanExtra("is_bus", true);
}
currentPosition = isBus ? 0 : 1;
viewPager.setCurrentItem(currentPosition, false);
}
/**
* @param position fragment 的位置
* @return
*/
private Fragment getViewPagerFragment(int position) {
return getSupportFragmentManager().findFragmentByTag("f" + position);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return isClose(keyCode) || super.onKeyDown(keyCode, event);
}
private boolean isClose(int keyCode) {
PlaceholderFragment fragment = (PlaceholderFragment) getViewPagerFragment(currentPosition);
if (fragment != null) {
return fragment.onKeyDownChild(keyCode);
}
return false;
}
}

View File

@@ -0,0 +1,41 @@
package com.zhidao.support.adas.high.other.router;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.HashMap;
import java.util.Map;
public class SectionsPagerAdapter extends FragmentStateAdapter {
private final String[] TAB_TITLES;
public final Map<String, PlaceholderFragment> fragments = new HashMap<>();
private final FragmentActivity fragmentActivity;
public SectionsPagerAdapter(@NonNull FragmentActivity fragmentActivity, String[] TAB_TITLES) {
super(fragmentActivity);
this.fragmentActivity = fragmentActivity;
this.TAB_TITLES = TAB_TITLES;
}
@NonNull
@Override
public Fragment createFragment(int position) {
String url = "192.168.1.1";
if ("Bus".equals(TAB_TITLES[position])) {
url = "192.168.8.1";
}
return PlaceholderFragment.newInstance(url);
}
@Override
public int getItemCount() {
return TAB_TITLES.length;
}
}

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".router.RouterActivity">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.cardview.widget.CardView
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="10dp">
<Button
android:id="@+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="返回" />
<Button
android:id="@+id/refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="刷新" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="输入路由器用户名/密码->点击“登录”->点击“连接用户”查看当前列表中是否存在IP是“192.168.X.102”的设备"
android:textColor="#000000"
android:textStyle="bold" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tabs" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_adas_dialog"
android:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:id="@+id/hint_battery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="电池优化:优化"
android:textColor="#000000" />
<Button
android:id="@+id/btn_close_battery_optimizations"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="关闭" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="开启池优化功能,会影响熄屏或休眠后网络连接"
android:textColor="#696969" />
</LinearLayout>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".router.PlaceholderFragment">
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/constraintLayout"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintTop_creator="1" />
<ProgressBar
android:id="@+id/progressbar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="3dip"
android:max="100"
android:progress="0"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/constraintLayout"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintTop_creator="1" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -18,4 +18,8 @@
<item name="android:backgroundDimEnabled">true</item>
</style>
<style name="NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
</resources>

View File

@@ -62,7 +62,7 @@ include ':libraries:mogo-map-api'
include ':libraries:mogo-map'
include ':libraries:mogo-adas'
include ':libraries:mogo-adas-data'
include ':libraries:mogo-adas-backgrounder-permission'
include ':libraries:mogo-adas-other'
// OLD业务模块
include ':modules:mogo-module-common'