Unity开发之Android必要的基础知识(二)

AndroidManifest清单文件(一)

Posted by 打个大西瓜 on August 17, 2022 16:40:22

AndroidManifest清单文件(一)

官方文档

概念

清单文件用于向 Android 构建工具、Android 操作系统和 Google Play 描述应用的基本信息

划重点,清单文件需声明以下内容:

  • 声明包名、icon、SDK等等应用信息: 应用的软件包名称,其通常与代码的命名空间相匹配。 构建项目时,Android 构建工具会使用此信息来确定代码实体的位置。 打包应用时,构建工具会使用 Gradle 构建文件中的应用 ID 来替换此值,而此 ID 则用作系统和 Google Play 上的唯一应用标识符。

  • 注册四大组件: 应用的组件,包括所有 Activity、Service、Broadcast reciver和Content provider。 每个组件都必须定义基本属性,例如其 Kotlin 或 Java 类的名称。 清单文件还能声明一些功能,例如其所能处理的设备配置,以及描述组件如何启动的 Intent 过滤器。

  • 申请必要的权限: 应用为访问系统或其他应用的受保护部分所需的权限。 如果其他应用想要访问此应用的内容,则清单文件还会声明其必须拥有的权限。

  • 应用需要的硬件和软件功能: 这些功能会影响哪些设备能够从 Google Play 安装应用

标签

官方文档 对于在应用中创建的每个应用组件,您必须在清单文件中声明相应的 XML 元素:

  • <activity> 用于 Activity 的每个子类。
  • <service> 用于 Service 的每个子类。
  • <receiver> 用于 BroadcastReceiver 的每个子类。
  • <provider> 用于 ContentProvider 的每个子类。

如果您创建此类组件的任何子类,但未在清单文件中对其进行声明,则系统便无法启动该子类。

这是一份从unity导出的Android工程中的清单文件

<?xml version="1.0" encoding="utf-8"?>
<!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools">
  <application android:isGame="true">
    <uses-library
        android:name="org.apache.http.legacy"
        android:required="false" />
    <activity android:name="com.unity3d.player.UnityPlayerActivity" android:theme="@style/UnityThemeSelector" android:screenOrientation="sensorPortrait" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:resizeableActivity="false" android:hardwareAccelerated="false" android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
      <meta-data android:name="android.notch_support" android:value="true" />
    </activity>
    <meta-data android:name="unity.splash-mode" android:value="0" />
    <meta-data android:name="unity.splash-enable" android:value="True" />
    <meta-data android:name="unity.allow-resizable-window" android:value="False" />
    <meta-data android:name="notch.config" android:value="portrait|landscape" />
    <meta-data android:name="unity.build-id" android:value="20d9d69c-7bcf-4746-ac6b-9dff6c6c7753" />
    <!-- Google Play Services -->
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

    <!--添加Google AdMob App ID-->
    <!--官方测试APPID,正式上线更换-->
    <meta-data
        android:name="com.google.android.gms.ads.APPLICATION_ID"
        android:value="xxxxxxxxxxxxxxxxxxxxxx"/>
    <!--AppLovin -->
    <!--添加您的Applovin SDK Key-->
    <meta-data
        android:name="applovin.sdk.key"
        android:value="xxxxxxxxxxxxxxxxxxxxxxxxxxxx"  />
  </application>
  <uses-feature android:glEsVersion="0x00020000" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-feature android:name="android.hardware.location.gps" android:required="false" />
  <uses-feature android:name="android.hardware.location" android:required="false" />
  <uses-feature android:name="android.hardware.sensor.accelerometer" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
</manifest>

applicaltion标签

二级标签,配置项目级的参数,如 debuggable、enabled、description 和 allowClearUserData,或者为组件属性设置全局默认值,且组件可以再自己的标签内定义覆盖,比如icon、label等。

一般情况下不需要更改

咱们也可以自定义一个 MyApplication 类继承自 Application 类来在应用启动时做些业务,然后在清单中applicaltion标签下设置 android:name=.MyApplication属性来告诉系统用自定义的application类启动

包含于:
 <manifest>
可包含:
<activity>
<activity-alias>
<meta-data>
<service>
<receiver>
<profileable>
<provider>
<uses-library>
<uses-native-library>

activity标签

如果是由Unity导出,默认只会有一个UnityPlayerActivity作为启动Activity,咱们游戏的主要业务都会在这个activity中

但是通常会定义一个SplashActivity作为启动的Activity,用于在进入到游戏业务前做一些业务,比如第三方sdk的初始化,权限申请,原生androidAPI调用之类的工作,然后再跳转到UnityPlayerActivity

UnityPlayerActivity这个类是不建议修改的,但是某些业务游戏要在UnityPlayerActivity生命周期中添加业务代码,尤其是第三方sdk的业务,这个时候就需要定义一个MainActivity继承自UnityPlayerActivity,然后在MainActivity中重写生命周期方法,添加自己的业务代码,同时别忘了在清单中注册MainActivity


<activity> 包含于 <application>

<activity> 可包含

<intent-filter>
<meta-data>
<layout>

