您的位置:首页 > 移动开发

App Widget Host

2016-04-03 19:57 417 查看
The Android Home screen available on most Android devices allows the user to embed app widgets for quick access
to content. If you're building a Home replacement or a similar app, you can also allow the user to embed app widgets by implementing an 
AppWidgetHost
.
This is not something that most apps will ever need to do, but if you are creating your own host, it's important to understand the contractual obligations a host implicitly agrees to.

This document focuses on the responsibilities involved in implementing a custom 
AppWidgetHost
.
For an example of how to implement an 
AppWidgetHost
, see the source code for
the Android Home screen Launcher.

Here is an overview of key classes and concepts involved in implementing a custom 
AppWidgetHost
:
App Widget Host— The 
AppWidgetHost
 provides
the interaction with the AppWidget service for apps, like the home screen, that want to embed app widgets in their UI. An 
AppWidgetHost
 must
have an ID that is unique within the host's own package. This ID remains persistent across all uses of the host. The ID is typically a hard-coded value that you assign in your application.
App Widget ID— Each app widget instance is assigned a unique ID at the time of binding (see
bindAppWidgetIdIfAllowed()
,
discussed in more detail in Binding app widgets). The unique ID is obtained by the host using 
allocateAppWidgetId()
.
This ID is persistent across the lifetime of the widget, that is, until it is deleted from the host. Any host-specific state (such as the size and location of the widget) should be persisted by the hosting package and associated with the app widget ID.
App Widget Host View— 
AppWidgetHostView
 can
be thought of as a frame that the widget is wrapped in whenever it needs to be displayed. An app widget is assigned to an 
AppWidgetHostView
 every
time the widget is inflated by the host.
Options Bundle— The 
AppWidgetHost
 uses
the options bundle to communicate information to the
AppWidgetProvider
 about
how the widget is being displayed (for example, size range, and whether the widget is on a lockscreen or the home screen). This information allows the 
AppWidgetProvider
 to
tailor the widget's contents and appearance based on how and where it is displayed. You use
updateAppWidgetOptions()
 and 
updateAppWidgetSize()
 to
modify an app widget's bundle. Both of these methods trigger a callback to the 
AppWidgetProvider
.


Binding App Widgets

When a user adds an app widget to a host, a process called binding occurs. Binding refers to associating a particular app widget ID to a specific host and to a specific 
AppWidgetProvider
.
There are different ways of achieving this, depending on what version of Android your app is running on.


Binding app widgets on Android 4.0 and lower

On devices running Android version 4.0 and lower, users add app widgets via a system activity that allows users to select a widget. This implicitly does a permission check—that is, by adding the app widget, the user is implicitly granting permission to your
app to add app widgets to the host. Here is an example that illustrates this approach, taken from the original Launcher.
In this snippet, an event handler invokes
startActivityForResult()
 with
the request code 
REQUEST_PICK_APPWIDGET
 in response to a user action:
private static final int REQUEST_CREATE_APPWIDGET = 5;
private static final int REQUEST_PICK_APPWIDGET = 9;
...
public void onClick(DialogInterface dialog, int which) {
    switch (which) {
    ...
        case AddAdapter.ITEM_APPWIDGET: {
            ...
            int appWidgetId =
                    Launcher.this.mAppWidgetHost.allocateAppWidgetId();
            Intent pickIntent =
                    new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
            pickIntent.putExtra
                    (AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            ...
            startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
            break;
    }
    ...
}


When the system activity finishes, it returns a result with the user's chosen app widget to your activity. In the following example, the activity responds by calling 
addAppWidget()
 to add the app widget:
public final class Launcher extends Activity
        implements View.OnClickListener, OnLongClickListener {
    ...
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        mWaitingForResult = false;

        if (resultCode == RESULT_OK && mAddItemCellInfo != null) {
            switch (requestCode) {
                ...
                case REQUEST_PICK_APPWIDGET:
                    addAppWidget(data);
                    break;
                case REQUEST_CREATE_APPWIDGET:
                    completeAddAppWidget(data, mAddItemCellInfo, !mDesktopLocked);
                    break;
                }
        }
        ...
    }
}


The method 
addAppWidget()
 checks to see if the app widget needs to be configured before it's added:
void addAppWidget(Intent data) {
    int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);

    String customWidget = data.getStringExtra(EXTRA_CUSTOM_WIDGET);
    AppWidgetProviderInfo appWidget =
            mAppWidgetManager.getAppWidgetInfo(appWidgetId);

    if (appWidget.configure != null) {
        // Launch over to configure widget, if needed.
        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
        intent.setComponent(appWidget.configure);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
    } else {
        // Otherwise, finish adding the widget.
    }
}


