【问题标题】:Android Adding Widgets To App Programmatically Warning MessageAndroid以编程方式将小部件添加到应用程序警告消息
【发布时间】:2014-11-10 16:02:28
【问题描述】:

我创建了一个测试 Android 启动器应用程序,并将其作为系统应用程序安装在有根设备上。目标是让应用程序将所有已安装的小部件放置在 viewpager 的片段上。这已成功完成;但是,每次显示新页面时都会向用户显示一条消息。

即使用户选中该框,每次添加小部件时仍会显示该消息。

我通常按照Hosting widgets in an android launcherAdding widgets to a launcher page without bindAppWidgetId() 中的步骤将小部件添加到应用程序。

首先我得到一个扩展应用程序的类中的小部件列表并将其存储在一个公共静态变量中

AppWidgetManager manager = AppWidgetManager.getInstance(this); 
widgetList = manager.getInstalledProviders();

接下来我使用绑定意图来获取小部件

appWidgetManager = AppWidgetManager.getInstance(this.getActivity());
appWidgetHost = new AppWidgetHost(this.getActivity(), APPWIDGET_HOST_ID);
int id = appWidgetHost.allocateAppWidgetId();
Intent bindIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER,LauncherExperiment.widgetList.get(mParam1).provider);
startActivityForResult(bindIntent, REQUEST_BIND_APPWIDGET);

然后根据活动结果创建小部件

Bundle extras = data.getExtras();
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
AppWidgetProviderInfo appWidgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);

AppWidgetHostView hostView = appWidgetHost.createView(this.getActivity(), appWidgetId, appWidgetInfo);
hostView.setAppWidget(appWidgetId, appWidgetInfo);
// Add  it on the layout you want
myLayout.addView(hostView);

再次,我已通过更新清单将设备植根并安装为系统应用

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.launcherexperiment"
android:sharedUserId="android.uid.system" >

并按照此处的步骤操作: How can I sign my application with the system signature key?

所以综上所述,我已经能够成功的绑定应用并展示出来了;但问题是警告信息应该最多显示一次。

【问题讨论】:

    标签: java android widget


    【解决方案1】:

    我们来了!使用此代码,用户只会看到一次对话框。 它还展示了以编程方式添加小部件的完整解决方案。

    由于我将在我的 github 上更新此内容,请在此处查找最新版本,https://github.com/DagW/FragmentHomescreen/blob/master/app/src/main/java/se/dw/fragmenthomescreen/widget/WidgetFragment.java

    但出于存档目的,这是我现在的做法。

    /**
     * checkToAddWidget
     * <p/>
     * At the creation of WidgetFragment,
     * add a default widget so that the homescreen is not empty
     * shows how to add widgets programmatically
     */
    private void checkToAddWidget () {
            MainActivity m = (MainActivity) getActivity();
            AppWidgetManager manager = m.getAppWidgetManager();
            AppWidgetHost host = m.getAppWidgetHost();
    
            List<AppWidgetProviderInfo> widgetList = manager.getInstalledProviders();
    
            AppWidgetProviderInfo searchProvider = null;
            AppWidgetProviderInfo search2Provider = null;
            AppWidgetProviderInfo clockProvider = null;
    
            for ( AppWidgetProviderInfo info : widgetList ) {
                Log.d(TAG, info.provider.getPackageName() + " " + info.provider.getClassName());
                if ( info.provider.getClassName().equals("com.google.android.googlequicksearchbox.SearchWidgetProvider") ) {
                    searchProvider = info;
                    break;
                }
                if ( info.provider.getClassName().equals("com.android.alarmclock.AnalogAppWidgetProvider") ) {
                    clockProvider = info;
                }
                if ( info.provider.getClassName().equals("com.android.alarmclock.DigitalAppWidgetProvider") ) {
                    clockProvider = info;
                }
                if ( info.provider.getClassName().equals("com.android.quicksearchbox.SearchWidgetProvider") ) {
                    search2Provider = info;
                }
            }
            if ( searchProvider != null || search2Provider != null || clockProvider != null ) {
                AppWidgetProviderInfo provider = null;
                if ( searchProvider != null ) {
                    provider = searchProvider;
                } else if ( clockProvider != null ) {
                    provider = clockProvider;
                } else {
                    provider = search2Provider;
                }
    
                addProvider(m, host, manager, provider);
            }
        }
    
    
    
    public void addProvider (MainActivity m, AppWidgetHost host, AppWidgetManager manager, AppWidgetProviderInfo provider) {
        int id = host.allocateAppWidgetId();
        boolean success = false;
        success = manager.bindAppWidgetIdIfAllowed(id, provider.provider);
    
        if ( success ) {
            AppWidgetHostView hostView = host.createView(getActivity(), id, provider);
            AppWidgetProviderInfo appWidgetInfo = manager.getAppWidgetInfo(id);
    
            LauncherAppWidgetInfo info = new LauncherAppWidgetInfo(id);
            info.setHostView(hostView);
            info.getHostView().setAppWidget(id, appWidgetInfo);
    
            ItemInfo launcherInfo = attachWidget(info);
            if ( launcherInfo != null ) {
                WidgetPersistance.addDesktopAppWidget(screen, launcherInfo);
            }
    
        } else {
            Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, provider.provider);
            m.startActivityForResult(intent, MainActivity.REQUEST_BIND_APPWIDGET);
        }
    
    }
    

    你可能还需要

    <uses-permission android:name="android.permission.BIND_APPWIDGET"
                     tools:ignore="ProtectedPermissions"/>
    

    【讨论】:

    • 该权限仅对系统应用可用。在您的应用程序中,它什么也没做。除非您希望用户成为 root 并将您的应用转换为系统应用。
    • 这非常接近我的解决方案。如果您单击小部件并打开相关的应用程序,一旦您单击返回,您的整个应用程序就会关闭,您是否也遇到过问题? (而不是回到您的应用程序)
    • 实际上,奇怪的是,我需要获得该权限,尽管正如你所说的那样。也许在您被选为默认启动器之后?
    猜你喜欢
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多