标题解释了所有...我在我的应用程序中有这段代码:
String url = createTelUrl("3112007315");
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse(url));
context.startActivity(intent);
它会拨打电话,但一旦通话结束,我的应用程序就会崩溃。一旦通话结束,我想回到我的应用程序,但我读了this post,似乎不可能。那么......无论如何,至少暂停我的应用程序并在通话结束后恢复它?
修改
感谢我收到的两个答案,我觉得我真的很接近我的目标......我已经完成了你们建议的一些事情。但是,也许我没有解释应用程序的一些细节...我正在开发谁想成为Millonarie 游戏,所以我需要实现调用(我不知道它是怎么称的在美国或其他国家,但在这里我们称之为“打电话给朋友”。)
无论如何......我对这个应用程序做了太多更改,现在它没有崩溃。但是,一旦调用结束,我绘制UI的Canvas就不显示了。
我有一个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");
}
}
在我开始实施电话呼叫之前,这很好用。这里的问题是,一旦调用结束并再次执行start方法,该方法抛出IllegalThreadStateException
,因为该线程已经启动。我尝试使用一些'技术'来暂停UI线程,但我无法解决这个问题。我尝试过这样的事情:
// this in the UI thread class
if(haveToWait)
wait();
....
// this in the surface view class
if(callEnded)
hilo.notify();
但那没用。我也尝试了其他一些“技巧”,例如使用sleep(50);
代替wait();
,但它也不起作用。
根据我提供的所有信息......你能给我什么建议?
答案 0 :(得分:5)
可以使用android.telephony.PhoneStateListener
。
首先,我们需要处理应用程序的清单:
我们需要获得拨打电话的权限(duh!)以及观看电话状态的权限。后者是必需的,因此app也可以对呼叫的结束作出反应。因此,我们将这些行添加到应用程序清单中:
<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!
答案 1 :(得分:5)
这里的问题是你用来启动线程的地方。一旦你开始一个新的电话,你的主要活动将被暂停,并且表面视图将被销毁。虽然,该线程将继续运行。因此,一旦您的应用程序取回控件,将再次创建曲面并调用start方法。这会导致IllegalThreadStateException。
这里的方法是从SurfaceView类中操纵线程。这将使您能够控制主活动中的线程,并且您将能够决定何时开始或暂停您的线程。
答案 2 :(得分:1)
至于崩溃 - 请发布日志并将调试器放在Start / onResume上以找出崩溃的原因。有可能在错误的地方初始化某些东西,你可能会像nullpointer一样简单。
至于通话结束的事情 - 我从来没有试过这个,但我会尝试注册接收器,赶上 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中使用该功能的应用程序中使用它的示例