For more discussion of configuration, see Creating an App Widget Configuration Activity.

Once the app widget is ready, the next step is to do the actual work of adding it to the workspace. The original
Launcher uses a method called 
completeAddAppWidget()
 to do this.


Binding app widgets on Android 4.1 and higher

Android 4.1 adds APIs for a more streamlined binding process. These APIs also make it possible for a host to provide a custom UI for binding. To use this improved process, your app must declare the 
BIND_APPWIDGET
permission
in its manifest:
<uses-permission android:name="android.permission.BIND_APPWIDGET" />


But this is just the first step. At runtime the user must explicitly grant permission to your app to allow it to add app widgets to the host. To test whether your app has permission to add the widget, you use the
bindAppWidgetIdIfAllowed()
 method.
If 
bindAppWidgetIdIfAllowed()
 returns 
false
,
your app must display a dialog prompting the user to grant permission ("allow" or "always allow," to cover all future app widget additions). This snippet gives an example of how to display the dialog:
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
// This is the options bundle discussed above
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
startActivityForResult(intent, REQUEST_BIND_APPWIDGET);


The host also has to check whether the user added an app widget that needs configuration. For more discussion of this topic, see Creating
an App Widget Configuration Activity.


Host Responsibilities


What Version are You Targeting?

The approach you use in implementing your host should depend on what Android version you're targeting. Many of the features described in this section were introduced in 3.0 or later. For example:
Android 3.0 (API Level 11) introduces auto-advance behavior for widgets.
Android 3.1 (API Level 12) introduces the ability to resize widgets.
Android 4.0 (API Level 15) introduces a change in padding policy that puts the responsibility on the host to manage padding.
Android 4.1 (API Level 16) adds an API that allows the widget provider to get more detailed information about the environment in which its widget instances are being hosted.
Android 4.2 (API Level 17) introduces the options bundle and the
bindAppWidgetIdIfAllowed()
method.
It also introduces lockscreen widgets.
If you are targeting earlier devices, refer to the original Launcher as
an example.

Widget developers can specify a number of configuration settings for widgets using the AppWidgetProviderInfo
metadata. These configuration options, discussed in more detail below, can be retrieved by the host from the 
AppWidgetProviderInfo
 object
associated with a widget provider.

Regardless of the version of Android you are targeting, all hosts have the following responsibilities:
When adding a widget, you must allocate the widget ID as described above. You must also make sure that when a widget is removed from the host, you call 
deleteAppWidgetId()
 to
deallocate the widget ID.
When adding a widget, be sure to launch its configuration activity if it exists, as described in Updating
the App Widget from the Configuration Activity. This is a necessary step for many app widgets before they can be properly displayed.
Every app widget specifies a minimum width and height in dps, as defined in the 
AppWidgetProviderInfo
 metadata
(using
android:minWidth
 and 
android:minHeight
).
Make sure that the widget is laid out with at least this many dps. For example, many hosts align icons and widgets in a grid. In this scenario, by default the host should add the app widget using the minimum number of cells that satisfy the 
minWidth
 and
minHeight
 constraints.

In addition to the requirements listed above, specific platform versions introduce features that place new responsibilities on the host. These are described in the following sections.


Android 3.0

Android 3.0 (API Level 11) introduces the ability for a widget to specify 
autoAdvanceViewId()
.
This view ID should point to an instance of an 
Advanceable
, such as 
StackView
 or 
AdapterViewFlipper
.
This indicates that the host should call 
advance()
 on this view at an interval
