2012-04-25 3 views
4

PhoneGAPに基づいてアプリケーションをビルドして、電話をかけてから5秒後にアプリに戻る必要があります。PhoneGapから電話をかけた後、主なアクティビティにフォーカスを戻す

電話をかける部分は問題なく動作します。通話だけではなく、ダイヤルパッドとAndroidはオープンにするには、呼び出しを行うコードがcom.phonegap.api.Pluginに入れて、アプリを再起動するには

private void callNumber(String phoneNumber){ 
    Uri calling = Uri.parse("tel:" + phoneNumber); 
    Intent callIntent = new Intent(Intent.ACTION_CALL, calling); 
    this.ctx.startActivity(callIntent); 
} 

のように見えている、イムはちょうどAsyncTaskを起動しますRestartTaskという名前のコールを発信します。このコードはプラグインの中にあるので、RestartTaskを起動するにはActivity.runOnUiThreadを使用する必要がありますが、それ以外に特別なものはありません。 RestartTaskで

は、唯一doInBackground方法が実装されており、それがないすべては、5秒間スリープし、次の意図を実行している:

Intent restartIntent = new Intent(DialerPlugin.this.ctx.getBaseContext(), MainActivity.class); 
restartIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
DialerPlugin.this.ctx.startActivity(restartIntent); 

ここMainActivity延びる、PhoneGapの由来するメインクラスでありますDroidGap

FLAG_ACTIVITY_CLEAR_TOPを設定し、FLAG_ACTIVITY_SINGLE_TOPは、人々がhereを言っていると活動が「再活性化」される場合hereは、設定する必要があり、活動は現在インスタンス化されたタスクが使用されていることを意味するの代わりに、新しいタスクを作成する正確に何であります新しいアクティビティー・インスタンスを作成するのではなく、アクティビティーが実行中の状態で再使用されます。インテントがOSによって提供された場合、「古い」アクティビティにはonNewIntentがコールされます。

しかし、電話がアクティブになると何も起こりません。電話機の1台で電話を切るまで、意図はMainActivityに届かないようです。奇妙な。

フラグを変更してFLAG_ACTIVITY_CLEAR_TOPを含めると、アプリタスクまたはメインアクティビティが再開されます。しかし、これはPhoneGAPなので、どちらも私が望んでいないアプリの再起動に相当します。私はまた、Androidブートを別のタスクでアプリケーションのまったく新しいインスタンスにすることができます。これには焦点が当てられています。

しかし、Androidの主な活動にフォーカスを戻すことはできません。私は間違って何をしていますか?

ありがとうございます!

答えて

3

私は何時間ものハッキングの後にこれを解決することができました。 組み込みダイヤラを使用して電話をかけると、新しいアンドロイドタスクが制御されると、コールを行ったタスクから開始されたバックグラウンドタスクも新しいアクティビティを開始する特権を失い、新しいタスクでアクティビティを開始している場合を除きます。

これは、呼び出しを行う前にアクティビティからAsyncTaskが開始され、ダイヤラタスク/アクティビティが開いていることを確認するために少しスリープ状態になっているため、フォーカスを戻すために新しいタスクを開始する必要があることを意味します。 Cordovaのアクティビティを再び開始するオプションはありません。アプリ全体を効果的に再起動するため、ソリューションは細い再起動タスクを作成し、直ちに終了します。

コルドバのプラグインでは、以下の内部クラスを配置することができます:

protected class RestartTask extends AsyncTask<Void, Void, Void>{ 
    protected RestartTask() { } 

    @Override 
    protected Void doInBackground(Void... unused){ 
     try { 
      // pass time so the built-in dialer app can make the call 
      Thread.sleep(MyPlugin.restartDelay); 
     } 
     catch (InterruptedException localInterruptedException) 
     { 
      Log.d("MyPlugin", "RestartTask received an InterruptedException"); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void justEyeCandy){ 
     super.onPostExecute(justEyeCandy); 

     // Start the RestartActivity in a new task. This will snap the phone out of the built-in dialer app, which 
     // has started in it's own task at this point in time. The RestartActivity gains control and finishes 
     // immediately, leading control back to the activity at the top of the stack in the 
     // app (where the user came from when making the call). 
     Intent restartIntent = new Intent(MyPlugin.this.ctx.getApplicationContext(), RestartActivity.class); 
     restartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     MyPlugin.this.ctx.getApplicationContext().startActivity(restartIntent); 
    } 
} 

このAsyncTaskは呼び出すことで、プラグインに解雇することができます。

this.ctx.runOnUiThread(new Runnable(){ 
    public void run(){ 
     try { 
      RestartTask restartTask = new RestartTask(); 
      restartTask.execute(); 
     } 
     catch (Exception e) { 
      Log.d("MyPlugin", "Exploded when trying to start background task: " + e.getMessage()); 
     } 
    } 
}); 

AsyncTaskがAに起動するためのクラス新しいタスクは次のとおりです。

public class RestartActivity extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // the prototype RestartActivity there is a possibility that this will be the root activity of the app. 
     // If that is the case, this activity will boot the main activity of the app in a new task, before signing off. 
     // However, this is not the case for this app, as restarts are only used once a call diversion has taken place, 
     // form within the app. 
     if (isTaskRoot()) 
     { 
      // Start the app before finishing 
      String packageName = this.getBaseContext().getPackageName(); 
      Intent startAppIntent = this.getBaseContext().getPackageManager().getLaunchIntentForPackage(packageName); 
      startAppIntent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); 
      startActivity(startAppIntent); 
     } 

     // Now finish, which will drop the user in to the activity that was at the top of the task stack 
     finish(); 
    } 
} 
関連する問題