当前位置:首页 » 安卓系统 » android监听电源键

android监听电源键

发布时间: 2023-01-11 00:47:21

Ⅰ 9按android手机的电源键来黑屏和点亮屏幕,可以对app的功能产生影响,这里应用的技术是

消除 activity 启动时白屏、黑屏问题

安卓源代码修改之framework下面长按power键,修改安卓原生的关机、重启界面(二)

修改Android系统长按关机时间,或禁用长按关机

Android 实现KeyguardView 锁屏界面横屏显示

Android源码解析(二十八)-->电源开关机按键事件

Ⅱ Android启动过程深入解析

当按下Android设备电源键时究竟发生了什么?

Android的启动过程是怎么样的?

什么是linux内核?

桌面系统linux内核与Android系统linux内核有什么区别?

什么是引导装载程序?

什么是Zygote?

什么是X86以及ARM linux?

什么是init.rc?

什么是系统服务?

当我们想到Android启动过程时,脑海中总是冒出很多疑问。本文将介绍Android的启动过程,希望能帮助你找到上面这些问题的答案。

Android是一个基于Linux的开源操作系统。x86(x86是一系列的基于intel 8086 CPU的计算机微处理器指令集架构)是linux内核部署最常见的系统。然而,所有的Android设备都是运行在ARM处理器(ARM 源自进阶精简指令集机器,源自ARM架构)上,除了英特尔的Xolo设备(http://xolo.in/xolo-x900-features)。Xolo来源自凌动1.6GHz x86处理器。Android设备或者嵌入设备或者基于linux的ARM设备的启动过程与桌面版本相比稍微有些差别。这篇文章中,我将解释Android设备的启动过程。深入linux启动过程是一篇讲桌面linux启动过程的好文。

当你按下电源开关后Android设备执行了以下步骤。

此处图片中step2中的一个单词拼写错了,Boot Loaeder应该为Boot Loader(多谢@jameslast 提醒)

第一步:启动电源以及系统启动

当电源按下,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM,然后执行。

第二步:引导程序

引导程序是在Android操作系统开始运行前的一个小程序。引导程序是运行的第一个程序,因此它是针对特定的主板与芯片的。设备制造商要么使用很受欢迎的引导程序比如redboot、uboot、qi bootloader或者开发自己的引导程序,它不是Android操作系统的一部分。引导程序是OEM厂商或者运营商加锁和限制的地方。

引导程序分两个阶段执行。第一个阶段,检测外部的RAM以及加载对第二阶段有用的程序;第二阶段,引导程序设置网络、内存等等。这些对于运行内核是必要的,为了达到特殊的目标,引导程序可以根据配置参数或者输入数据设置内核。

Android引导程序可以在找到。

传统的加载器包含的个文件,需要在这里说明:

init.s初始化堆栈,清零BBS段,调用main.c的_main()函数;

main.c初始化硬件(闹钟、主板、键盘、控制台),创建linux标签。

更多关于Android引导程序的可以在这里了解。

第三步:内核

Android内核与桌面linux内核启动的方式差不多。内核启动时,设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动root进程或者系统的第一个进程。

第四步:init进程

init是第一个进程,我们可以说它是root进程或者说有进程的父进程。init进程有两个责任,一是挂载目录,比如/sys、/dev、/proc,二是运行init.rc脚本

init进程可以在/system/core/init找到。

init.rc文件可以在/system/core/rootdir/init.rc找到。

readme.txt可以在/system/core/init/readme.txt找到。

对于init.rc文件,Android中有特定的格式以及规则。在Android中,我们叫做Android初始化语言。

Action(动作):动作是以命令流程命名的,有一个触发器决定动作是否发生。

语法

1

2

3

4

5

; html-script: false ]

on <trigger>

<command>

<command>

<command>

Service(服务):服务是init进程启动的程序、当服务退出时init进程会视情况重启服务。

语法

1

2

3

4

5

; html-script: false ]

service <name> <pathname> [<argument>]*

<option>

<option>

...

Options(选项)

选项是对服务的描述。它们影响init进程如何以及何时启动服务。

咱们来看看默认的init.rc文件。这里我只列出了主要的事件以及服务。

Table

Action/Service

描述

on early-init

设置init进程以及它创建的子进程的优先级,设置init进程的安全环境

