当前位置: 首页 > news >正文

Unity 权限 之 Android 【权限 动态申请】功能的简单封装

Unity 权限 之 Android 【权限 动态申请】功能的简单封装

目录

Unity 权限 之 Android 【权限 动态申请】功能的简单封装

一、简单介绍

二、Android 权限 动态申请

三、实现原理

四、注意事项

五、案例实现简单步骤

附录:

一、进一步优化

二、多个权限申请代码参考


一、简单介绍

Unity 是一个功能强大的跨平台游戏引擎,广泛用于开发视频游戏和其他实时3D互动内容,如模拟器和虚拟现实应用。

  1. 游戏引擎

    • Unity:Unity Technologies 开发的跨平台游戏引擎,支持2D和3D图形、物理引擎、音频、视频、网络和多平台发布。
    • 跨平台支持:Unity 支持在多个平台上发布,包括 Windows、macOS、Linux、iOS、Android、WebGL、PlayStation、Xbox、Switch 等。
  2. 开发环境

    • Unity Editor:用于创建和管理 Unity 项目的集成开发环境(IDE)。开发者可以在其中创建场景、设计关卡、编写代码和调试游戏。
    • 场景(Scene):Unity 中的基本构建块,一个场景可以被视为一个关卡或一个游戏中的独立部分。
  3. 编程语言

    • C#:主要编程语言。Unity 使用 C# 脚本来控制游戏对象和实现游戏逻辑。
    • UnityScript(已弃用):曾经支持的 JavaScript 变种,但已经被弃用。

Unity 进阶开发涉及更复杂的技术和更深入的知识,以创建高性能、复杂和专业的游戏和应用程序。以下是一些 Unity 进阶开发的关键领域和技术:

  • 设计模式

    • 学习和应用常见的设计模式(如单例模式、工厂模式、观察者模式)以便更好地组织和管理代码。
  • 异步编程

    • 使用 C# 的 asyncawait 关键字进行异步编程,以提高应用的响应速度和性能。
  • 依赖注入

    • 使用依赖注入(如 Zenject)来管理对象的依赖关系,减少耦合,提高代码的可测试性和可维护性。

二、Android 权限 动态申请

在开发 Unity Android 应用时,动态获取权限是一个常见的需求。由于 Android 6.0(API 级别 23)引入了运行时权限模型,应用必须在运行时请求某些权限。下面是一个如何在 Unity 中封装动态获取权限功能的示例。

在 Unity 中,仅使用 C# 代码来处理 Android 动态权限请求是可能的,但仍需要调用 Android 的原生 API。这可以通过 AndroidJavaClassAndroidJavaObject 来实现。

三、实现原理

PermissionManager 是一个用于管理 Android 权限请求的单例类。其主要功能是动态请求权限并在用户响应后处理结果。以下是其工作原理和实现步骤的详细解释:

  1. 单例模式

    • PermissionManager 使用单例模式确保在整个应用生命周期中只有一个实例。
  2. 权限请求接口

    • RequestPermission 方法用于请求特定的权限。
    • 首先检查权限是否已经授予,如果已授予则立即调用回调函数返回结果。
    • 如果权限未授予,启动协程 RequestAndCheckPermission 请求权限并等待用户响应。
  3. 协程处理

    • RequestAndCheckPermission 方法通过协程 IEnumerator 实现异步等待。
    • 使用 Permission.RequestUserPermission 方法请求权限。
    • 使用 yield return new WaitForSeconds(1.0f) 等待一段时间,让用户有足够时间响应权限请求。
    • 等待结束后,再次检查权限状态并调用回调函数返回结果。

四、注意事项

  1. 权限列表

    • 确保在 AndroidManifest.xml 中声明所有需要请求的权限,否则请求可能会失败。
    • 例如:
      <uses-permission android:name="android.permission.CAMERA" />
  2. 权限请求的异步性

    • 用户响应权限请求的时间是不确定的。使用协程 (IEnumerator) 异步等待用户响应而不阻塞主线程是必要的。
    • yield return new WaitForSeconds(1.0f) 是一个简单的等待机制,实际项目中可能需要更复杂的逻辑来处理用户的响应。
  3. 回调函数

    • 确保传递给 RequestPermission 的回调函数能正确处理权限被授予或拒绝的情况。
    • 回调函数签名为 System.Action<string, bool>,其中第一个参数是权限名,第二个参数是权限是否被授予的布尔值。
  4. 用户体验

    • 提示用户为什么需要请求特定权限,以提高用户接受权限请求的概率。
    • 在权限被拒绝后,提供适当的反馈和处理机制,如再次请求权限或退出相关功能。
  5. 多权限请求

    • 当前示例处理单个权限请求。如果需要请求多个权限,可以扩展 PermissionManager 类以支持批量请求,并分别处理每个权限的授予结果。

