译自 http://developer.android.com/intl/zh-cn/about/versions/android-5.0.html —— By NashLegend
Sample示例在这里找:https://github.com/googlesamples/
原译文在我的github上:https://github.com/NashLegend/ProjectBabel/blob/master/Android%205.0%20APIs.md
前排渣翻译预警,如果你能提供更好更专业的翻译或者提出修改意见就好了……
Android 5.0 (LOLLIPOP) 为用户和开发人员提供了一些新特性,这篇文章将重点介绍一些值得注意的新增API。
如果你已经发布了一款app,请查看这里 Android 5.0 系统行为变化 以适配你的app. 在Android5.0上,即使你没有使用最新API或者新功能,这些新的系统行为仍可能会影响你的app。
如果想看一些新平台的更高级的特性,请看这里
要为Android 5.0开发app,请先使用SDK Mnager下载最新的SDK和系统镜像。
为使得你的app在Android获得更好的表现,请将你的targetSdkVersion设置成21。调用最新的Android 5.0 API的时候要注意在调用前判断系统版本号以兼容之前的系统版本。不能使用低于minSdkVersion的API。详见Android后向兼容性
欲知更多有关API级别的事儿,看这里:啥是API级别
Android 5.0 新增了material design样式的支持. 你可以通过material design创建具有自然的动态效果和过渡风格的app. 系统支持包括以下方面:
系统自带Material design主题
组件阴影
RecyclerView组件以取代ListView
Drawable动画和样式效果。(这里应该是指Ripple Drawable之类)(Drawable animation and styling effects)
Material design风格的动画和activity过渡效果
基于组件状态的Animator。(Animators for view properties based on the state of the view)
可定制的UI组件和工具栏(这里指的应该是ToolBar)
基于XML的矢量动画和图形(Animated and non-animated drawables)
欲知更多有关Material Design的事儿,看这里。
以及我翻译的下面两篇:
在低版本Android上使用Material Design。
如何在你的App中应用Material Design设计风格。
以前的版本中,“最近运行”界面对于一个app来说只能显示用户最近交互过的一个task。现在你的应用可以打开更多task以同时打开不同的文档。这种新的多任务特性可以让用户在最近运行界面中快速在activity们和打开的文档们之间任意切换。有可能使用这种并发任务的情景示例:浏览器标签多开、看比赛多开、生产力工具(比如Word、PPT等)文档多开、多窗口与多个妹子聊天等等。你的app可以通过ActivityManager.AppTask来管理这些task。
要让系统把你的activity当成一个新的task,在startActivity()的时候使用FLAG_ACTIVITY_NEW_DOCUMENT,你也可以在manifest文件中把activity的documentLaunchMode
属性设置成"intoExisting"
或者 "always"
来实现这一点。
为了避免“最近运行”界面太多太乱,你可以设置你的app可以显示在此界面上的最大任务数量——设置manifest文件中 的属性android:maxRecents
,目前的最大数量是每个用户50个,RAM较小的手机则为25个。
最近运行界面上的task可以设置为重启时常驻(persist across reboots),可以设置android:persistableMode属性以控制常驻行为。你也可以通过setTaskDescription()方法修改activity在最近运行界面上的颜色、标签和图标等可见元素。
Android 5.0的WebView升级到了Chromium M37,修复了诸多bug以及带来了安全和稳定性的加强,默认的user-agent也已经升级到了37.0.0.0。
新的WebView引入了PermissionRequest类,可以允许你的app通过类似getUserMedia()赋予WebView摄像头和麦克风的权限——当然前提是你的app也有相应的权限。
使用最新的onShowFileChooser()方法,你可以通过一个input选择设备里的图片和文件了。
此外,新的WebView还带来了对WebAudio,WebGL,WebRTC的支持。欲知更多WebView的新特性,请看这里。
Android 5.0新增android.media.projection API以让你拥有捕获和屏幕分享功能。举个例子,如果你要在视频会议app中添加屏幕分享功能的话,就可以使用这个功能。
新的 createVirtualDisplay() 方法 允许你的app将主屏幕内容(the default display)捕获到一个Surface对象上,这样你的app就可以通过网络对此进行分享。这个API只允许捕获非敏感屏幕内容,不能捕获声音。要进行屏幕捕获,你的app必须要先发起一个对话框请求用户同意,此请求通过发送createScreenCaptureIntent() 方法产生的Intent实现。
你可以查看示例项目的MediaProjectionDemo
来学习如何使用新的API。
从Android 5.0开始可以在锁屏界面上显示通知。用户可以通过设置选择是否允许敏感通知内容显示在安全锁屏界面(secure lock screen)上。
你的应用可以控制通知内容的具体显示级别,通过调用setVisibility()方法传入下面值中的一个:
VISIBILITY_PRIVATE: 显示基本信息,比如说icon,但是隐藏具体内容。
VISIBILITY_PUBLIC: 显示通知的所有内容.
VISIBILITY_SECRET: 不显示任何东西,icon也不显示.
如果你设置的是VISIBILITY_PRIVATE,你可以设置显示敏感内容的替代信息,比如“收到了3条QQ消息”,但是不显示具体消息的联系人。要提供这种显示,首先用Notification.Builder创建一个替代通知。当创建private通知的时候,通过setPublicVersion() 方法将这个替代通知关联到这个隐私通知上。
Android 5.0通过关联在你的通知上的元数据对通知进行智能排序。你可以通过Notification.Builder的下面这些方法设置这些元数据:
setCategory(): 告诉系统当设备处于优先模式(比如这个通知表明来电、即时消息或者闹钟)时如何处理通知。
setPriority(): 标记此通知的重要程度——是否比普通通知要高或者低。拥有PRIORITY_MAX 或者 PRIORITY_HIGH级别的通知在有声音或者振动的情况下,会弹出一个浮动窗口。
addPerson(): 允许你添加一个或者多个与此通知相关联的人。这样系统可以根据不同的人把通知分开,并按人物重要性排序。
Android 5.0为OpenGL ES 3.1增加java接口和native支持。3.1重要的新增功能包括:
计算着色器(Compute Shaders)
独立的着色器对象
间接呼叫指令
多重采样和模版纹理
着色语言改进
高级混合模式和调试扩展。
对OpenGL ES 2.0 和 3.0和后向兼容性
OpenGL ES 3.1 的java接口是GLES31。使用OpenGL ES 3.1的时候,请在manifest里面使用标签及android:glEsVersion
属性声明之,例如:
<manifest> <uses-feature android:glEsVersion="0x00030001" /> ... </manifest>
欲知更多OpenGL ES的信息,包括设备对OpenGL支持的版本,请看OpenGL ES指南。
除了OpenGL ES 3.1,这个版本还提供了拥有java接口和native支持的扩展包以提供高级图形功能。这个扩展包作为一个独立的包发布
扩展包支持:
这块儿不懂
Guaranteed fragment shader support for shader storage buffers, p_w_picpaths, and atomics (Fragment shader support is optional in OpenGL ES 3.1.) Tessellation and geometry shaders ASTC (LDR) texture compression format Per-sample interpolation and shading Different blend modes for each color p_w_upload in a frame buffer
The Java interface for the extension pack is provided with GLES31Ext. In your app manifest, you can declare that your app must be installed only on devices that support the extension pack. For example:
<manifest> <uses-feature android:name=“android.hardware.opengles.aep” android:required="true" /> ... </manifest>
Android 5.0引入了新的android.hardware.camera2 API以帮助fine-grain照片捕捉和图像处理,你可以编程的方式通过调用getCameraIdList() 获取系统的可用相机设备列表并通过。你可以通过 openCamera() 方法指定其中一个相机设备。要捕捉图像,创建一个CameraCaptureSession并将捕获到的图像绘制到一个Surface对象上。 CameraCaptureSession可设置为单拍或者一次性连拍多张(take single shots or multiple p_w_picpaths in a burst)。
需要继承CameraCaptureSession.CaptureCallback类并设置到图像捕获请求里以获得图像捕获完成事件。当系统完成图像捕获的时候,CameraCaptureSession.CaptureCallback将接到一个onCaptureCompleted()回调,返回给你一个包含图像元数据的 CaptureResult。
CameraCharacteristics类可以让你的app检查此设备的相机支持哪些特性。此对象的INFO_SUPPORTED_HARDWARE_LEVEL属性表示相机功能级别。
所有的设备至少可达到INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY级别的硬件支持,此级别功能大致相当于已弃用的Camera API(注:此API在API21开始弃用)。
达到INFO_SUPPORTED_HARDWARE_LEVEL_FULL级别硬件支持的设备可以手动控制图像的捕捉和后期处理以及以高帧频捕获高分辨率的图像。
要查看如何使用最新的camera2 API,请查看SDK示例中的Camera2Basic
和 Camera2Video
此版本包含AudioTrack的以下变化:
你的app现在可以用浮点格式(ENCODING_PCM_FLOAT)提供音频数据。可以获得更大的动态范围,more consistent precision和greater headroom。浮点运算在中间值计算(intermediate calculation)的时候尤其有用。Playback endpoints use integer format for audio data, and with lower bit depth. (In Android 5.0, portions of the internal pipeline are not yet floating point.)
你现在可以ByteBuffer方式提供音频数据,就像提供给MediaCodec的数据一样。
WRITE_NON_BLOCKING模式可以帮助某些app简化缓冲和多线程工作(simplify buffering and multithreading)。
使用新的通知和媒体API以确保系统UI知道你的媒体播放情况并提取和显示专辑信息。使用新的MediaSession 和MediaController类可使得通过UI和service控制播放变得更加简单。
新的MediaSession类取代了已弃用的RemoteControlClient,它提供一套回调方法以处理各种播放行为(差不多这么翻译吧,无非是快进快退暂停以及其他控制等等) (transport controls and media buttons)。如果你的app提供媒体播放功能并且运行在Android TV或者Wear平台上,也可以通过MediaSession类使用相同的回调方法处理播放行为(transport controls)。
现在你可以使用MediaController类创建自己的媒体控制器app。这个类提供了一个线程安全的方式以在你的UI线程上监控和控制媒体的播放行为。创建控制器的时候,指定一个MediaSession.Token对象以便与给定的MediaSession交互。
通过使用MediaController.TransportControls方法,你可以传达诸如 play(), stop(), skipToNext(), 和 setRating()命令以控制MediaSession上的媒体播放。你也可以注册一个MediaController.Callback回调对象以监听session上的元数据和状态变化(metadata and state changes)。
此外,你还可以通过最新的Notification.MediaStyle类创建rich notification以控制mediasession播放。
Android 5.0引入了新的android.media.browse API,你的app可以使用此api浏览其他app的媒体库。继承MediaBrowserService类以对外暴露你的app的媒体内容。你继承的MediaBrowserService应该提供MediaSession.Token的接入口以便其他应用可以通过它播放你提供的媒体内容。
若要与媒体浏览服务交互,请使用MediaBrowser类。创建MediaBrowser实例时,请为MediaSession指定一个组件名。通过这个MediaBrowser实例,你的app可以连接到关联的service并获得一个暴露出来的MediaSession.Token对象。
Android 5.0扩展了存储框架(Storage Access Framework),用户可以借此将一个文件夹(包括其子文件和文件夹)的读写权限赋予一个app。
要选择一个文件夹,请发出一条OPEN_DOCUMENT_TREE intent 即可。系统会列出所有支持文件夹选择的DocumentsProvider来让用户浏览并选择一个文件夹,返回值是选中的文件夹的URI。然后你就可以使用buildChildDocumentsUriUsingTree() 、 buildDocumentUriUsingTree() 和 query() 浏览此文件夹的子目录了。
新的 createDocument() 方法使得你可以在上面选择的文件夹及其子文件夹下面创建新文档或者文件夹。要操作已经存在的文件,请使用 renameDocument() 和 deleteDocument(). 调用这此方法之前先检查 COLUMN_FLAGS 以确定provider对这些方法是否。分别是:FLAG_SUPPORTS_WRITE,FLAG_SUPPORTS_DELETE,FLAG_SUPPORTS_THUMBNAIL,FLAG_DIR_PREFERS_GRID,FLAG_DIR_PREFERS_LAST_MODIFIED)。
如果你实现了一个DocumentsProvider并且想要支持子目录选择,请实现isChildDocument()方法并将FLAG_SUPPORTS_IS_CHILD放到COLUMN_FLAGS里。
Android 5.0同时也引入了新的共享存储区上的package-specific目录,你可以在为里存储媒体文件,这些媒体文件可以被包含进MediaStore里,新的 getExternalMediaDirs()方法返回你的app在所有共享存储设备上的媒体存储目录。像getExternalFilesDir()一样不需要特殊权限。系统会定时扫描这些文件夹中的媒体内容,当然你也可以使用MediaScannerConnection自行扫描新内容。(大哥们不要把缓存的图片放这儿啊,好想把那些将缓存图片直接放到sd卡某个目录下的人拉出来打一顿)
Android 5.0支持新的多网络连接API以使你的app可以根据特定功能(with specific capabilities)动态扫描可用的网络并建立连接。当你的app需要指定网络——SUPL(无线位置服务), 彩信或者运营商计费网络——才能用或者要通过一个特定的协议才能传输你的数据的时候,这个功能就派上用场了。
你的app动态选择并连接一个网络连接的步骤如下:
新建一个ConnectivityManager.
使用NetworkRequest.Builder 类创建一个NetworkRequest对象并指定你的app需要的网络特性和传输类型。
要扫描合适的网络,请调用requestNetwork() 或者 registerNetworkCallback(), 并将NetworkRequest对象和一个ConnectivityManager.NetworkCallback作为参数传过去。如果你要在合适的网络被扫描到之后就切换到这个网络,请调用用 requestNetwork() 方法 如果仅仅接收扫描结果而不切换网络的话,请使用registerNetworkCallback() 方法. 当系统探测到一个合适的网络时连接到这个网络并调用onAvailable()方法。你可以使用这个方法传进来的Network对象得到这个网络更多的信息或者使用此网络。
(表示不懂……)
Android 4.3引入了对Bluetooth Low Energy (Bluetooth LE)的平台支持in the central role(咋理解)。从Android 5.0开始,Android设备可以像低功耗蓝牙外设一样了。应用可以使用些功能使得附近的设备探测到你的存在。比如说,你可以创建一个计步器应用或者健康状况监视应用并与另外一个低功耗蓝牙外设建立数据连接。
使用新的android.bluetooth.le API,你的app可以广播广告(broadcast advertisements)、扫描响应(scan for responses)并与附近的低功耗蓝牙设备连接。要使用新的广播和扫描特性,请在manifest文件中添加BLUETOOTH_ADMIN权限。当用户下载或者更新你的app时,会被请求允许这些权限。
要开始Bluetooth LE advertising以便别的设备可以发现你的app,请调用startAdvertising()将一个AdvertiseCallback作为参数传进去。这个callback对象会接收advertising功能或者失败的消息。
Android 5.0 引入了ScanFilter,这样你的app就可以只搜索你需要的特定类型的设备。调用startScan()方法并传递进一个filter列表以扫描低功耗蓝牙设备——你必须提供一个ScanCallback以在Bluetooth LE advertisement被发现后可以报告。(............)
Android 5.0对NFC进行了以下增强以使其得以更广泛和灵活的应用:
Android Beam 可以在分享按钮中使用了。
你的应用可以通过invokeBeam()调用Android Beam以分享数据。避免了用户必须自己手动操作设备以来分享数据的麻烦。
你现在可以使用createTextRecord()方法创建包含UTF-8文本格式数据的NDEF记录。
如果你在开发一款支付类应用,你现在可以对过调用registerAidsForService()以动态地注册一个NFC应用ID(AID)。你也可以使用setPreferredService()方法用于在某个特定的acitivy处于前台时指定一个偏好的Card Emulation服务。
除了新特性之外(?),Android 5.0还重点突出了对电池寿命的提升(emphasizes improvements in battery life)。使用新的API和工具可以查看并优化你的app的电量使用。
Android 5.0提供一个新的JobScheduler API以让你通过使系统推迟一些时间或者在特定条件下(比如充电中)异步执行某些任务以优化电池寿命。在下面情况下这很有用。
应用有可延后执行的后台任务。
应用有你想在充电时才执行的任务。
应用有需要网络或者WIFI才能执行的任务。
应用有一些要定期统一执行(run as a batch on a regular schedule)的任务。
一批任务(A unit of work)同一个JobInfo对象封装,这个对象指定了任务如何安排。
使用JobInfo.Builder类来设置如何安排这些任务的运行时刻表,你可以安排任务在正面情况下运行,比如:
设备充电时开始执行。
设备连接到非计费网络时开始执行。
设置空闲时开始执行。
在某个deadline前或者某个delay后结束执行。
举例,如果你想在设备连接到非计费网络时执行,可以这样做:
JobInfo uploadTask = new JobInfo.Builder(mJobId, mServiceComponent /* JobService component */) .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) .build(); JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(uploadTask);
如果设备有一个稳定的电源(进入充电状态超过两分钟并且电量处于健康水平),系统就会执行被安排好的任务,即使该任务的deadline还没有过期(???even if the job’s deadline has not expired)。
要查看如何使用JobScheduler API,请查看Sample中的JobSchedulerSample。
新的dumpsys batterystats
命令可以返回你感兴趣的按唯一的UID组织的电量使用数据。数据包括以下几方面:
电池相关事件历史。
设备的全局数据。
每个UID和系统组件的粗略的电量使用。
Per-app mobile ms per packet
系统UID总数据。
应用UID总数据。
使用--help
可以学习更多的参数选项以输出你想要的数据。比如,要输出上次充电后某个指定app的电量使用数据,执行如下命令:
$ adb shell dumpsys batterystats --charged <package-name>
你可以对上面的命令的输出数据使用Battery Historian工具来生成HTML页面以方便查看。
(不知所云,一片胡扯,译者处于昏迷状态)
Android 5.0 为在办公环境中运行的app提供了新的功能。如果用户已经在设备上有了一个个人账户,设备管理员可以启动一个管理配置进程(managed provisioning process)以再添加一个共存但是相互独立的profile。受管理的profiles关联的app与非受管理的app并列出现在Launcher、最近任务和通知里面。
要启动管理配置进程,发起一个ACTION_PROVISION_MANAGED_PROFILE Intent。如果调用成功的话,系统回调onProfileProvisioningComplete()。然后你可以调用setProfileEnabled() 来启动这个受管理的profile。
默认情况下,在受管理的profile里面只有很少的app可用。你可以在受管理profile里面调用enableSystemApp()来使其他app在包含进profile中。
如果你在开发一款Launcher程序,可以使用新的LauncherApps类来获取可展示到Launcher上的的activity列表——当然只能是属于当前用户和相关的受管理的profiles的。你的Launcher可以通过加入一个工作标志来使得使受管理的app突出显示出来,通过getUserBadgedIcon()方法可以取得这种带标志的图标。
查看Sample中的BasicManagedProfile
来学习如何使用这些新功能。
Android 5.0 引入了可以部署设备所有者
app的能力,设备所有者
是一个拥有创建和删除子用户以及配置全局设置的特殊类型的(specialized type)设备管理员。你的所有者应用可以使用DevicePolicyManager里面的方法的对设备配置、安全策略的应用进行细粒度的控制(take fine-grain control)。一个设备在同一时间只能有一个活动的设备所有者。
要部署并激活设备所有者,在设备的unprovisioned状态下,进行从一个编程应用(programming app)到设备NFC数据传输。传输的数据和上面刚刚提到的provisioning intent中的数据相同。
Android 5.0 引入了新的屏幕固定API,可以让用户暂时限制在一个任务中无法离开,此时也不会被通知所干扰。如果你正在开发一款教育应用以在Android支持高风险的评估要求或者目的单一的或者Kiosk应用程序(an education app to support high stakes assessment requirements on Android, or a single-purpose or kiosk application——这啥意思,口吐白沫中)的时候,你就可以考虑使用这个API。一旦你的app启动了屏幕固定,用户就将看不到通知、打开其他app或者返回桌面,直到退出这种模式。
有两种方式启动屏幕固定:
手动固定:用户可以拖动开启屏幕固定。设置>安全>屏幕固定,然后选择在最近任务界面选择在固定的任务。
编程固定:要通过编码实现屏幕固定,在你的app中调用startLockTask()方法。如果请求的app不是设备所有者(device owner),用户会被弹出一个询问提示。设备所有者可以调用setLockTaskPackages()方法以使得某个app可以不经过用户确认就进步屏幕固定状态。
任务锁定后,会:
状态栏变空,用户通知和状态信息被隐藏。
主屏幕和最近任务按钮被隐藏。
其他app打不开新的activity。
只要不开启新的task,当前app可以打开新的activity。
如果屏幕固定是由设备所有者启动,用户仍旧会锁定在你的app下直到调用了stopLockTask()。
如果屏幕固定由非设备所有者启动或者由用户手动启动,用户可以通过同时按住返回的最近任务按钮退出(the user can exit by holding both the Back and Recent buttons)
现在可以用新的PdfRenderer类将PDF页面渲染成bitmap来渲染。必须指定一个可搜索(内容可以随机访问)的ParcelFileDescriptor,系统会在它上面写入可打印数据。通过调用openPage()方法,你的app可以得到一个待渲染页面,然后调用render()以将打开的PdfRenderer.Page渲染到一个bitmap上。如果你想只转换此文档的一部分的话,要传入额外的一些参数。
要查看如何使用新的API,请查看Sample里面的PdfRendererBasic
。
现在你可以使用android.app.usage API获取Android设备的app使用历史。这个API提供了比已经弃用的getRecentTasks()方法更详细的使用数据。要使用这个API,首先要在manifest中添加android.permission.PACKAGE_USAGE_STATS
权限,用户可以通过Settings > Security > Apps赋予此app的读取app使用数据的权限.
系统按应用分别收集使用数据,并且按天、周、月、年整合数据。系统保存数据的最长时间如下:
Daily data: 7天
Weekly data: 4周
Monthly data: 6个月
Yearly data: 2年
对于每个应用,系统记录如下数据:
应用上次使用时间。
对应时间段内应用前台运行总时间(by day, week, month, or year)。
一个组件(按包名和activity名区分)在一天内被移动到前台或者后台的Timestamp capturing。
设备设置改变(比如屏幕方向改变)的Timestamp capturing。
Android 5.0为测试和可访问性增加如下支持:
新的getWindowAnimationFrameStats()和getWindowContentFrameStats()方法可以捕获窗口动画和内容的帧数据。这些方法使你可以编写instrumentation tests以评估app是否流畅。
新的executeShellCommand()方法让你可以在instrumentation test中执行shell命令。类似于执行 adb shell,这样你可以使用一些shell工具比如dumpsys, am, content
和pm
.
使用accessibility APIs(比如UiAutomator)的Accessibility Service和测试工具现在可以取得屏幕上能够进行可见交互的窗口的详细信息。要获得AccessibilityWindowInfo对象列表,请调用 getWindows()方法。
新的AccessibilityNodeInfo.AccessibilityAction类让你可以在AccessibilityNodeInfo上执行标准的或者自定义的动作。新的 AccessibilityNodeInfo.AccessibilityAction类取代了AccessibilityNodeInfo中的早期action API。
Android 5.0使你的app可以对文字转语音(text-to-speech synthesis)进行更细粒度的控制。有了新的Voice类,你的App可以通过指定地区, 质量和延迟率来设置声音,也可以使用文字转语音引擎相关的特定特性(text-to-speech engine-specific parameters)。
这块不翻译了,标题说的很明确了,但是输入法右下角那个切换按钮总是误触好蛋疼啊~摔~
下面的一些特性已经开始在<uses-feature>
中支持,所以你可以确认你的app是否安装在支持你所需特性的设备上。
FEATURE_AUDIO_OUTPUT
FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING
FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR
FEATURE_CAMERA_CAPABILITY_RAW
FEATURE_CAMERA_LEVEL_FULL
FEATURE_GAMEPAD
FEATURE_LIVE_TV
FEATURE_MANAGED_USERS
FEATURE_LEANBACK
FEATURE_OPENGLES_EXTENSION_PACK
FEATURE_SECURELY_REMOVES_USERS
FEATURE_SENSOR_AMBIENT_TEMPERATURE
FEATURE_SENSOR_HEART_RATE_ECG
FEATURE_SENSOR_RELATIVE_HUMIDITY
FEATURE_VERIFIED_BOOT
FEATURE_WEBVIEW
现在<uses-permission>
已经支持下面的权限,如果你需要的话就加上它吧。
BIND_DREAM_SERVICE: 如果目标API是21或更高, Daydream服务需要使用这个权限。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。