deemed appropriate by the host (taking into account whether it makes sense to advance the widget—for example, the host probably wouldn't want to advance a widget if it were on another page, or if the screen were turned off).


Android 3.1

Android 3.1 (API Level 12) introduces the ability to resize widgets. A widget can specify that it is resizable using the 
android:resizeMode
 attribute
in the 
AppWidgetProviderInfo
 metadata, and indicate whether it supports
horizontal and/or vertical resizing. Introduced in Android 4.0 (API Level 14), the widget can also specify a
android:minResizeWidth
 and/or 
android:minResizeHeight
.

It is the host’s responsibility to make it possible for the widget to be resized horizontally and/or vertically, as specified by the widget. A widget that specifies that it is resizable can be resized arbitrarily large, but should not be resized smaller than
the values specified by 
android:minResizeWidth
 and 
android:minResizeHeight
.
For a sample implementation, see 
AppWidgetResizeFrame
 in 
Launcher2
.


Android 4.0

Android 4.0 (API Level 15) introduces a change in padding policy that puts the responsibility on the host to manage padding. As of 4.0, app widgets no longer include their own padding. Instead, the system adds padding for each widget, based the characteristics
of the current screen. This leads to a more uniform, consistent presentation of widgets in a grid. To assist applications that host app widgets, the platform provides the method
getDefaultPaddingForWidget()
.
Applications can call this method to get the system-defined padding and account for it when computing the number of cells to allocate to the widget.


Android 4.1

Android 4.1 (API Level 16) adds an API that allows the widget provider to get more detailed information about the environment in which its widget instances are being hosted. Specifically, the host hints to the widget provider about the size at which the widget
is being displayed. It is the host’s responsibility to provide this size information.

The host provides this information via 
updateAppWidgetSize()
.
The size is specified as a minimum and maximum width/height in dps. The reason that a range is specified (as opposed to a fixed size) is because the width and height of a widget may change with orientation. You don’t want the host to have to update all of
its widgets on rotation, as this could cause serious system slowdown. These values should be updated once upon the widget being placed, any time the widget is resized, and any time the launcher inflates the widget for the first time in a given boot (as the
values aren’t persisted across boot).


Android 4.2

Android 4.2 (API Level 17) adds the ability for the options bundle to be specified at bind time. This is the ideal way to specify app widget options, including size, as it gives the 
AppWidgetProvider
 immediate
access to the options data on the first update. This can be achieved by using the method 
bindAppWidgetIdIfAllowed()
.
For more discussion of this topic, see Binding app widgets.

Android 4.2 also introduces lockscreen widgets. When hosting widgets on the lockscreen, the host must specify this information within the app widget options bundle (the 
AppWidgetProvider
 can
use this information to style the widget appropriately). To designate a widget as a lockscreen widget, use 
updateAppWidgetOptions()
 and
include the field 
OPTION_APPWIDGET_HOST_CATEGORY
 with
the value 
WIDGET_CATEGORY_KEYGUARD
. This option
defaults to 
WIDGET_CATEGORY_HOME_SCREEN
,
so it is not explicitly required to set this for a home screen host.

Make sure that your host adds only app widgets that are appropriate for your app—for example, if your host is a home screen, ensure that the 
android:widgetCategory
 attribute
in the 
AppWidgetProviderInfo
 metadata includes the flag 
WIDGET_CATEGORY_HOME_SCREEN
.
Similarly, for the lockscreen, ensure that field includes the flag
WIDGET_CATEGORY_KEYGUARD
.
For more discussion of this topic, see Enabling App Widgets on the Lockscreen.




在该文献

结合应用小工具
在Android 4.0和更低的结合应用小工具
在Android 4.1及更高的结合应用小工具

主持人职责
Android 3.0的
Android版3.1
Android 4.0的
搭载Android 4.1
Android
4.2版

大多数Android设备上可用的Android主屏幕允许用户嵌入应用小工具,以便快速访问的内容。如果你正在构建一个家庭更换或类似的应用程序,也可以允许用户通过实现嵌入应用程序部件 
AppWidgetHost
。这不是大多数应用程序都不会需要做的事情,但如果你正在创建您自己的主机,它了解合同义务的主机隐含同意是非常重要的。
本文件的重点参与实施定制的责任 
AppWidgetHost
。对于如何实现一个例子 
AppWidgetHost
,请参阅Android主屏幕的源代码 发射器
这里是参与实施定制关键类和概念的概述 
AppWidgetHost

应用的Widget主机 -该
AppWidgetHost
提供与AppWidget服务的应用程序,如主屏幕,希望嵌入应用小部件在其UI交互。一个
AppWidgetHost
必须有一个ID,它是主机自己的包中是唯一的。此ID在跨越主机的所有使用持久性。该ID通常是在应用程序中指定一个硬编码值。
应用程序窗口小部件ID -每个应用程序控件实例是在结合时分配一个唯一的ID(见
bindAppWidgetIdIfAllowed() 
,详细讨论绑定应用小部件)。唯一ID是由使
​​用主机获得
allocateAppWidgetId() 
。该ID是横跨插件,即的寿命持久,直到它从主机中删除。任何特定的主机的状态(例如大小和小部件的位置)应当由主机包被持久并与该应用微件ID相关联。
应用窗口小部件主机视图 - 
AppWidgetHostView
可以被认为是一帧,该插件是包裹在每当需要将其显示出来。一个应用程序widget被分配给一个
AppWidgetHostView
每个小部件由主机充气时间。
选项包 -该
AppWidgetHost
使用选项束将信息传达给所述
AppWidgetProvider
如何正在显示微件(例如,尺寸范围,以及是否该窗口小部件上的锁定屏幕或主屏幕)。该信息允许 
AppWidgetProvider
的基础上如何以及在哪里显示定制Widget的内容和外观。您可以使用 
updateAppWidgetOptions()
 和
updateAppWidgetSize()
 来修改应用程序widget的包。这两种方法触发一个回调至 
AppWidgetProvider



结合应用小工具

当用户添加一个应用程序窗口小部件到主机,这个过程被称为 绑定发生。绑定是指一个特定的应用程序部件编号为特定主机和特定的关联 
AppWidgetProvider
。有实现这一目标,取决于什么版本的Android您的应用程序上运行的不同方式。


在Android 4.0和更低的结合应用小工具

在运行Android 4.0版和更低的设备,用户通过系统的活动,允许用户选择一个小部件添加应用程序部件。这含蓄地做了权限检查,也就是说,通过将应用程序窗口小部件,用户被隐性授予权限,以您的应用程序小部件添加到主机。这里是示出该方法中,从原始拍摄的示例 发射器。在这个片段中,一个事件处理程序调用
startActivityForResult()
 的请求代码
REQUEST_PICK_APPWIDGET
响应用户操作:
private  static  final  int REQUEST_CREATE_APPWIDGET =  5 ;
private  static  final  int REQUEST_PICK_APPWIDGET =  9 ;
...
public  void onClick ( DialogInterface dialog ,  int which )  {
    switch  ( which )  {
    ...
        case  AddAdapter . ITEM_APPWIDGET :  {
            ...
            int appWidgetId =
                    Launcher . this . mAppWidgetHost . allocateAppWidgetId ();
            Intent pickIntent =
                    new  Intent ( AppWidgetManager . ACTION_APPWIDGET_PICK );
            pickIntent . putExtra
                    ( AppWidgetManager . EXTRA_APPWIDGET_ID , appWidgetId );
            ...
            startActivityForResult ( pickIntent , REQUEST_PICK_APPWIDGET );
            break ;
    }
    ...
}

当系统活动结束时,它返回与用户选择的应用小工具,你的活动的结果。在下面的例子中,活性通过调用响应
addAppWidget()
添加的应用插件:
public  final  class  Launcher  extends  Activity
        implements  View . OnClickListener ,  OnLongClickListener  {
    ...
    @Override
    protected  void onActivityResult ( int requestCode ,  int resultCode ,  Intent data )  {
        mWaitingForResult =  false ;

        if  ( resultCode == RESULT_OK && mAddItemCellInfo !=  null )  {
            switch  ( requestCode )  {
                ...
                case REQUEST_PICK_APPWIDGET :
                    addAppWidget ( data );
                    break ;
                case REQUEST_CREATE_APPWIDGET :
                    completeAddAppWidget ( data , mAddItemCellInfo ,  ! mDesktopLocked );
                    break ;
                }
        }
        ...
    }
}

该方法
addAppWidget()
检查是否该应用插件需要它的加入之前进行配置:
   

   
   

   
        在启动配置小工具,如果
       

   
        否则,完成添加小部件。
    }
}