五、案例实现简单步骤

1、新建一个 Unity 工程

2、新建脚本 PermissionWrapper 封装权限申请功能

3、新建脚本 TestPermissionWrapper 测试封装权限申请功能,申请 camera 权限

4、把 TestPermissionWrapper  挂载到场景中

5、在 Player Settings 中的 Build 中勾选 Custom Main Manifest ,添加 Camera 权限申请

6、打包运行

六、关键代码

1、PermissionWrapper


using UnityEngine;
using UnityEngine.Android;public class PermissionWrapper : MonoSingleton<PermissionWrapper>
{/// <summary>/// 请求权限/// </summary>/// <param name="permission">权限名称</param>/// <param name="callback">权限回调:true 权限获取成功回调,false 权限获取失败回调</param>public void RequestPermission(string permission, System.Action<string, bool> callback){if (Permission.HasUserAuthorizedPermission(permission)){callback?.Invoke(permission, true);}else{StartCoroutine(RequestAndCheckPermission(permission, callback));}}/// <summary>/// 协程请求权限/// </summary>/// <param name="permission">权限名称</param>/// <param name="callback">权限回调:true 权限获取成功回调,false 权限获取失败回调</param>/// <returns></returns>private System.Collections.IEnumerator RequestAndCheckPermission(string permission, System.Action<string, bool> callback){Permission.RequestUserPermission(permission);yield return new WaitForSeconds(1.0f);bool granted = Permission.HasUserAuthorizedPermission(permission);callback?.Invoke(permission, granted);}
}

2、TestPermissionWrapper


