2

ホームスクリーンにあるウィジェットからアプリケーションのActivityの関数を呼び出す適切な方法は何ですか?私の例では、私は自分のActivityクラスで初期化されたバックグラウンドスレッドを持っていて、アプリケーションに入ることなくスレッドを開始/停止する特定の関数を呼び出すためにホーム画面からウィジェットを押すことができます。HomeScreenウィジェットからアクティビティの関数を呼び出す方法

以下

私が働いている活動の剥奪とベアボーンのバージョンである:

以下
public class MainActivity extends AppCompatActivity { 
    private Thread thread; 
    private Runnable runner; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     startThread(); 
    } 

    private void startThread() { 
     //start/restart the thread 
    } 

    public void stopThread() { 
     //interupt the thread 
    } 
} 

ホーム画面のウィジェットのベアボーンコードです:ここで

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { 

    Intent intent = new Intent(context, MainActivity.class); 

    intent.putExtra("Goal","Stop"); 
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); 

    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.speed_widget); 
    views.setOnClickPendingIntent(R.id.widgetButton, pendingIntent); 

    appWidgetManager.updateAppWidget(appWidgetId, views); 
} 

は最高のものを私の現在であります私がこれまで行ってきた研究から、putExtra()と引き続きgetExtra()をウィジェットから送信されたインテントと共に使用し、startThread()または0を呼び出すかどうかを示す文字列を追加する必要があるようですは、スレッドのステータスに基づいています。現在の目標は、このようにそれを使用することです:

String intentGoal = getIntent().getExtras().getString("Goal"); 
    if(intentGoal.compareTo("Stop")==0){ 
     stopThread(); 
    }else if(intentGoal.compareTo("Start")==0){ 
     startThread(); 
    } 

そして、それは最も可能性の高いonNewIntent()のオーバーロードされたバージョンで走ったことになります。しかし、ウィジェットから送信されたインテントはonCreate()にもコールされます。これは、スレッドや他の初期化コードを再起動するため、再実行されるため、発生したくないものです。私はlaunchModeをsingleTaskに設定しようとしましたが、それでもonNewIntent()ではなくonCreate()が呼び出されます。要約すると、私はホーム画面ウィジェットを押して、スレッドを開始または停止させたり、より一般的には既存の `MainActivity '内の特定の関数を呼び出すことができます。

答えて

0

Michael Spitsinの回答とthe answer hereの間で、私はホーム画面ウィジェットのボタンがクリックされたときに特定のメソッドを実行する方法を見つけ出すことができました。マイケルが言ったように、getBroadcastgetActivityの間に違いがあります。このような場合のために、私は意図をブロードキャストするgetBroadcastを使用することができたが、代わりに意図がMainActivityを開くことも有していると、私は「これは」機能updateAppWidgetがであるクラスであるthis.classを、使用していました。

何これはそれ自体に意図をブロードキャストし、同クラスのonReceive(Context,Intent)にキャッチされます。 onReceiveによってキャッチされた他のインテントと自分自身を区別する方法を与えるために送信するインテントにaddActionを必ず使用してください。以下は、私がウィジェットを稼働させるために得たものの剥き落ちた骨なしのバージョンです:

public class MyWidget extends AppWidgetProvider { 
    public static String YOUR_ACTION = "YourAction"; 

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { 

     Intent intent = new Intent(context, SpeedWidget.class); 
     intent.setAction(YOUR_ACTION); 

     PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); 
     RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.speed_widget); 
     views.setOnClickPendingIntent(R.id.widgetButton, pendingIntent); 

     appWidgetManager.updateAppWidget(appWidgetId, views); 

    } 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     super.onReceive(context, intent); 

     if (intent.getAction().equals(YOUR_ACTION)) { 
       //THIS IS WHERE YOUR CODE WILL BE EXECUTED 
      } 
     } 
    } 
} 
1

私はウィジェットの構築プロセスの専門家でないんだけど、私はあなたが変更する必要があると仮定します。

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); 

へ:

PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); 

アプリケーションとの何らかの相互作用を提供する必要があるので、特定のアクティビティにウィジェットをアタッチする必要はありません。代わりに、あなたはメッセージングのメカニズムを言うために使用する必要があります。 Androidの場合はBroadcastRecieverです。たとえば、これを使用して「開始」サービスと対話します。 here about simple exampleを読むことができます。

次にonRecieve方法では、あなたの意図を解析し、あなた何を行うことができます。

また、this答えに応じて私たちは、あなたがマニフェストにレシーバを登録する必要があること、ソリューションに来ました欲しいです。あなたの場合は、アクティビティを閉じることができるので(Serviceでも、画面なしで復元して実行できます)、バックグラウンドで作業することをお勧めします。ActivityからServiceに移動してください。そしてMyWidgetReciever.onReceiveでは、あなたは "stop"インテントを渡してサービスを開始する必要があります。

私はよく分かりませんが、外部の受信者ではなく、直接サービスで放送を捕捉することはできますが、サービスが強制終了されると状況が悪化する可能性があります。

関連する問題