2010-05-04 184 views
1

標題解釋了所有...我有此代碼段在我的應用程序:撥打電話編程後,我的Android應用程序崩潰

String url = createTelUrl("3112007315"); 
Intent intent = new Intent(Intent.ACTION_CALL); 
intent.setData(Uri.parse(url)); 
context.startActivity(intent); 

它撥打電話,但一旦通話結束,我應用程序崩潰。一旦通話結束,我想回到我的應用程序,但我讀this post,似乎不可能。所以......反正至少暫停我的應用程序並在通話完成後恢復它。

編輯:

感謝我收到了兩個答案,我覺得我真的很接近我的目標。我已經做了一些你們建議的事情。但是,也許我沒有解釋應用程序的一些細節...我正在開發誰想成爲Millonarie遊戲,所以我需要實現調用(我不知道它是如何在美國或其他國家,但在這裏我們稱之爲「打電話給朋友」)。

無論如何...我已經做了太多的改變這個應用程序,現在它不會崩潰。但是,一旦被調用結束,我畫的UI畫布就不會顯示出來。

我有一個SurfaceView持有用戶界面。對於SurfaceView我創建,是爲了刷新UI線程...這基本上是線程做什麼:

@Override 
public void run() { 
    Canvas c; 
    while (_run) { 
     c = null; 
     try { 
      c = _surfaceHolder.lockCanvas(null); 
      // Check if should wait 
      synchronized (_surfaceHolder) { 
       _panel.onDraw(c); 
      } 
     } finally { 
      // do this in a finally so that if an exception is thrown 
      // during the above, we don't leave the Surface in an 
      // inconsistent state 
      if (c != null) { 
       _surfaceHolder.unlockCanvasAndPost(c); 
      } 
     } 
    } 
} 

但是,一旦通話結束,我收到了黑屏。表面在那裏(我知道它,因爲它仍然可以接收一些觸摸事件),但它沒有顯示任何東西。您考慮的另一件事是,我如何從SurfaceView類啓動線程:

public void surfaceCreated(SurfaceHolder holder) { 
    hilo.setRunning(true); 
    try{ 
     hilo.start(); 
    }catch(IllegalThreadStateException ite){ 
     Log.e("wwtbam", "god dammed"); 
    } 
} 

這個工作不錯我纔開始實施的手機通話。這裏的問題是一旦調用結束並且它再次執行啓動方法,該方法會拋出一個IllegalThreadStateException,因爲該線程已經啓動。我試着用一些'技術'在調用時暫停UI線程,但我一直無法解決這個問題。我試着做類似的事情:

// this in the UI thread class 
if(haveToWait) 
    wait(); 
.... 
// this in the surface view class 
if(callEnded) 
    hilo.notify(); 

但是沒有奏效。我也嘗試過使用sleep(50);而不是wait();等其他'技巧',但它也不起作用。

有了我提供的所有信息......你能向我推薦什麼?

回答

5

這裏的問題是你用來啓動線程的地方。一旦你開始一個新的通話,你的主要活動將被暫停,並且Surfaceview將被銷燬。雖然,線程將繼續運行。所以,一旦您的應用程序重新獲得控制權,將再次創建曲面,並調用啓動方法。這會導致IllegalThreadStateException。

這裏要去的方法是操作線程出SurfaceView類。這將使您能夠控制主要活動的線程,並且您將能夠決定何時啓動或暫停您的線程。

看一看這個例子:http://code.google.com/p/apps-for-android/source/browse/trunk/SpriteMethodTest/src/com/android/spritemethodtest/

1

至於崩潰 - 請發佈日誌並將你的調試器onStart/onResume發現你爲什麼崩潰。有可能是在錯誤的地方初始化了一些東西,而你可能會像空指針一樣簡單。

對於呼叫結束的東西 - 我從來沒有嘗試這一點,但我會試着註冊接收器,趕上 http://developer.android.com/reference/android/telephony/TelephonyManager.html#ACTION_PHONE_STATE_CHANGED 評估手機的狀態,你需要做什麼。

也有在這裏更多信息 http://developer.android.com/reference/android/telephony/ http://developer.android.com/reference/android/telephony/PhoneStateListener.html

最後,你會發現如何使用,在這是source.android使用該功能的應用的例子。com

+0

謝謝...我編輯帖子,包括新的信息。 – Cristian 2010-05-09 04:14:03

5

這可以使用​​。

首先,我們需要的應用程序的清單的護理:

我們需要許可才能撥打電話(廢話!),以及觀看手機狀態的權限。後者是需要的,所以應用程序也可以對通話結束做出反應。所以我們這些行添加到了應用程序清單:

<uses-permission android:name="android.permission.CALL_PHONE" /> 
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 

而且,我們不希望在通話結束的Android,開始我們的活動的不同實例,所以我們設置了活動的launchMode屬性「 singleInstance「。

<activity android:name=".CallTest" android:label="Calling Test" 
     android:launchMode="singleInstance" /> 

已經在清單準備好了,我們現在可以看看進行調用的活動:

public class CallTest extends Activity { 
    PhoneStateListener mListener; 
    TelephonyManager mTelMgr; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     mListener = new CallEndedListener(); 
     mTelMgr = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE); 
    } 

    public void makecall(View v) { 
     // Register our listener to be notified of the beginning 
     // and ending of calls 
     mTelMgr.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE); 

     // Start the call 
     Intent call = new Intent(Intent.ACTION_CALL); 
     call.setData(Uri.parse("tel:12345")); 
     startActivity(call); 
    } 

    class CallEndedListener extends PhoneStateListener { 
     boolean called = false; 

     @Override 
     public void onCallStateChanged(int state, String incomingNumber) { 
      super.onCallStateChanged(state, incomingNumber); 

      // Don't fire before the call was made 
      if (state == TelephonyManager.CALL_STATE_OFFHOOK) 
       called = true; 

      // Call has ended -- now bring the activity back to front 
      if (called && state == TelephonyManager.CALL_STATE_IDLE) { 
       called = false; 
       mTelMgr.listen(this, PhoneStateListener.LISTEN_NONE); 
       startActivity(new Intent(CallTest.this, CallTest.class)); 
      } 
     } 
    } 
} 

makecall方法的唯一新的東西,而在問題的代碼片段,是在實際撥打電話之前添加的PhoneStateListener實施。然後,當撥出撥出的電話,來電正在響鈴或正在進行的通話結束時,該監聽器會通過Android獲得通知。

我們的實施等待後者CALL_STATE_IDLE事件並再次開始我們的活動,以便在通話結束後我們回到我們的應用程序中,我們離開它。然後它會自行註銷,所以我們的活動不會在用戶每次結束未由我們自己的活動啓動的呼叫時重新啓動。

但是,當使用TelephonyManager註冊CALL_STATE事件時,Android會立即觸發當前狀態的通知 - 因此我們的偵聽器會在通話開始前觸發。因此,我們的監聽器實現首先會等待直到撥出電話開始(CALL_STATE_OFFHOOK),然後纔會對CALL_STATE_IDLE通知作出反應。

HTH!

+0

感謝您的回覆......我編輯了帖子,以便它提供更多信息。 – Cristian 2010-05-09 04:13:42

相關問題