Android 12系统源码_系统栏管理服务(一)StatusBarManagerService服务介绍

这篇具有很好参考价值的文章主要介绍了Android 12系统源码_系统栏管理服务(一)StatusBarManagerService服务介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在Android系统中,其他模块想要和SystemUI模块交互,基本都离不开StatusBarManagerService这个服务的,StatusBarManagerService顾名思义,就是状态栏管理服务,但其实这个服务不单单可以管理系统状态栏,通过这个服务,我们可以管理SystemUI模块的大部分系统栏组件,比如状态栏、导航栏、最近任务等,本篇文章我们先来简单认识一下这个服务。

一、SystemServer创建StatusBarManagerService服务

1、和大部分系统服务一样,StatusBarManagerService服务也是在SystemServer中被创建:

frameworks/base/service/java/com/android/server/SystemServer.java

public final class SystemServer {
    
    public static void main(String[] args) {
        new SystemServer().run();
    }
    
   private void run() {
    	...代码省略...
        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();//启动引导服务
            startCoreServices();//启动核心服务
            startOtherServices();//启动其他服务
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
    	...代码省略...
    }
}

2、startOtherServices方法和WindowManagerService服务启动相关的代码如下所示。

public final class SystemServer {
  
  private ActivityManagerService mActivityManagerService;
  private boolean mOnlyCore;
  private boolean mFirstBoot;

  private void startOtherServices() {
          ...代码省略...
       	StatusBarManagerService statusBar = null;
          ...代码省略...
        boolean isWatch = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
          ...代码省略...    
        if (!isWatch) {
          traceBeginAndSlog("StartStatusBarManagerService");
           try {
                //系统栏管理服务
                statusBar = new StatusBarManagerService(context, wm);
                ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
            } catch (Throwable e) {
                reportWtf("starting StatusBarManagerService", e);
            }
            traceEnd();
        }
        ...代码省略...            
    }
}     

二、StatusBarManagerService类定义

2.1 构造方法

frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java

public class StatusBarManagerService extends IStatusBarService.Stub implements DisplayListener {
    /**
     * 构造方法
     */
    public StatusBarManagerService(Context context) {
        mContext = context;

        LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
        LocalServices.addService(GlobalActionsProvider.class, mGlobalActionsProvider);

        // We always have a default display.
        final UiState state = new UiState();
        mDisplayUiState.put(DEFAULT_DISPLAY, state);

        final DisplayManager displayManager =
                (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
        displayManager.registerDisplayListener(this, mHandler);
        mActivityTaskManager = LocalServices.getService(ActivityTaskManagerInternal.class);
    }

}

2.2 继承的父类

StatusBarManagerService继承自IStatusBarService.Stub,IStatusBarService.aidl文件如下所示。

frameworks/base/core/java/com/android/internal/statusbar/IStatusBarService.aidl

interface IStatusBarService
{
    @UnsupportedAppUsage
    void expandNotificationsPanel();
    @UnsupportedAppUsage
    void collapsePanels();
    void togglePanel();
    @UnsupportedAppUsage
    void disable(int what, IBinder token, String pkg);
    void disableForUser(int what, IBinder token, String pkg, int userId);
    void disable2(int what, IBinder token, String pkg);
    void disable2ForUser(int what, IBinder token, String pkg, int userId);
    int[] getDisableFlags(IBinder token, int userId);
    void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription);
    @UnsupportedAppUsage
    void setIconVisibility(String slot, boolean visible);
    @UnsupportedAppUsage
    void removeIcon(String slot);
    void setImeWindowStatus(int displayId, in IBinder token, int vis, int backDisposition,
            boolean showImeSwitcher, boolean isMultiClientImeEnabled);
    void expandSettingsPanel(String subPanel);