on init

设置全局环境,为cpu accounting创建cgroup(资源控制)挂载点

on fs

挂载mtd分区

on post-fs

改变系统目录的访问权限

on post-fs-data

改变/data目录以及它的子目录的访问权限

on boot

基本网络的初始化,内存管理等等

service servicemanager

启动系统管理器管理所有的本地服务,比如位置、音频、Shared preference等等…

service zygote

启动zygote作为应用进程

在这个阶段你可以在设备的屏幕上看到“Android”logo了。

第五步

java中,我们知道不同的虚拟机实例会为不同的应用分配不同的内存。假如Android应用应该尽可能快地启动,但如果Android系统为每一个应用启动不同的Dalvik虚拟机实例,就会消耗大量的内存以及时间。因此,为了克服这个问题,Android系统创造了”Zygote”。Zygote让Dalvik虚拟机共享代码、低内存占用以及最小的启动时间成为可能。Zygote是一个虚拟器进程,正如我们在前一个步骤所说的在系统引导的时候启动。Zygote预加载以及初始化核心库类。通常,这些核心类一般是只读的,也是Android SDK或者核心框架的一部分。在Java虚拟机中,每一个实例都有它自己的核心库类文件和堆对象的拷贝。

Zygote加载进程

加载ZygoteInit类,源代码:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

registerZygoteSocket()为zygote命令连接注册一个服务器套接字。

preloadClassed “preloaded-classes”是一个简单的包含一系列需要预加载类的文本文件,你可以在/frameworks/base找到“preloaded-classes”文件。

preloadResources() preloadResources也意味着本地主题、布局以及android.R文件中包含的所有东西都会用这个方法加载。

在这个阶段,你可以看到启动动画。

第六步:系统服务或服务

完成了上面几步之后,运行环境请求Zygote运行系统服务。系统服务同时使用native以及java编写,系统服务可以认为是一个进程。同一个系统服务在Android SDK可以以System Services形式获得。系统服务包含了所有的System Services。

Zygote创建新的进程去启动系统服务。你可以在ZygoteInit类的”startSystemServer”方法中找到源代码。

核心服务:

启动电源管理器;

创建Activity管理器;

启动电话注册;

启动包管理器;

设置Activity管理服务为系统进程;

启动上下文管理器;

启动系统Context Providers;

启动电池服务;

启动定时管理器;

启动传感服务;

启动窗口管理器;

启动蓝牙服务;

启动挂载服务。

其他服务:

启动状态栏服务;

启动硬件服务;

启动网络状态服务;

启动网络连接服务;

启动通知管理器;

启动设备存储监视服务;

启动定位管理器;

启动搜索服务;

启动剪切板服务;

启动登记服务;

启动壁纸服务;

启动音频服务;

启动耳机监听;

启动AdbSettingsObserver(处理adb命令)。

第七步:引导完成

一旦系统服务在内存中跑起来了,Android就完成了引导过程。在这个时候“ACTION_BOOT_COMPLETED”开机启动广播就会发出去。

Ⅲ 如何在android 中service后台监听按键,比如监听音量键