有关配置的更多讨论,请参见创建应用程序窗口小部件配置活动
一旦应用小工具已准备就绪,下一步就是做它添加到工作区的实际工作。在 最初的启动使用一种称为方法
completeAddAppWidget()
 来做到这一点。


在Android 4.1及更高的结合应用小工具

搭载Android 4.1增加了API,用于一个更精简的绑定过程。这些API也有可能使一台主机绑定提供自定义UI。要使用此改进方法,您的应用程序必须声明 
BIND_APPWIDGET
在其清单权限:
<使用许可权 的android:名称= “android.permission.BIND_APPWIDGET”  />

但是,这仅仅是第一步。在运行时,用户必须明确授予权限,您的应用程序,使其能够应用小部件添加到主机。要测试你的应用程序是否有权限新增的小工具,可以使用 
bindAppWidgetIdIfAllowed()
 方法。如果
bindAppWidgetIdIfAllowed()
 返回
假的
,你的应用程序必须显示一个对话框,提示用户授予权限(“允许”或“总是允许”,以涵盖所有未来的应用小工具添加)。这段代码提供了如何显示对话框的例子:
Intent intent =  new  Intent ( AppWidgetManager . ACTION_APPWIDGET_BIND );
intent . putExtra ( AppWidgetManager . EXTRA_APPWIDGET_ID , appWidgetId );
intent . putExtra ( AppWidgetManager . EXTRA_APPWIDGET_PROVIDER , info . componentName );
//这是讨论的选项包above
intent . putExtra ( AppWidgetManager . EXTRA_APPWIDGET_OPTIONS , options );
startActivityForResult ( intent , REQUEST_BIND_APPWIDGET );