    // ---- Methods below are for use by the status bar policy services ----
    // You need the STATUS_BAR_SERVICE permission
    RegisterStatusBarResult registerStatusBar(IStatusBar callbacks);
    void onPanelRevealed(boolean clearNotificationEffects, int numItems);
    void onPanelHidden();
    // Mark current notifications as "seen" and stop ringing, vibrating, blinking.
    void clearNotificationEffects();
    void onNotificationClick(String key, in NotificationVisibility nv);
    void onNotificationActionClick(String key, int actionIndex, in Notification.Action action, in NotificationVisibility nv, boolean generatedByAssistant);
    void onNotificationError(String pkg, String tag, int id,
            int uid, int initialPid, String message, int userId);
    void onClearAllNotifications(int userId);
    void onNotificationClear(String pkg, int userId, String key,
            int dismissalSurface, int dismissalSentiment, in NotificationVisibility nv);
    void onNotificationVisibilityChanged( in NotificationVisibility[] newlyVisibleKeys,
            in NotificationVisibility[] noLongerVisibleKeys);
    void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded, in int notificationLocation);
    void onNotificationDirectReplied(String key);
    void onNotificationSmartSuggestionsAdded(String key, int smartReplyCount, int smartActionCount,
            boolean generatedByAsssistant, boolean editBeforeSending);
    void onNotificationSmartReplySent(in String key, in int replyIndex, in CharSequence reply,
            in int notificationLocation, boolean modifiedBeforeSending);
    void onNotificationSettingsViewed(String key);
    void onNotificationBubbleChanged(String key, boolean isBubble, int flags);
    void onBubbleNotificationSuppressionChanged(String key, boolean isNotifSuppressed, boolean isBubbleSuppressed);
    void hideCurrentInputMethodForBubbles();
    void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName);
    void clearInlineReplyUriPermissions(String key);
    void onNotificationFeedbackReceived(String key, in Bundle feedback);

    void onGlobalActionsShown();
    void onGlobalActionsHidden();

    /**
     * These methods are needed for global actions control which the UI is shown in sysui.
     */
    void shutdown();
    void reboot(boolean safeMode);

    void addTile(in ComponentName tile);
    void remTile(in ComponentName tile);
    void clickTile(in ComponentName tile);
    @UnsupportedAppUsage
    void handleSystemKey(in int key);

    /**
     * Methods to show toast messages for screen pinning
     */
    void showPinningEnterExitToast(boolean entering);
    void showPinningEscapeToast();

    // Used to show the authentication dialog (Biometrics, Device Credential)
    void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver,
            in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
            int userId, long operationId, String opPackageName, long requestId,
            int multiSensorConfig);

    // Used to notify the authentication dialog that a biometric has been authenticated
    void onBiometricAuthenticated();
    // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
    void onBiometricHelp(int modality, String message);
    // Used to show an error - the dialog will dismiss after a certain amount of time
    void onBiometricError(int modality, int error, int vendorCode);
    // Used to hide the authentication dialog, e.g. when the application cancels authentication
    void hideAuthenticationDialog();

    /**
     * Sets an instance of IUdfpsHbmListener for UdfpsController.
     */
    void setUdfpsHbmListener(in IUdfpsHbmListener listener);

    /**
     * Show a warning that the device is about to go to sleep due to user inactivity.
     */
    void showInattentiveSleepWarning();

    /**
     * Dismiss the warning that the device is about to go to sleep due to user inactivity.
     */
    void dismissInattentiveSleepWarning(boolean animated);

    /**
     * Notifies SystemUI to start tracing.
     */
    void startTracing();

    /**
     * Notifies SystemUI to stop tracing.
     */
    void stopTracing();

    /**
     * Returns whether SystemUI tracing is enabled.
     */
    boolean isTracing();

    /**
     * If true, suppresses the ambient display from showing. If false, re-enables the ambient
     * display.
     */
    void suppressAmbientDisplay(boolean suppress);

}

2.3 实现的接口

StatusBarManagerService实现了DisplayListener,该接口如下所示。

frameworks/base/core/java/android/hardware/display/DisplayManager.java文章来源地址https://www.toymoban.com/news/detail-468852.html

public final class DisplayManager {
    /**
     * Listens for changes in available display devices.
     */
    public interface DisplayListener {
        /**
         * Called whenever a logical display has been added to the system.
         * Use {@link DisplayManager#getDisplay} to get more information about
         * the display.
         *
         * @param displayId The id of the logical display that was added.
         */
        void onDisplayAdded(int displayId);

        /**
         * Called whenever a logical display has been removed from the system.
         *
         * @param displayId The id of the logical display that was removed.
         */
        void onDisplayRemoved(int displayId);

        /**
         * Called whenever the properties of a logical {@link android.view.Display},
         * such as size and density, have changed.
         *
         * @param displayId The id of the logical display that changed.
         */
        void onDisplayChanged(int displayId);
    }
}

2.4 常用属性

public class StatusBarManagerService extends IStatusBarService.Stub implements DisplayListener {
    private final Context mContext;

    private final Handler mHandler = new Handler();
    private NotificationDelegate mNotificationDelegate;
    private volatile IStatusBar mBar;
    private final ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();