为了实现键盘的监控,从新开发一个输入法是不现实的,一般的操作就是在系统的输入法机制中添加接口回调。我们知道,再应用程序中拿到按键的回调一般是监听onKeyDown的接口,如下所示:publicbooleanonKeyDown(intkeyCode,KeyEventevent)开发者就可以根据回调方法中的参数,keyCode与KeyEvent来判断具体事件。但是,由于事件的回调机制在其的沙箱中运行,在其他应用中是无法拿到当前应用事件回调的。那么我们就从上到下,具体的看看事件的传递机制。如下图所示,用户点击后,软键盘或物理按键的输入驱动就会产生一个中断,且向/dev/input/event*中写入一个相应的信号量。Android操作系统则会循环的读取其中的事件,再分发给WindowManagerServer。由WindowManagerServer根据事件的来源分发到各个不同的ViewGroup与View中,从而产生不同的OnClick、OnKeyDown和OnTouch等事件。这个时候很自然的想到,黑客们希望做键盘监控,一定会向Linux底层增加自定义的事件。这里我们使用的是Linux中的getevent获得/dev/input/eventX设备汇报的事件,这个命令还会输出所有event设备的基本信息。包括触屏、按键、耳机插入等等。其基本用法如下:Usage:getevent[-t][-n][-sswitchmask][-S][-v[mask]][-d][-p][-i][-l][-q][-ccount][-r][device]-t:showtimestamps-n:don'tprintnewlines-s:printswitchstatesforgivenbits-S:printallswitchstates-v:verbositymask(errs=1,dev=2,name=4,info=8,vers=16,pos.events=32,props=64)-d:showHIDdescriptor,ifavailable-p:showpossibleevents(errs,dev,name,pos.events)-i:-l:-q:quiet(clearverbositymask)-c:-r:printrateeventsarereceived键入getevent后,我们能够看到设备中的一些列输入硬件驱动信息,同样下面会出现很多输入指令信号,通常情况下,这些信号量都在刷屏,如下图所示:这些信号量的表示我们无法直接看懂,输入getevent–l加入Label我们能够看到一些添加的标签,如下所示:其实这些Lable已经在其input.h头文件中定义好,其中type的定义如下:/**Eventtypes*/#defineEV_SYN0x00#defineEV_KEY0x01#defineEV_REL0x02#defineEV_ABS0x03#defineEV_MSC0x04#defineEV_SW0x05#defineEV_LED0x11#defineEV_SND0x12#defineEV_REP0x14#defineEV_FF0x15#defineEV_PWR0x16#defineEV_FF_STATUS0x17#defineEV_MAX0x1f#defineEV_CNT(EV_MAX+1)一般来说,常用的是EV_KEY、EV_REL、EV_ABS、EV_SYN,分别对应键盘按键、相对坐标、绝对坐标、同步事件。EV_SYN则表示一组完整事件已经完成,需要处理,EV_SYN的code定义事件分发的类型。

Ⅳ android物理键

一般都是4个物理键。系统本身要求至少2个。

或导航键没算。)

有【 菜单,返回,搜索,小房子。】
菜单和返回好像是必须的。但是也可以做成不要物理键的。

Ⅳ Android 电源管理相关逻辑之PMS

       PowerManagerService是负责管理、协调设备电源管理的系统服务之一,设备常见功能如亮灭屏、亮度调节、低电量模式、保持CPU唤醒等,都会通过PMS的协调和处理。其继承自SystemService,因此具有SystemService子类的共性:具有生命周期方法,由SystemServer启动、注册到系统服务中,通过Binder和其他组件进行交互等。

       和SystemService的其他子类一样,PMS由SystemServer通过反射的方式启动,看一下PMS的构造方法:

       通过上面可以看到,在构造方法中首先创建了一个HandlerThread;其次获取了两个Suspend锁,SuspendBlocker是一种锁机制,只用于系统内部,上层申请的Wakelock锁在PMS中都会反映为SuspendBlocker锁。这里获取的两个Suspend锁在申请Wakelock时会用到;最后调用了native方法,这几个方法会通过JNI层调用到HAL层。

       在该方法中,首先对该服务进行Binder注册和本地注册,当进行Binder注册后,在其他模块中就可以通过Binder机制获取其实例,同理,当进行本地注册后,只有在System进程才能获取到其实例;最后设置Watchdog的监听。

       在这个方法中,设置mBootCompleted为true,表示启动完成,将mDirty置位,mDirty是一个二进制的标记位,用来表示电源状态哪一部分发生了改变,通过对其进行置位(|操作)、清零(~操作),得到二进制数各个位的值(0或1),进行不同的处理 ,然后执行updatePowerStateLocked()方法,这是整个PMS中最重要的方法,这块会在下文中具体功能中进行详细分析。

        该方法内主要有5个重要功能
a.获取各类本地服务和远程服务,如屏保(DreamMangerService)、窗口(PhoneWindowManager)、电池状态监听服务(BatteryService)等服务,用于进行交互;
b.注册用于和其他Sytem交互的广播;
c.调用updateSettingsLocked()方法更新Settings中值的变化;
d.调用readConfigurationLocked()方法读取配置文件中的默认值;
e.注册SettingsObserver监听;

       当通过系统设置等进行屏幕亮度调节时,会调用到PMS内部的updatePowerStateLocked(),通过该方法进行接下来的逻辑执行,最终通过HAL层来设置屏幕亮度,本文基于 Android 8.1 版本进行分析:

       当亮度调节时,处理逻辑主要是在phase 2,即updateDisplayPowerStateLocked(dirtyPhase2),一起看一下该方法:

       该方法内部主要做了两件事:
a.封装DisplayPowerRequest实例mDisplayPowerRequest,包括通过
getDesiredScreenPolicyLocked()获取policy,此处为DisplayPowerRequest. POLICY_BRIGHT ;还有screenBrightness等;
b.调用DisplayManagerInternal的requestPowerState(),上步封装的DisplayPowerRequest作为参数传入,mDisplayManagerInternal是在systemReady()内部获取的;

       DisplayManagerInternal内部的requestPowerState为抽象方法,因此会调用到实现类中,具体是在DisplayManagerService内部的LocalService,看一下具体实现:

       最终会调用到DisplayPowerController内部的requestPowerState()方法:

       在该方法内部先将传入的DisplayPowerRequest对象赋值给mPendingRequestLocked,后续会使用;接着执行sendUpdatePowerStateLocked(),在该方法内部会发送异步消息 MSG_UPDATE_POWER_STATE ,对应处理方法为updatePowerState();

       该方法内部主要干了6件事:
a.将要更新的DisplayPowerRequest实例赋值给mPowerRequest;
b.如果为首次执行的话,需要执行initialize()来执行初始化操作,创建DisplayPowerState实例mPowerState、RampAnimator实例mScreenBrightnessRampAnimator等;

       c.根据mPowerRequest.policy来更新state,此处为Display. STATE_ON
d.执行animateScreenStateChange(state, performScreenOffTransition)来更新DisplayPowerState;
e.根据策略进行选择,最终确定要更新的brightness值;
f.执行animateScreenBrightness(brightness,slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast)来进行更新;

       可以看到,在animateTo()内部会执行mProperty.setValue(mObject, target),mProperty对应的是
DisplayPowerState. SCREEN_BRIGHTNESS, mObject对应的是mPowerState,都是在DisplayPowerController内部的initialize()内部传入的,接下来就进入了DisplayPowerState内部了

       scheleScreenUpdate()会执行到postScreenUpdateThreadSafe(),然后会post mScreenUpdateRunnable;

       可以看到,在执行setState()后,最终会执行mBlanker.requestDisplayState(state, backlight),mBlanker是DisplayBlanker实例,初始化是在DisplayPowerController构造方法内,在DisplayPowerController内部的initialize()内部传入的,根据调用关系会追溯到DisplayMangerService的LocalService的initPowerManagerment()方法,该方法是在PowerManagerService的systemReady()方法内执行的;

       由于传入的state为Display. STATE_ON ,执行到(state, brightness),根据调用关系最终会执行到updateDisplayStateLocked()获取Runnable实例;

       根据调用关系看到,会通过DisplayDevice的requestDisplayStateLocked()来获取到Runnable;
在DisplayManagerService的onStart()内发送消息来执行registerDisplayAdapterLocked(new LocalDisplayAdapter())加载 BUILT_IN_DISPLAY_IDS_TO_SCAN对应 的LocalDisplayDevice(继承DisplayDevice),加载成功后存入mDisplayDevices列表内进行管理;
在创建LocalDisplayDeivce时会通过lights.getLight(LightsManager. LIGHT_ID_BACKLIGHT )获取mBackLight,对应的是LightsService内部的LightImpl继承light;
在通过LocalDisplayDevice获取到Runnable后接着执行run(),会执行到setDisplayBrightness();

       在setDisplayBrightness()内部会执行到mBacklight.setBrightness(brightness),具体实现逻辑是在LightsService内部;

       最终通过native方法调用到HAL层对屏幕的背光进行设置。

       不同的调节方式对应不同的入口及判断逻辑,只分析调用入口及涉及的关键策略来选择最终目标brightness值逻辑;

       系统设置在调节屏幕亮度时,会实时更新Settings. SCREEN_BRIGHTNESS 值,DisplayPowerController在监听到该值变化后会执行handleSettingsChanged()方法:

       监听到变化后,先通过getScreenBrightnessSetting()来获取到当前值,然后赋值给,接下来执行sendUpdatePowerState(),最终执行updatePowerState()方法:

        结论:系统设置会根据的值来设置对应的目标brightness值;

       快速设置来滑动进度条来调节屏幕亮度时,会调用PowerManagerService的()方法:

       跟随调用关系,调用到DisplayPowerController的setTemporaryBrightness()方法,发送 MSG_SET_TEMPORARY_BRIGHTNESS 消息,设置mTemporaryScreenBrightness为传入的值,然后执行updatePowerState():