以上面清单中的activity标签为例

    <activity 
        android:name="com.unity3d.player.UnityPlayerActivity" 
        android:theme="@style/UnityThemeSelector" 
        android:screenOrientation="sensorPortrait"
        android:launchMode="singleTask" 
        android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" 
        android:resizeableActivity="false" 
        android:hardwareAccelerated="false" 
        android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
      <meta-data android:name="android.notch_support" android:value="true" />
    </activity>

android:configChanges 属性

这里有一大堆配置项,按官方说法,这个属性列出了 Activity 将自行处理的配置变更。在运行时发生配置变更时,默认情况下会关闭 activity 并将其重启,但使用该属性声明配置将阻止 activity 重启。相反,Activity 会保持运行状态,并且系统会调用其 onConfigurationChanged() 方法。

以下是该属性的有效值,若要配置多个则用 “ | ” 分割

说明
density 显示密度发生变更 - 用户可能已指定不同的显示比例,或者有不同的显示现处于活跃状态。在 API 级别 24 中引入
fontScale 字体缩放系数发生变更 - 用户已选择新的全局字号。
keyboard 键盘类型发生变更 - 例如,用户插入外置键盘。
keyboardHidden 键盘无障碍功能发生变更 - 例如,用户显示硬键盘。
layoutDirection 布局方向发生变更 - 例如,自从左至右 (LTR) 更改为从右至左 (RTL)。在 API 级别 17 中引入。
locale 语言区域发生变更 - 用户已为文本选择新的显示语言。
mcc IMSI 移动设备国家/地区代码 (MCC) 发生变更 - 检测到 SIM 并更新 MCC。
mnc IMSI 移动设备网络代码 (MNC) 发生变更 - 检测到 SIM 并更新 MNC。
navigation 导航类型(轨迹球/方向键)发生变更。(这种情况通常不会发生。)
orientation 屏幕方向发生变更 - 用户旋转设备。 ( 注意:如果应用面向 Android 3.2(API 级别 13)或更高版本的系统,则还应声明 “screenSize” 和 “screenLayout” 配置,因为当设备在纵向模式与横向模式之间切换时,该配置也会发生变更。 )
screenLayout 屏幕布局发生变更 - 现处于活跃状态的可能是其他显示模式。
screenSize 当前可用屏幕尺寸发生变更。该值表示目前可用尺寸相对于当前宽高比的变更,当用户在横向模式与纵向模式之间切换时,它便会发生变更。在 API 级别 13 中引入。
smallestScreenSize 物理屏幕尺寸发生变更。该值表示与方向无关的尺寸变更,因此它只有在实际物理屏幕尺寸发生变更(如切换到外部显示器)时才会变化。对此配置所作变更对应 smallestWidth 配置的变化。 在 API 级别 13 中引入。
touchscreen 触摸屏发生变更。(这种情况通常不会发生。)
uiMode 界面模式发生变更 - 用户已将设备置于桌面或车载基座,或者夜间模式发生变更。如需了解有关不同界面模式的更多信息,请参阅 UiModeManager。在 API 级别 8 中引入。

android:exported 属性

此元素设置 Activity 是否可由其他应用的组件启动

  • 如果设为“true”,那么 Activity 可由任何应用访问,并且可通过其确切类名称启动。
  • 果设为“false”,则 Activity 只能由同一应用的组件、使用同一用户 ID 的不同应用或具有特权的系统组件启动。 没有 intent 过滤器时,这是默认值。

如果应用中的 Activity 包含 intent 过滤器,请将此元素设置为“true”,以允许其他应用启动该 Activity。例如,假设 Activity 是应用的主要 Activity,并且包含 category“android.intent.category.LAUNCHER”。

android:launchMode 属性

启动模式,有机会另起一篇,对于Unity导出,没特殊情况,使用默认的 singleTask 即可

还有很多属性,详情可参考 官方文档

intent-filter 标签

必须包含 <action>

可包含 <category> <data>

一般包含于四大组件的标签中,指定 Activity、服务或广播接收器可以响应的 intent 类型。Intent 过滤器声明其父组件的功能 - Activity 或服务可执行哪些操作,以及接收器可处理哪些类型的广播。它让组件可以接收所通告类型的 Intent,同时过滤掉对组件没有意义的 Intent。

过滤器的大部分内容由它的 <action>、<category><data> 子元素进行描述。

简单的开发只需要了解 <action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />

<action android:name="android.intent.action.MAIN" /> 指定了程序的启动Activity,

<category android:name="android.intent.category.LAUNCHER" /> 决定了是否会在程序列表里面显示,也就是会不会出现在手机桌面上,声明了这个属性就会在桌面上出现图标,多个Activity的 <intent-filter> 声明了这个 category 就会在桌面显示多个图标

meta-data标签

 <meta-data 
    android:name="mymeta-Data"           
    android:resource="resource specification"           
    android:value="string" />

元数据标签,可以包含于任意组件标签且可以有任意数量

主要作用就是存储信息,整个应用都可以访问,有点类似配置表,最常见是就是在接入第三方sdk时会要求加入 meta-data 标签记录 APPKEY

那怎么读取呢

ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
Bundle bundle = ai.metaData;
String myApiKey = bundle.getString("mymeta-Data");