3

作業中のカスタムランチャーでホーム画面にウィジェットを追加する際に問題が発生します。

AppWidgetManagerを使用して追加するウィジェットのリストを生成することができ、ウィジェットをホーム画面に追加するためのワークフローを開発しました。コードは以下のとおりではありませんが、次のようになります。

AppWidgetHost widget_host = new AppWidgetHost(this, 1);
AppWidgetManager widget_manager = AppWidgetManager.getInstance(this);

int widget_id = widget_host.allocateAppWidgetId(); 
AppWidgetProviderInfo widget_provider = ... //from an array;

Intent bindIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget_id);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, widget_provider.provider);
startActivityForResult(bindIntent, REQUEST_BIND_APPWIDGET);

if (widget_provider.configure != null) {
    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
    intent.setComponent(widget_provider.configure);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget_id);
    startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
} else {
    createWidget(widget_id);
}

次に、必要に応じてウィジェットの構成につながるonActivityResultメソッドがあり、createWidgetメソッドはAppWidgetHostのcreateViewメソッドを使用します。

このワークフローは機能しますが、ACTION_APPWIDGET_BINDインテントはユーザーにアプリをバインドする許可を求めます。これはちょっと面倒です。私の理解では、システムアプリのみがこのアクセス許可を要求でき、アプリの実行中にこのアクセス許可を要求せずにウィジェットをバインドすることはできません。一方、他にも多くのランチャーがあり、それらはすべてウィジェットをシームレスに追加できることを私は知っています。したがって、これには別のアプローチが必要です。

アドバイスをいただければ幸いです。

乾杯

4

2 に答える 2

3

質問がまだ開いていることを願っています...

メソッド内でやりすぎです。特定の状況下では、次々と短時間でイベントを発生させます。私はAndroidであまり長く働いていないので、これが大丈夫かどうかはわかりません.

そして、ここで常にインテントを起動します。

Intent bindIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget_id);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, widget_provider.provider);
startActivityForResult(bindIntent, REQUEST_BIND_APPWIDGET);

上記の意図は、最も可能性の高い質問を引き起こします。事前に許可が必要かどうか確認しておきましょう。このルーチンで尋ねることができます:

Boolean callProviderIntent = false;
if (checkCallProviderIntent)
{
    callProviderIntent = true;
    Method m = null;
    try
    {
        m = AppWidgetManager.class
            .getMethod("bindAppWidgetIdIfAllowed", new Class[]
            { Integer.TYPE, ComponentName.class });
    }
    catch (NoSuchMethodException e)
    {
    }
    if (m != null)
    {
        try
        {
            callProviderIntent = !(Boolean) m
             .invoke(mAppWidgetManager,
                     appWidgetId,
                     launcherAppWidgetInfo.provider);
        }
        catch (Exception e)
        {
        }
    }
}

ダミーコードです。私はAndroid 2.3の下にいるので、リフレクションを使用しています。

于 2013-02-23T23:27:43.303 に答える
3

これが、私のアプリケーションで最終的に見つけたソリューションです。

            AppWidgetManager manager = m.getAppWidgetManager();
            AppWidgetHost host = m.getWidgetHost();

            List<AppWidgetProviderInfo> widgetList = manager.getInstalledProviders();

            AppWidgetProviderInfo provider = null;
            for(AppWidgetProviderInfo info : widgetList){
                //To get the google search box
                if(info.provider.getClassName().equals("com.google.android.googlequicksearchbox.SearchWidgetProvider")){
                    provider = info;
                    break;
                }
            }
            if(provider != null){
                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.hostView = hostView;
                    info.hostView.setAppWidget(id, appWidgetInfo);
                    attachWidget(info);
                } else {
                    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER,
                            provider.provider);
                    // TODO: we need to make sure that this accounts for the options
                    // bundle.
                    // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS,
                    // options);
                    m.startActivityForResult(intent, Main.REQUEST_BIND_APPWIDGET);
                }

            }
        }
于 2014-12-27T10:04:40.353 に答える