主机也必须检查用户是否补充说,需要配置一个应用程序部件。有关此主题的更多讨论,请参阅 创建应用程序窗口小部件配置活动


主持人职责


什么版本你定位?

您实现您的主机使用的方法应该取决于你的目标是什么Android版本。许多本节所述的功能在3.0或更高版本进行了介绍。例如:
Android 3.0的(API等级11)介绍了小部件自动推进的行为。
Android的3.1(API等级12)引入了调整部件的能力。
搭载Android 4.0(API等级15)引入该把责任在主机上管理填充填充政策的改变。
搭载Android 4.1(API等级16)增加了一个API,允许小部件供应商,以获取有关在其控件实例被托管环境的更多详细信息。
Android的4.2(API等级17)推出期权包和
bindAppWidgetIdIfAllowed()
方法。它还引入了锁屏小部件。
如果你的目标早期设备,参考原始 启动作为一个例子。

插件开发者可以指定用于使用小窗口的数目的配置设置AppWidgetProviderInfo元数据。这些配置选项,在下面更详细讨论的,可以通过从主机检索
AppWidgetProviderInfo
 与小窗口提供者相关联的对象。
无论你的目标了Android版本,所有主机具有以下职责:
当添加窗口小部件,则必须按照上述分配部件ID。您还必须确保当一个小部件从主机中删除,你可以调用
deleteAppWidgetId()
 来释放小部件ID。
当添加窗口小部件,可以肯定如果存在推出配置活动,如描述从配置活动更新应用的Widget。这是许多应用小部件的必要步骤可以正确显示前。
每一个应用程序窗口小部件指定的dps的最小宽度和高度,如定义
AppWidgetProviderInfo
元数据(使用
安卓了minWidth
安卓了minHeight
)。确保小部件至少有这么多的dps布局。例如,许多主机对齐栅格图标和窗口小部件。在这种情况下,在默认情况下,主机应使用满足细胞的最小数量添加的应用插件
了minWidth
了minHeight
约束。
除了上面列出的要求,具体版本的平台引入放置在主机上新的责任功能。这些将在以下各节中描述。