结论:快速设置会根据mTemporaryScreenBrightness的值来设置对应的目标brightness值;

在视频播放界面可以通过左侧上下滑动来调节屏幕亮度,具体实现方式如下:

       Window是activity对应的Window,通过getWindow()可以得到,设置WindowManager.LayoutParams内部的screenBrightness后执行window.setAttributes(lp)可以来调节屏幕亮度;
Window执行setAttributes()会执行到Activity的onWindowAttributesChanged()方法,调用到WindowManagerGlobal的updateViewLayout()最终调用到ViewRootImpl的setLayoutParams来执行重新绘制;
绘制流程就不陈述了,最终会执行到RootWindowContainer内部的performSurfacePlacement()方法,接下来通过handleNotObscuredLocked()获取到对应WindowState的w.mAttrs.screenBrightness赋值给mScreenBrightness,然后在performSurfacePlacement()发送 SET_SCREEN_BRIGHTNESS_OVERRIDE消息, 最终通过WindowManagerService来调用到PowerManagerService内部的()方法:

       可以看到,在Internal()内部会将brightness赋值给,然后执行updatePowerStateLocked(),先看
updateDisplayPowerStateLocked()方法:

       可以看到,screenBrightness会设置为,该值默认为-1,经过设置后screenBrightness>0,接着执行到DisplayPowerController的updatePowerState()方法:

结论:Window属性调节会根据的值来设置对应的目标brightness值;

       设置屏幕亮度时,主要是在DisplayPowerController内部的 updatePowerState() 来对目标screenBrightness进行设置,screenBrightness默认值为PowerManager.BRIGHTNESS_DEFAULT = -1,会根据DisplayPowerRequest及其他策略进行选择,顺序依次为:
a.if (brightness < 0 && mPowerRequest.screenBrightness >= 0): 通过设置Window属性来进行调节(视频播放界面)
b.if (mTemporaryScreenBrightness > 0): 通过快速设置滑动来进行调节
c.if (brightness < 0) {brightness = clampScreenBrightness()}: 通过系统设置滑动调节

       当系统设置内部设置了自动进入屏保时间后,如果在此段时间后满足进入条件,会进入屏保,该逻辑入口是在PMS内部的updatePowerStateLocked(),一起看一下:

       本流程只分析满足条件后进入屏保的整个过程,关于条件判断会在下一节中进行分析,先从updatePowerStateLocked()看起:

       在该方法内部首先循环执行了三个方法:
a.updateWakeLockSummaryLocked():根据mWakeLocks来计算得到mWakeLockSummary的值;
       b.():计算得到mUserActivitySummary以及何时进行下一次check;
       c.updateWakefulnessLocked():判断是否可以进入屏保及更新mWakefulness状态;
d.updateDreamLocked():根据当前状态选择是否进入屏保;

       当mWakefulness为 WAKEFULNESS_AWAKE 时,且isItBedTimeYetLocked(),即:副驾满足进入屏保的条件,看一下该方法的逻辑:

       当满足以上条件后,执行napNoUpdateLocked():

       设置mSandmanSummoned为true,更新当前mWakefulness状态 WAKEFULNESS_DREAMING ,最后返回true;
前面的循环中当结果返回true时,会执行下一次循环,重新计算mWakeLockSummary和mUserActivitySummary,最终返回false,执行break退出循环,执行updateDreamLocked();

       满足条件后执行scheleSandmanLocked()来发送异步消息,执行handleSandman(),mDisplayReady是在updateDisplayPowerStateLocked()内部最终通过DisplayPowerController内部返回的;

       在handleSandman()先进行判断,满足条件后即startDreaming为true时,执行stopDream()、startDream(),接下来再执行wakeUpNoUpdateLocked(),一起看一下该方法的实现:

       将mWakefulness更新为 WAKEFULNESS_AWAKE ;然后再执行 userActivityNoUpdateLocked()来更新user activity相关信息,接着上面进行分析,执行startDream()进入屏保;

       在startDream()逻辑执行过程中首先获取到本地屏保实现的ComponentName,通过在core/res/res/values/config.xml内进行配置:

       接下来最终通过DreamController的startDream()来启动;

       可以看到在startDream()内部通过bindService()来启动本地实现的屏保服务SevenDreamService;