using UnityEngine;
using UnityEngine.Android;public class TestPermissionWrapper : MonoBehaviour
{private void Start(){// 请求摄像头权限PermissionWrapper.Instance.RequestPermission(Permission.Camera, OnPermissionResult);}private void OnPermissionResult(string permission, bool granted){if (granted){Debug.Log("权限已授予: " + permission);// 执行需要权限的功能}else{Debug.Log("权限被拒绝: " + permission);// 处理权限被拒绝的情况}}
}

3、MonoSingleton

using System;
using UnityEngine;public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{private static T m_Instance;public static T Instance{get{if ((UnityEngine.Object)m_Instance == (UnityEngine.Object)null){T[] array = UnityEngine.Object.FindObjectsOfType<T>();if (array != null && array.Length != 0){if (array.Length != 1){throw new Exception($"## Uni Exception ## Cls:{typeof(T)} Info:Singleton not allows more than one instance");}m_Instance = array[0];}else{m_Instance = new GameObject($"{typeof(T).ToString()}(Singleton)").AddComponent<T>();m_Instance.OnSingletonInit();}}return m_Instance;}}protected virtual void Awake(){m_Instance = this as T;}protected virtual void OnDestroy(){m_Instance = null;}protected virtual void OnSingletonInit(){}
}

4、AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"package="com.unity3d.player"xmlns:tools="http://schemas.android.com/tools"><!--相机权限--><uses-permission android:name="android.permission.CAMERA" /><application><activity android:name="com.unity3d.player.UnityPlayerActivity"android:theme="@style/UnityThemeSelector"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><meta-data android:name="unityplayer.UnityActivity" android:value="true" /></activity></application>
</manifest>

附录:

一、进一步优化

  • 用户提示:在请求权限前,先提示用户为何需要该权限,增强用户接受度。
  • 多权限支持:实现多权限同时请求的逻辑。
  • 超时处理:考虑在等待用户响应时添加超时处理逻辑,避免无限期等待。
  • 权限变更监听:实现权限变更监听,当用户在应用设置中更改权限时做出相应处理。

通过这些改进和注意事项,可以确保权限请求功能更加健壮和用户友好。

二、多个权限申请代码参考

1、PermissionJudgeMgr

using FfalconXR;
using FFALFramework.UIModule;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Android;public class PermissionJudgeMgr : MonoSingleton<PermissionJudgeMgr>
{#region Data/// <summary>/// TAG/// </summary>const string TAG = "[PermissionJudgeMgr] ";/// <summary>/// 权限申请列表/// </summary>List<IRequestPermissionItem> m_RequestPermissionItemLst;/// <summary>/// 请求权限回调/// </summary>private PermissionCallbacks m_PermissionCallbacks;/// <summary>/// 全部权限允许后的事件/// </summary>public Action OnAllPermissionGrantedAction;/// <summary>/// 判断是否有权限/// </summary>public bool IsHasPermission { get { return JudgeIsHasPermission(); } }#endregion#region public function/// <summary>/// 检测 权限/// </summary>public void CheckAppPermission(){CheckRequestPermissionLst();}#endregion#region 生命周期/// <summary>/// OnSingletonInit/// </summary>protected override void OnSingletonInit(){base.OnSingletonInit();RegisterPermissionListener();}/// <summary>/// OnDestroy/// </summary>protected override void OnDestroy(){base.OnDestroy();UnRegisterPermissionListener();}#endregion#region private function/// <summary>/// 检测权限队列/// </summary>private void CheckRequestPermissionLst() {IRequestPermissionItem requestPermissionItem = null;foreach (var item in m_RequestPermissionItemLst){if (item.IsHasPermission == false){requestPermissionItem = item;break;}}if (requestPermissionItem != null){requestPermissionItem.RequestPermission(m_PermissionCallbacks);}else{OnAllPermissionGrantedAction?.Invoke();}}/// <summary>/// 注册权限监听/// </summary>private void RegisterPermissionListener(){UIManager.Instance.QuitAll();AddRequestPermissionItem();m_PermissionCallbacks = new PermissionCallbacks();//对系统权限处理的回调m_PermissionCallbacks.PermissionGranted += OnPermissionGranted;m_PermissionCallbacks.PermissionDenied += OnPermissionDenied;}/// <summary>/// 取消权限监听/// </summary>private void UnRegisterPermissionListener(){m_PermissionCallbacks.PermissionGranted -= OnPermissionGranted;m_PermissionCallbacks.PermissionDenied -= OnPermissionDenied;m_PermissionCallbacks = null;OnAllPermissionGrantedAction = null;m_RequestPermissionItemLst.Clear();m_RequestPermissionItemLst = null;}/// <summary>/// 权限授予事件/// </summary>/// <param name="Permission"></param>private void OnPermissionGranted(string Permission){MainThreadQueue.Instance.ExecuteQueue.Enqueue(() =>{Debug.Log(TAG+"OnPermissionGranted():" + Permission);// 继续请求其他权限CheckRequestPermissionLst();});}/// <summary>/// 权限拒绝事件/// </summary>/// <param name="Permission"></param>private void OnPermissionDenied(string Permission){MainThreadQueue.Instance.ExecuteQueue.Enqueue(() =>{Debug.Log(TAG + "OnPermissionDenied():" + Permission);// Todo 提示:1、打开失败页界面;2、然后可以继续请求权限});}/// <summary>/// 添加权限申请判断/// </summary>private void AddRequestPermissionItem() {m_RequestPermissionItemLst = new List<IRequestPermissionItem>();// 相机权限获取m_RequestPermissionItemLst.Add(new CameraRequestPermissionItem());// 麦克风权限获取m_RequestPermissionItemLst.Add(new MicrophoneRequestPermissionItem());// 继续添加更多...}/// <summary>/// 判断是否有权限没有申请/// </summary>/// <returns></returns>private bool JudgeIsHasPermission() {if (m_RequestPermissionItemLst == null) return true;else {foreach (var item in m_RequestPermissionItemLst){if (item.IsHasPermission == false) return false;}}return true;}#endregion
}

2、CameraRequestPermissionItem


using UnityEngine.Android;public class CameraRequestPermissionItem : BaseRequestPermissionItem
{/// <summary>/// TAG/// </summary>protected override string TAG { get; } = "[CameraRequestPermissionItem] ";/// <summary>/// 去申请的权限名称/// </summary>public override string ToRequestPermissionName => Permission.Camera;
}

3、MicrophoneRequestPermissionItem

using UnityEngine.Android;public class MicrophoneRequestPermissionItem : BaseRequestPermissionItem
{/// <summary>/// TAG/// </summary>protected override string TAG { get; } = "[MicrophoneRequestPermissionItem] ";/// <summary>/// 去申请的权限名称/// </summary>public override string ToRequestPermissionName => Permission.Microphone;
}

4、BaseRequestPermissionItem


using UnityEngine;
using UnityEngine.Android;public class BaseRequestPermissionItem : IRequestPermissionItem
{#region Data/// <summary>/// TAG/// </summary>protected virtual string TAG { get; } = "[BaseRequestPermissionItem] ";/// <summary>/// 去申请的权限名称/// </summary>public virtual string ToRequestPermissionName => Permission.Camera;/// <summary>/// 判断是否有权限/// </summary>public virtual bool IsHasPermission => Permission.HasUserAuthorizedPermission(ToRequestPermissionName);#endregion#region Interface function/// <summary>/// 请求权限/// </summary>/// <param name="permissionCallbacks">权限回调事件</param>public virtual void RequestPermission(PermissionCallbacks permissionCallbacks){if (permissionCallbacks == null) {Debug.LogError(TAG + " RequestPhoneStatePermission() permissionCallbacks is null ");return;}if (!IsHasPermission){Debug.Log(TAG+ " RequestPhoneStatePermission() ");Permission.RequestUserPermission(ToRequestPermissionName, permissionCallbacks);}}#endregion
}

5、IRequestPermissionItem

using UnityEngine.Android;public interface IRequestPermissionItem 
{/// <summary>/// 去申请的权限名称/// </summary>string ToRequestPermissionName { get; }/// <summary>/// 请求权限/// </summary>/// <param name="permissionCallbacks">权限回调事件</param>void RequestPermission(PermissionCallbacks permissionCallbacks);/// <summary>/// 判断是否有权限/// </summary>bool IsHasPermission { get; }
}

相关文章:

Unity 权限 之 Android 【权限 动态申请】功能的简单封装

Unity 权限 之 Android 【权限 动态申请】功能的简单封装 目录 Unity 权限 之 Android 【权限 动态申请】功能的简单封装 一、简单介绍 二、Android 权限 动态申请 三、实现原理 四、注意事项 五、案例实现简单步骤 附录&#xff1a; 一、进一步优化 二、多个权限申请…...

跟进2年弄丢1.8亿,你的大客管理错在哪里?

数量并非目的之所在&#xff0c;质量才是根本之道。重视1%的超级用户&#xff0c;才是提高效率的关键所在。 ——凯文凯利 在当今的商业环境中&#xff0c;大客户已成为销售服务型企业最宝贵的资产。他们不仅贡献了企业收入的重要一环&#xff0c;…...

浅说线性DP(上)

前言 在说线性dp之前&#xff0c;我们先来聊一聊动态规划是啥&#xff1f; 动态规划到底是啥&#xff1f; 动态规划是普及组内容中最难的一个部分&#xff0c;也是每年几乎必考的内容。它对思维的要求极高&#xff0c;它和图论、数据结构不同的地方在于它没有一个标准的数学…...

leetcode题目18

四数之和 中等 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xf…...

后端企业级开发之yaml数据序列化格式文件详解2024

yaml格式 数据格式 yaml 是一种数据序列化的格式 容易阅读 容易与脚本语言交互 以数据为核心 重数据轻格式 我们要知道他怎么书写 大小写敏感 属性层级关系使用多行描述 每行结尾使用冒号结束 使用缩进表示层级关系 同层级左侧对其 只运行使用空格 属性前面添加空格 #表…...

智能界面设计:数字孪生与大数据结合的美学典范

智能界面设计&#xff1a;数字孪生与大数据结合的美学典范 引言 在数字化浪潮的推动下&#xff0c;智能界面设计成为了连接用户与技术的重要桥梁。数字孪生技术与大数据的结合&#xff0c;不仅为UI设计带来了前所未有的创新机遇&#xff0c;更成为了美学与功能性融合的典范。…...

听说部门来了个00后测试开发,一顿操作给我整麻了

公司新来了个同事&#xff0c;听说大学是学的广告专业&#xff0c;因为喜欢IT行业就找了个培训班&#xff0c;后来在一家小公司实习半年&#xff0c;现在跳槽来我们公司。来了之后把现有项目的性能优化了一遍&#xff0c;服务器缩减一半&#xff0c;性能反而提升4倍&#xff01…...

Linux shell命令

cat 文件名 查看文件内容&#xff0c; tac文件名 倒着显示。 more 文件名 显示内容 less文件名 和more的功能一样&#xff0c;按上下左右键&#xff0c;按Q键结束。 head文件名&#xff0c;只显示前10行内容。 ln是一个默认创建硬链接的命令 ln 文件名 ls -i文件名…...

【Linux】Linux基本指令1

1.软件&#xff0c;OS&#xff0c;驱动 我们看看计算机的结构层次 1.1.操作系统 操作系统是一款做 软硬件管理 的软件 操作系统&#xff08;计算机管理控制程序&#xff09;_百度百科 (baidu.com) 操作系统&#xff08;英语&#xff1a;Operating System&#xff0c;缩写&a…...

重学java 49 增强for

知之俞明&#xff0c;则行之越笃&#xff1b;行之愈笃&#xff0c;则知之愈益&#xff1b; —— 24.5.28 一、基本使用 1.作用: 遍历集合或者数组 2.格式: for(元素类型 变量名:要遍历的集合名或者数组名) 变量名就是代表的每一个元素 3.快捷键: 集合名或者数组名.for package …...

BUUCTF靶场[Web] [极客大挑战 2019]Havefun1、[HCTF 2018]WarmUp1、[ACTF2020 新生赛]Include

[web][极客大挑战 2019]Havefun1 考点&#xff1a;前端、GET传参 点开网址&#xff0c;发现是这个界面 点击界面没有回显&#xff0c;老规矩查看源代码&#xff0c;看到以下代码 代码主要意思为&#xff1a; 用get传参&#xff0c;将所传的参数给cat&#xff0c;如果catdog…...

现代信号处理11_Spectral Analysis谱分析(CSDN_20240526)

谱分析与傅里叶变换 对于一个信号&#xff0c;一方面可以从时域上对其进行分析&#xff0c;另一方面也可以从频域上对其进行认识&#xff0c;对信号进行频谱分析能够帮助我们了解能量在频域上的分布。 确定性信号的能量通常是有限的&#xff0c;而平稳随机信号的能量通常是无限…...

C#开发上位机应用:基础与实践

C#是一种流行的面向对象编程语言&#xff0c;常用于Windows应用程序的开发。上位机应用是一种用于监控和控制设备或系统的应用程序&#xff0c;通常与下位机&#xff08;如传感器、执行器等&#xff09;进行通信。在本文中&#xff0c;我们将介绍C#开发上位机应用的基础知识和实…...

话术巧妙分隔沟通效果更佳看看这个小技巧

客服回复客户咨询&#xff0c;如果遇到比较复杂的问题&#xff0c;经常会有大段的文字回复&#xff0c;用聊天宝的分段符功能&#xff0c;在需要分段的地方点击右上角的“插入分隔符”&#xff0c;就可以在指定位置分段&#xff0c;实现多段发送的目的。 前言 客服回复客户咨询…...

【Spring】设计模式(GOF)

Spring Framework在其架构和实现中广泛使用了多种GOF&#xff08;Gang of Four&#xff09;设计模式。这些设计模式帮助Spring解决了许多常见的软件开发问题&#xff0c;提高了代码的可重用性、可维护性和可扩展性。 1、工厂模式&#xff08;Factory Pattern&#xff09; 1.1简…...

php抖音详情和关键词搜索api

抖音详情和关键词搜索的 API 可以通过抖音提供的开放平台来获取。以下是使用 PHP 实现的示例代码&#xff1a; 获取抖音视频详情 API&#xff1a; 获取Key和secret请移步 <?php$accessToken YOUR_ACCESS_TOKEN; // 替换为自己的 access_token $itemId YOUR_ITEM_ID; /…...

SOCKS 代理 和 HTTP 代理

SOCKS 代理 和 HTTP 代理 的区别 SOCKS 代理 和 HTTP 代理 都是代理服务器&#xff0c;它们充当客户端和目标服务器之间的中介&#xff0c;但它们的工作方式和应用场景有所不同。 1. SOCKS 代理&#xff1a; 工作原理&#xff1a; SOCKS 代理是一种更底层的代理&#xff0c;…...

【Linux】自己实现一个bash进程

bash就是命令行解释器&#xff0c;就是Linux操作系统让我们看到的&#xff0c;与用户进行交互的一种外壳&#xff08;shell&#xff09;&#xff0c;当然了bash也是一个进程&#xff0c;它有时候就是通过创建子进程来执行我们输入的命令的。这无疑就离不开我们上篇博客所说的进…...

记录深度学习GPU配置,下载CUDA与cuDnn

目标下载: cuda 11.0.1_451.22 win10.exe cudnn-11.0-windows-x64-v8.0.2.39.zip cuda历史版本网址 CUDA Toolkit Archive | NVIDIA Developer 自己下载过11.0.1版本 点击下载local版本,本地安装,有2个多GB,很大,我不喜欢network版本,容易掉线 cuDnn https://developer.nvi…...

Word将表格调成合适的大小

请等待内容完善...

2024HBCPC:C Goose Goose Duck

题目描述 Iris 有 n n n 个喜欢玩鹅鸭杀的朋友&#xff0c;编号为 1 ∼ n 1∼n 1∼n。 假期的时候&#xff0c;大家经常会在群里问有没有人玩鹅鸭杀&#xff0c;并且报出现在已经参与的人数。 但是每个人对于当前是否加入游戏都有自己的想法。 具体的来说&#xff0c;对于第…...

Llama 3 模型家族构建安全可信赖企业级AI应用之使用 Llama Guard 保护大模型对话 (八)

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…...

《一地霜白》读书笔记

1.3.6 街灯明灭&#xff0c;勾缀成行&#xff0c;为了生者与死者 “很多年过去了。回头看&#xff0c;沿着一排暗中的街灯&#xff0c;两三盏灭了&#xff0c;郁闷中有意外的欣喜&#xff1a;街灯明灭&#xff0c;勾缀成行&#xff0c;为了生者与死者。” 童年、青少年在人的…...

在Java中实现多线程之间的通信

一、技术难点 在Java中实现多线程之间的通信是一个复杂但重要的任务&#xff0c;它涉及到线程同步、数据共享和线程间协作等多个方面。以下是实现多线程通信时可能遇到的一些技术难点&#xff1a; 线程同步&#xff1a;多线程环境下&#xff0c;多个线程可能同时访问和修改共享…...

Python中的json.dump与json.dumps对比

Python中的json.dump与json.dumps对比 json.dumps()json.dump() json.dumps() dumps 是 “dump string” 的缩写。它将Python对象转换&#xff08;序列化&#xff09;为JSON格式的字符串。数据被转换为一个字符串&#xff0c;并且这个字符串可以直接被写入文件、发送到网络&am…...

【从零开始学习RabbitMQ | 第二篇】如何确保MQ的可靠性和消费者可靠性

目录 前言&#xff1a; MQ可靠性&#xff1a; 数据持久化&#xff1a; Lazy Queue&#xff1a; 消费者可靠性&#xff1a; 消费者确认机制&#xff1a; 消费失败处理&#xff1a; MQ保证幂等性&#xff1a; 方法一&#xff1a; 总结&#xff1a; 前言&#xff1a; …...

常用批处理命令及批处理文件编写技巧

一常用批处理命令 1.查看命令用法&#xff1a;命令 /? //如&#xff1a;cd /? 2.切换盘符目录&#xff1a;cd /d D:\test 或直接输入 d: //进入上次d盘所在的目录 3.切换目录&#xff1a;cd test 4.清屏:cls 5.“arp -a” //它会列出当前设备缓存中的所有…...

android NetworkMonitor记录

是否能上网的状态 上网url地址的设置&#xff1a; NetworkMonitor.java makeCaptivePortalHttpsUrls config_captive_portal_https_urls DEFAULT_CAPTIVE_PORTAL_HTTPS_URLS http准备监测 isCaptivePortal sendHttpAndHttpsParallelWithFallbackProbes httpsProbe.start();…...

OSPF优化——OSPF减少LSA更新量2

二、特殊区域——优化非骨干区域的LSA数量 不是骨干区域、不能存在虚链路 1、不能存在 ASBR 1&#xff09;末梢区域 该区域将拒绝 4、5LSA的进人&#xff0c;同时由该区域连接骨干0区域的ABR 向该区域&#xff0c;发布一条3类的缺省路由; 该区域内每台路由器均需配置&#xf…...

【AMS】Android 8.0+ 绕开启动后台Service限制

一、背景 应客户要求,需要在开机时,拉起应用A。但因为开机时,同时被拉起的应用过多,导致Launcher在开机那一刻较为卡顿。为解决这一问题,采取了延迟拉起的做法。在开机后,延迟一定时间,由系统服务,拉起应用A。 于是乎,就出现这么个报错: Not allowed to start ser…...