Android 3.0的

Android 3.0的(API等级11)介绍了一个小部件,以指定的能力
autoAdvanceViewId() 
。这种观点ID应指向一个实例 
中推进
,如
StackView
 或
AdapterViewFlipper
。这表示主机应该调用
预先()
这一观点在间隔认为适当的宿主(考虑到是否有意义推进插件,例如,主机可能不希望如果提前一个小部件是另一个页上,或如果屏幕被关闭)。


Android版3.1

Android的3.1(API等级12)引入了调整部件的能力。一个小部件可以指定它使用调整大小 
的android:resizeMode
 在属性
AppWidgetProviderInfo
 元数据,并说明它是否支持水平和/或垂直大小调整。在Android
4.0的(API级别14)介绍,小部件也可以指定一个 
机器人:minResizeWidth
 和/或
机器人:minResizeHeight

它是主机的责任,这使该插件被水平和/或垂直地调整,由插件规定的。这说明它是可以调整大小可以调整任意大,但不应改变大小比规定值小的小部件
的Android版
​​本:minResizeWidth
 和
机器人:minResizeHeight
。有关示例实现,请参阅 
AppWidgetResizeFrame
的launcher2


Android 4.0的

搭载Android 4.0(API等级15)引入该把责任在主机上管理填充填充政策的改变。作为4.0,应用小部件不再包括自己的填充。相反,系统添加填充每个部件,基于当前屏幕的特性。这导致一个更均匀,在网格部件的一致呈现。为了帮助该主机的应用程序窗口小部件,该平台提供的方法应用 
getDefaultPaddingForWidget() 
。计算细胞的数量分配给widget时应用程序可以调用此方法来获取系统定义的填充和解释它。


搭载Android 4.1

搭载Android 4.1(API等级16)增加了一个API,允许小部件供应商,以获取有关在其控件实例被托管环境的更多详细信息。具体地,主机暗示至约在正被显示的窗口小部件的尺寸小窗口提供者。这是主机的责任提供这种规模的信息。
主机通过提供此信息 
updateAppWidgetSize() 
。的大小指定为在DPS的最小和最大宽度/高度。一个范围(而不是一个固定的大小)的原因是因为一个小窗口的宽度和高度可以与取向发生变化。你不希望主机必须更新其所有的旋转部件,因为这可能会导致严重的系统运行缓慢。这些值应从前的插件来更新被放置,所述插件被调整大小的任何时间,任何时间发射膨胀用于在给定引导在第一时间(作为值不跨越启动持续)的部件。


Android 4.2版

对于选择在捆绑绑定时指定的Android 4.2(API等级17)增加的能力。这是指定的应用程序插件选项,包括大小的理想方法,因为它给了
AppWidgetProvider
直接访问数据的选项在第一次更新。这可以通过使用该方法来实现
bindAppWidgetIdIfAllowed() 
。有关此主题的更多讨论,请参阅绑定应用程序部件
Android 4.2版还引入了锁屏小部件。当主机在锁定屏幕上的小部件,主机必须指定应用程序窗口小部件选项包内该信息(
AppWidgetProvider
可以使用这些信息来适当方式进行样式设置)。要指定一个widget作为锁屏插件,使用
updateAppWidgetOptions() 
,包括现场 
OPTION_APPWIDGET_HOST_CATEGORY
 与价值
WIDGET_CATEGORY_KEYGUARD
。此选项默认为 
WIDGET_CATEGORY_HOME_SCREEN
,所以也没有明确要求,设置本作的主屏幕主机。
请确保您的主机只增加了应用小工具,适合你的应用程序,例如,如果你的主机是主屏幕,确保 
机器人:widgetCategory
 在属性 
AppWidgetProviderInfo
元数据包括标志
WIDGET_CATEGORY_HOME_SCREEN
。同样,对于锁屏,确保字段包括标志 
WIDGET_CATEGORY_KEYGUARD
。有关此主题的更多讨论,请参阅 在锁屏启用应用程序的窗口小部件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息