如何在自己的程序中添加appWidget

1.概述

widget宿主端进程(比如Launcher) :AppWidgetService AppWidgetManager  AppWidgetHostView   AppWidgetHost 

widget客户端进程:RmoteViews  AppWidgetProviderInfo   AppWidgetProvider(extends BroadcastReceiver)

2.相关类介绍

2.1.AppWidgetService.java

这是widget framework的核心类,是系统service之一,它承担着所有widget的

管理工作。Widget安装,删除,更新等等都需要经过AppWidgetService.它是开机就启动的.

在开机过程中,java层进程System Server启动后(这个进程管理着所有的系统service, 例如
activity manager service, windows manager service, power manager service等),会创建
AppWdigetService的实例,并调用它的SystemReady()方法,在这个方法里,它做了三件事:
1)遍历所有的安装包,找到符合条件ACTION=ACTION_APPWIDGET_UPDATE和<meta-data android:name="android.appwidget.provider"/>的intent receiver,解析相关信息,保存到本地数据成员中。
2)读取本地文件数据:/data/system/appwidgets.xml,所有已安装到桌面的widget的信息都保存在这个文件里。读出来,也保存到本地数据成员里。

3)注册了三个消息:ACTION_BOOT_COMPLETED(系统启动到桌面就会发送此消息),ACTION_PACKAGE_ADDED(有新APK包安装到系统),ACTION_PACKAGE_REMOVED(有APK包被删除)。当系统启动到桌面后,AppWidgetService接收到了ACTION_BOOT_COMPLETED消息,它会去检查本地数据成员,如果有已经安装到桌面的widget,它会上发ACTION_APPWIDGET_ENABLED和ACTION_APPWIDGET_UPDATE消息。如果有widget设置了updatePeriodMillis的属性,它就会开始计时(这个是通过AlarmManager来实现的),到时间时,就会再次上发ACTION_APPWIDGET_UPDATE消息。


2.2AppWidgetManager 

是AppWidgetService的客户端代理,是标准的AIDL通讯。IAppWidgetService.java  

2.3.RemoteViews

并不是一个真正的View,它没有实现View的接口,而只是一个用于描述View的实体。比如:创建View需要的资源ID和各个控件的事件响应方法。RemoteViews会通过进程间通信机制传递给AppWidgetHost。

2.4.AppWidgetHostView

是真正的View,但它只是一个容器,用来容纳实际的AppWidget的View。这个AppWidget的View是根据RemoteViews的描述来创建。这是在updateAppWidget里做的:
remoteViews.apply创建了实际的View

2.5.AppWidgetHost

是真正容纳AppWidget的地方,它的主要功能有两个:
o 监听来自AppWidgetService的事件:

o 另外一个功能就是创建AppWidgetHostView。

3.在自己的程序中添加appWidget

如何创建一个AppWidget网上有大量的资料和代码,我这里就不赘述了。

下面来看看如何在自己的程序中添加appWidget(仿Launcher)

一共有三个源文件

  • LauncherAppWidgetHostView扩展了AppWidgetHostView,实现了对长按事件的处理。

public class LauncherAppWidgetHostView extends AppWidgetHostView {
    private LayoutInflater mInflater;
    private Context mContext;
    private int mPreviousOrientation;

    public LauncherAppWidgetHostView(Context context) {
        super(context);
        mContext = context;
//        mLongPressHelper = new CheckLongPressHelper(this);
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
//    @Override
//    protected View getErrorView() {
//        return mInflater.inflate(R.layout.appwidget_error, this, false);
//    }
    @Override
    public void updateAppWidget(RemoteViews remoteViews) {
        mPreviousOrientation = mContext.getResources().getConfiguration().orientation;
        super.updateAppWidget(remoteViews);
    }
    public boolean orientationChangedSincedInflation() {
        int orientation = mContext.getResources().getConfiguration().orientation;
        if (mPreviousOrientation != orientation) {
           return true;
       }
       return false;
    }
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //  return true :Consume any touch events for ourselves after longpress is triggered
        // Otherwise continue letting touch events fall through to children
        return false;
    }
}

  • LauncherAppWidgetHost扩展了AppWidgetHost,这里只是重载了onCreateView,创建LauncherAppWidgetHostView的实例。

public class LauncherAppWidgetHost extends AppWidgetHost {
    public LauncherAppWidgetHost(Context context, int hostId) {
        super(context, hostId);
    }
    @Override
    protected AppWidgetHostView onCreateView(Context context, int appWidgetId,
            AppWidgetProviderInfo appWidget) {
        return new LauncherAppWidgetHostView(context);
    }
    @Override
    public void stopListening() {
        super.stopListening();
        clearViews();
    }
}
  • HelloAcitvity.java

public class HelloActivity extends Activity {

    private ArrayList<AppWidgetProviderInfo> mWidgets = new ArrayList<AppWidgetProviderInfo>();
    private LauncherAppWidgetHost mAppWidgetHost;
    private PackageManager mPackageManager;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Get the list of widgets 
        updatePackages();

        mPackageManager = this.getPackageManager();
        mAppWidgetHost = new LauncherAppWidgetHost(this, 1001);
        //startListening AppWidgetChanged
        mAppWidgetHost.startListening();
        
        int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
        final AppWidgetProviderInfo widgetInfo = mWidgets.get(4);
        //获取RemoteView描述的对应的View
        LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) mAppWidgetHost.createView(
                this, appWidgetId, widgetInfo);
         
        final LinearLayout layout2 = new LinearLayout(this);
        layout2.setOrientation(LinearLayout.VERTICAL);
        layout2.addView(hostView);
        setContentView(layout2);
    }
    // 取自 AppsCustomizePagedView
    public void updatePackages() {
        mWidgets.clear();
        List<AppWidgetProviderInfo> widgets =
                AppWidgetManager.getInstance(this).getInstalledProviders();
        // Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
        // List<ResolveInfo> shortcuts =
        // mPackageManager.queryIntentActivities(shortcutsIntent, 0);
        for (AppWidgetProviderInfo widget : widgets) {
            if (widget.minWidth > 0 && widget.minHeight > 0) {
                Log.d("yzy", widget.label);
                mWidgets.add(widget);
            }
        }
        // mWidgets.addAll(shortcuts);
    }
}





你可能感兴趣的:(如何在自己的程序中添加appWidget)