Ⅵ android10编程如何摸拟电源键

有root可以用一键锁屏软件,加音量键唤醒。就可以代替了。现在的手机一般都有智能唤醒,你可以找找,就是双击唤醒和上滑唤醒

Ⅶ 如何监听Android电源键长按

如果要执行长按事件的话,必须先执行event.startTracking(); 然后onKeyLongPress(int, KeyEvent)才能被调到。更多内容 欢迎访问:
是说在dispatchkeyevent里先执行event.startTracking(); 然后才super.dispatchKeyE……

你可以这样子做:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode, event);
if(keyCode == KeyEvent.KEYCODE_POWER){
event.startTracking();
}
}

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
return super.onKeyLongPress(keyCode, event);
}

这样子你的onKeyLongPress方法就会被执行到了。

希望能对你有用!

Ⅷ Android同时监听电源键和音量上键

下面两种都可以获取到音量键

测试的时候,发现KeyEvent.KEYCODE_VOLUME_UP 一直按住的时候

三星的一款平板计数到200,就不在触发该事件;

所以改为 KeyEvent.ACTION_DOWN 时启动一个方法用来计数, KeyEvent.ACTION_UP的停止技数;

Ⅸ Android怎么获取屏幕被点亮的动作

复制参考的别人的希望对你有帮助,总的来说就是监听intent.action.SCREEN_ON广播

在manifest文件里面注册一个receiver
<receiver android:name="com.test.check.MyReceiver">

<intent-filter>

<action android:name="android.intent.action.SCREEN_OFF"></action>

<action android:name="android.intent.action.SCREEN_ON"></action>

<action android:name="android.intent.action.ACTION_POWER_CONNECTED"></action>

<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"></action>

<action android:name="android.intent.action.ACTION_SHUTDOWN"></action>

</intent-filter>

</receiver>

代码部分这样监听:

public class MyReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context arg0, Intent arg1) {

// TODO Auto-generated method stub

Log.v("#@%@%#", "Power button is pressed.");

Toast.makeText(arg0, "power button clicked",Toast.LENGTH_LONG).show();

//perform what you want here

}

}

希望这个连接能帮助你 http://hi..com/doyee/item/2f0f4d142c3455721009b548

Ⅹ 安卓怎么修改home键,使home键双击进后台(也就是像iPhone那样)

这个不能修改的,只能这样。

不过安卓可以安装虚拟Home键。下载Easy Touch,功能和苹果的AssistiveTouch一样的功能,可以自定义相关的操作,可以很好的模拟实体的HOME键。在各大应用商城都可以下载。

在苹果中按一次home键,返回主界面。双击home键,出现后台运行程序。长按home键,在iPhone 3GS(第三代)和iPhone4(第四代)中会开启“语音控制”,在iPhone4S(第五代)、iPhone5(第六代)、第三代与第四代iPad中将会开启Siri语音助手。按电源键3秒后,同时按住home键10秒,松开电源键,保持home键15秒,进入DFU模式(越狱用)。连按3下home键的功能可以自定义。

热点内容
竖编译 发布:2025-05-17 09:56:08 浏览:226
编程画飞机 发布:2025-05-17 09:54:03 浏览:800
手机如何解锁密码屏幕锁怎么删除 发布:2025-05-17 09:52:04 浏览:122
网络无法访问网页 发布:2025-05-17 09:51:40 浏览:648
云存储box估值 发布:2025-05-17 09:47:11 浏览:510
关系数据库实时数据库 发布:2025-05-17 09:43:07 浏览:874
去培训编程 发布:2025-05-17 09:41:16 浏览:701
android控制屏幕关闭 发布:2025-05-17 09:32:23 浏览:147
excel的快速访问工具栏 发布:2025-05-17 09:14:58 浏览:1
android360源码 发布:2025-05-17 09:11:47 浏览:76