    // for disabling the status bar
    private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
    private GlobalActionsProvider.GlobalActionsListener mGlobalActionListener;
    private final IBinder mSysUiVisToken = new Binder();

    private final Object mLock = new Object();
    private final DeathRecipient mDeathRecipient = new DeathRecipient();
    private final ActivityTaskManagerInternal mActivityTaskManager;
    private int mCurrentUserId;
    private boolean mTracingEnabled;

    private final SparseArray<UiState> mDisplayUiState = new SparseArray<>();
    @GuardedBy("mLock")
    private IUdfpsHbmListener mUdfpsHbmListener;

    /**
     * Private API used by NotificationManagerService.
     */
    private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() {
        private boolean mNotificationLightOn;

        @Override
        public void setNotificationDelegate(NotificationDelegate delegate) {
            mNotificationDelegate = delegate;
        }

        @Override
        public void showScreenPinningRequest(int taskId) {
            if (mBar != null) {
                try {
                    mBar.showScreenPinningRequest(taskId);
                } catch (RemoteException e) {
                }
            }
        }

        @Override
        public void showAssistDisclosure() {
            if (mBar != null) {
                try {
                    mBar.showAssistDisclosure();
                } catch (RemoteException e) {
                }
            }
        }

        @Override
        public void startAssist(Bundle args) {
            if (mBar != null) {
                try {
                    mBar.startAssist(args);
                } catch (RemoteException e) {
                }
            }
        }

        @Override
        public void onCameraLaunchGestureDetected(int source) {
            if (mBar != null) {
                try {
                    mBar.onCameraLaunchGestureDetected(source);
                } catch (RemoteException e) {
                }
            }
        }

        /**
         * Notifies the status bar that a Emergency Action launch gesture has been detected.
         *
         * TODO (b/169175022) Update method name and docs when feature name is locked.
         */
        @Override
        public void onEmergencyActionLaunchGestureDetected() {
            if (SPEW) Slog.d(TAG, "Launching emergency action");
            if (mBar != null) {
                try {
                    mBar.onEmergencyActionLaunchGestureDetected();
                } catch (RemoteException e) {
                    if (SPEW) Slog.d(TAG, "Failed to launch emergency action");
                }
            }
        }

        @Override
        public void setDisableFlags(int displayId, int flags, String cause) {
            StatusBarManagerService.this.setDisableFlags(displayId, flags, cause);
        }

        @Override
        public void toggleSplitScreen() {
            enforceStatusBarService();
            if (mBar != null) {
                try {
                    mBar.toggleSplitScreen();
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void appTransitionFinished(int displayId) {
            enforceStatusBarService();
            if (mBar != null) {
                try {
                    mBar.appTransitionFinished(displayId);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void toggleRecentApps() {
            if (mBar != null) {
                try {
                    mBar.toggleRecentApps();
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void setCurrentUser(int newUserId) {
            if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
            mCurrentUserId = newUserId;
        }


        @Override
        public void preloadRecentApps() {
            if (mBar != null) {
                try {
                    mBar.preloadRecentApps();
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void cancelPreloadRecentApps() {
            if (mBar != null) {
                try {
                    mBar.cancelPreloadRecentApps();
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void showRecentApps(boolean triggeredFromAltTab) {
            if (mBar != null) {
                try {
                    mBar.showRecentApps(triggeredFromAltTab);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
            if (mBar != null) {
                try {
                    mBar.hideRecentApps(triggeredFromAltTab, triggeredFromHomeKey);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void collapsePanels() {
            if (mBar != null) {
                try {
                    mBar.animateCollapsePanels();
                } catch (RemoteException ex) {
                }
            }
        }

        @Override
        public void dismissKeyboardShortcutsMenu() {
            if (mBar != null) {
                try {
                    mBar.dismissKeyboardShortcutsMenu();
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void toggleKeyboardShortcutsMenu(int deviceId) {
            if (mBar != null) {
                try {
                    mBar.toggleKeyboardShortcutsMenu(deviceId);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void showChargingAnimation(int batteryLevel) {
            if (mBar != null) {
                try {
                    mBar.showWirelessChargingAnimation(batteryLevel);
                } catch (RemoteException ex){
                }
            }
        }

        @Override
        public void showPictureInPictureMenu() {
            if (mBar != null) {
                try {
                    mBar.showPictureInPictureMenu();
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void setWindowState(int displayId, int window, int state) {
            if (mBar != null) {
                try {
                    mBar.setWindowState(displayId, window, state);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void appTransitionPending(int displayId) {
            if (mBar != null) {
                try {
                    mBar.appTransitionPending(displayId);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void appTransitionCancelled(int displayId) {
            if (mBar != null) {
                try {
                    mBar.appTransitionCancelled(displayId);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void appTransitionStarting(int displayId, long statusBarAnimationsStartTime,
                long statusBarAnimationsDuration) {
            if (mBar != null) {
                try {
                    mBar.appTransitionStarting(
                            displayId, statusBarAnimationsStartTime, statusBarAnimationsDuration);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void setTopAppHidesStatusBar(boolean hidesStatusBar) {
            if (mBar != null) {
                try {
                    mBar.setTopAppHidesStatusBar(hidesStatusBar);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public boolean showShutdownUi(boolean isReboot, String reason) {
            if (!mContext.getResources().getBoolean(R.bool.config_showSysuiShutdown)) {
                return false;
            }
            if (mBar != null) {
                try {
                    mBar.showShutdownUi(isReboot, reason);
                    return true;
                } catch (RemoteException ex) {}
            }
            return false;
        }

        // TODO(b/118592525): support it per display if necessary.
        @Override
        public void onProposedRotationChanged(int rotation, boolean isValid) {
            if (mBar != null){
                try {
                    mBar.onProposedRotationChanged(rotation, isValid);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void onDisplayReady(int displayId) {
            if (mBar != null) {
                try {
                    mBar.onDisplayReady(displayId);
                } catch (RemoteException ex) {}
            }
        }

        @Override
        public void onRecentsAnimationStateChanged(boolean running) {
            if (mBar != null) {
                try {
                    mBar.onRecentsAnimationStateChanged(running);
                } catch (RemoteException ex) {}
            }

        }

        @Override
        public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance,
                AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
                @Behavior int behavior, InsetsVisibilities requestedVisibilities,
                String packageName) {
            getUiState(displayId).setBarAttributes(appearance, appearanceRegions,
                    navbarColorManagedByIme, behavior, requestedVisibilities, packageName);
            if (mBar != null) {
                try {
                    mBar.onSystemBarAttributesChanged(displayId, appearance, appearanceRegions,
                            navbarColorManagedByIme, behavior, requestedVisibilities, packageName);
                } catch (RemoteException ex) { }
            }
        }

        @Override
        public void showTransient(int displayId, @InternalInsetsType int[] types,
                boolean isGestureOnSystemBar) {
            getUiState(displayId).showTransient(types);
            if (mBar != null) {
                try {
                    mBar.showTransient(displayId, types, isGestureOnSystemBar);
                } catch (RemoteException ex) { }
            }
        }

        @Override
        public void abortTransient(int displayId, @InternalInsetsType int[] types) {
            getUiState(displayId).clearTransient(types);
            if (mBar != null) {
                try {
                    mBar.abortTransient(displayId, types);
                } catch (RemoteException ex) { }
            }
        }

        @Override
        public void showToast(int uid, String packageName, IBinder token, CharSequence text,
                IBinder windowToken, int duration,
                @Nullable ITransientNotificationCallback callback) {
            if (mBar != null) {
                try {
                    mBar.showToast(uid, packageName, token, text, windowToken, duration, callback);
                } catch (RemoteException ex) { }
            }
        }

        @Override
        public void hideToast(String packageName, IBinder token) {
            if (mBar != null) {
                try {
                    mBar.hideToast(packageName, token);
                } catch (RemoteException ex) { }
            }
        }

        @Override
        public void requestWindowMagnificationConnection(boolean request) {
            if (mBar != null) {
                try {
                    mBar.requestWindowMagnificationConnection(request);
                } catch (RemoteException ex) { }
            }
        }

        @Override
        public void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {
            if (mBar != null) {
                try {
                    mBar.handleWindowManagerLoggingCommand(args, outFd);
                } catch (RemoteException ex) { }
            }
        }

        @Override
        public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {
            if (mBar != null) {
                try {
                    mBar.setNavigationBarLumaSamplingEnabled(displayId, enable);
                } catch (RemoteException ex) { }
            }
        }

        @Override
        public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
            synchronized (mLock) {
                mUdfpsHbmListener = listener;
            }
            if (mBar != null) {
                try {
                    mBar.setUdfpsHbmListener(listener);
                } catch (RemoteException ex) { }
            }
        }
    };

    private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
        @Override
        public boolean isGlobalActionsDisabled() {
            // TODO(b/118592525): support global actions for multi-display.
            final int disabled2 = mDisplayUiState.get(DEFAULT_DISPLAY).getDisabled2();
            return (disabled2 & DISABLE2_GLOBAL_ACTIONS) != 0;
        }

        @Override
        public void setGlobalActionsListener(GlobalActionsProvider.GlobalActionsListener listener) {
            mGlobalActionListener = listener;
            mGlobalActionListener.onGlobalActionsAvailableChanged(mBar != null);
        }

        @Override
        public void showGlobalActions() {
            if (mBar != null) {
                try {
                    mBar.showGlobalActionsMenu();
                } catch (RemoteException ex) {}
            }
        }
    };

}

到了这里,关于Android 12系统源码_系统栏管理服务(一)StatusBarManagerService服务介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot基于Web的社区医院管理服务系统源码和论文

    在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括 社区医院管理服务系统 的网络应用,在外国线上管理系统已经是很普遍的方式,不过 国内的 管理系统 可能 还处于起步阶段 。社区医院管理服务系统 具有社区医院信息管理功能的选择。社区医

    2024年01月20日
    浏览(55)
  • Java版工程行业管理系统源码-专业的工程管理软件-em提供一站式服务 em

    ​  Java版工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目显示1、项目进度图表  2、项目信息 施工地图:1、展示当前角色权限

    2024年02月13日
    浏览(42)
  • java spring cloud 企业工程管理系统源码+二次开发+定制化服务

    鸿鹄工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部工程管理的提升提出了更高

    2024年02月09日
    浏览(49)
  • 基于微服务、Java、Springcloud、Vue、MySQL开发的智慧工地管理系统源码

    智慧工地聚焦施工现场岗位一线,围绕“人、机、料、法、环”五大要素,数字化工地平台与现场多个子系统的互联实现了工地业务间的互联互通和协同共享。数字化工地管理平台能够盘活工地各大项目之间孤立的信息系统,实现数据的统一接入、处理与维护,提高现有系统

    2024年02月11日
    浏览(31)
  • java spring cloud 企业工程管理系统源码+二次开发+定制化服务 em

     Java版工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目显示1、项目进度图表  2、项目信息 施工地图:1、展示当前角色权限下

    2024年02月13日
    浏览(45)
  • 基于微信小程序的同城宠物服务管理系统的设计与实现(源码+论文)_v_163

    摘 要 本同城宠物服务店微信小程序划分了微信用户端和后台管理员端,其中微信用户端使用微信开发者工具开发和html、js、css、layui技术,后台管理员端使用IDEA开发工具和spingboot、fastjson、mybatis-plus、thymeleaf、shiro技术。微信端的用户可以进行微信授权登录、搜索宠物用品、

    2024年01月21日
    浏览(36)
  • Android 12系统源码_窗口管理(五)DisplayContent简介

    DisplayContent 用于管理屏幕,一块DisplayContent 对象实例代表一个屏幕设备,这样有多个屏幕的设备就可以创建多个DisplayContent 对象,虽然多数设备只有一个显示屏,但它们同样可以创建多个 DisplayContent 对象,如投屏的时候,可以创建一个虚拟的DisplayContent。 1、DisplayContent对象实

    2024年02月07日
    浏览(32)
  • ssm基于微信小程序的社区老人健康管理服务系统的设计与实现 毕业设计-附源码011513

    摘要 随着现在网络的快速发展,网络的应用在各行各业当中它很快融入到了许多分类管理之中,他们利用网络来做这个社区老人健康管理服务系统,随之就产生了“社区老人健康管理服务系统 .”,这样就让社区老人健康管理服务系统更加方便简单。 对于本社区老人健康管理

    2024年02月09日
    浏览(64)
  • (附源码)ssm基于微信小程序的社区老人健康管理服务系统的设计与实现 毕业设计011513

    摘要 随着现在网络的快速发展,网络的应用在各行各业当中它很快融入到了许多分类管理之中,他们利用网络来做这个社区老人健康管理服务系统,随之就产生了“社区老人健康管理服务系统 .”,这样就让社区老人健康管理服务系统更加方便简单。 对于本社区老人健康管理

    2024年02月08日
    浏览(119)
  • android h5 宿舍报修管理系统myeclipse开发mysql数据库编程服务端java计算机程序设计

    一、源码特点   android h5 宿舍报修管理系统是一套完善的WEB+android设计系统,对理解JSP java,安卓app编程开发语言有帮助(系统采用web服务端+APP端 综合模式进行设计开发),系统具有完整的 源代码和数据库,系统主要采用B/S模式开发。 二、功能介绍 本系统的最终用户为学生

    2024年02月12日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包