web-dev-qa-db-ja.com

同じアプリに複数のウィジェットを追加する方法は?

Androidウィジェットを終了しました。ユーザーが選択できるように、このウィジェットのサイズを変更する必要があります。

たとえば、中、小、大のウィジェットが必要なので、ユーザーがアプリをインストールしてホーム画面を押し、ウィジェットを選択すると、ウィジェットメニューで同じアプリ名でサイズが同じ3つのウィジェットが表示されるようにします。このようなもの:

ハロースモールハローミディアムハローラージ

ミディアムを用意しましたが、同じアプリに小と大を追加するにはどうすればよいですか? 3つのサイズすべてに同じ正確なデータとアクションが含まれていることがわかっているため、サイズと背景だけが異なります。

62
BarcaDroid

マニフェストファイルの各タイプには、次のようなレシーバー定義が必要です。

    <receiver Android:name=".MyWidget" Android:label="@string/medium_widget_name">
        <intent-filter>
            <action Android:name="Android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data Android:name="Android.appwidget.provider"
            Android:resource="@xml/medium_widget_provider" />
    </receiver>

    <receiver Android:name=".MyWidget" Android:label="@string/large_widget_name">
        <intent-filter>
            <action Android:name="Android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data Android:name="Android.appwidget.provider"
            Android:resource="@xml/large_widget_provider" />
    </receiver>

これにより、同じAppWidgetProviderクラスを複数のウィジェットに使用でき、異なるウィジェット名と異なるサイズを<appwidget-provider> XMLで定義できます。

<appwidget-provider> XMLにあるものよりもウィジェットに多くの違いが必要な場合は、異なるタイプ間のすべての一般的な動作を実装する基本ウィジェットクラスを作成します。

public abstract class MyBaseWidget extends AppWidgetProvider

そして、具体的な実装のそれぞれがMyBaseWidgetを拡張できます。次に、マニフェストファイルで、具体的な実装ごとに次のようなレシーバ定義を作成します。

    <receiver Android:name=".MyMediumWidget" Android:label="@string/medium_widget_name">
        <intent-filter>
            <action Android:name="Android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data Android:name="Android.appwidget.provider"
            Android:resource="@xml/medium_widget_provider" />
    </receiver>

    <receiver Android:name=".MyLargeWidget" Android:label="@string/large_widget_name">
        <intent-filter>
            <action Android:name="Android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data Android:name="Android.appwidget.provider"
            Android:resource="@xml/large_widget_provider" />
    </receiver>
101
Mark B

実際、各ウィジェットのAndroid:nameは異なっている必要があります。例のようにこれを行うと、ウィジェットリストには1つのウィジェットのみが表示されます。

26
korro

みんな、私は同じ問題を抱えていた。

実際に2番目のウィジェットプロバイダーも追加する必要があります。

<receiver Android:name=**".MyWidget**" Android:label="@string/medium_widget_name">
    <intent-filter>
        <action Android:name="Android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data Android:name="Android.appwidget.provider"
        Android:resource="@xml/medium_widget_provider" />
</receiver>

<receiver Android:name=**".MyWidget2"** Android:label="@string/large_widget_name">
    <intent-filter>
        <action Android:name="Android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data Android:name="Android.appwidget.provider"
        Android:resource="@xml/large_widget_provider" />
</receiver>

楽しい

11
jblz

わかりましたので、基本的にあなたが必要になります:

各ウィジェットのレイアウトファイル。例:main_small.xml、main_medium.xml ...

xmlディレクトリで、各ウィジェットのプロバイダーを追加します。例:small_provider.xml、medium_provider.xml ...など(xmlディレクトリがない場合は、描画可能ディレクトリの下に追加してください)。

それで!

  • マニフェストでレシーバーを定義しますfor eachウィジェット。 (主な答えの例のように)

  • 同じレイアウトまたは異なるレイアウトを使用できます。基本的にこれはあなた次第です。

  • プロバイダーには次のようなものが必要です。

<?xml version="1.0" encoding="utf-8"?>

<appwidget-provider xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:minWidth="146dip"
    Android:minHeight="138dip"
    Android:updatePeriodMillis="10000"
    Android:initialLayout="@layout/main"
    />

各プロバイダーで、使用するターゲットレイアウトファイルを指定するようにしてください。このコードでは、レイアウトディレクトリのファイルmain.xmlを要求しています。たとえば、中規模のウィジェットの場合、まったく同じコードを持つ別のプロバイダーがありますが、最後の行を変更します

> Android:initialLayout="@layout/medium".

これが私に知らせてくれない場合に役立つことを願っています。私のウェブサイトに実際の例をアップロードして、あなたがそれを詳しく見ることができます。それがどうなるか教えてください。

幸運を祈ります。

5
user308238

他の回答への追加情報...

  • 上記のファイルを複製する場合、ウィジェットがServiceを使用して機能を提供する場合、サービスを複製する必要があります。

  • Serviceを複製する場合、新しいサービスでマニフェストを更新することを忘れないでください、そうでない場合、新しいサービスは実行されません...

これは私にとって時間を無駄にしました。


BroadcastReceiverを使用してIntentsを重複するServicesに送信する場合は、そのコードも更新することを忘れないでください。

  • サービスのeachにインテントを送信する必要があります。
0