无论应用程序当前是否正在运行,我都需要能够接收传入的Twilio调用。
用户启动应用程序并登录我们的服务器后,我将启动下面显示的服务。
服务以粘性方式启动,并且在任何时候都没有调用stopService
或stopSelf
等,因此应用程序关闭后服务仍应运行。
当应用程序运行时,IncomingCallActivity
启动正常以响应Twilio调用。
如果应用程序在后台,IncomingCallActivity
仍然可以正常响应Twilio通话。
如果应用已关闭,IncomingCallActivity
将不再启动以响应Twilio通话。
如果应用已关闭,为什么没有IncomingCallActivity
启动?
public class CallService extends Service implements Twilio.InitListener, DeviceListener, ConnectionListener {
private Device mDevice;
private Connection mConnection;
@Override
public void onCreate() {
super.onCreate();
registerBroadcastReceiver();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Initialize the Twilio SDK if required
if (!Twilio.isInitialized()) {
Twilio.initialize(getApplicationContext(), this);
} else {
getCapabilityToken("CallService", getUser());
}
...
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
// Unregister broadcast receiver
final LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
localBroadcastManager.unregisterReceiver(mBroadcastReceiver);
super.onDestroy();
}
@Override
public void onInitialized() {
getCapabilityToken("CallService", getUser());
}
@Override
public void onError(Exception e) {
}
private void getCapabilityToken(String string, User user) {
// Request the capability token from the server.
...
}
protected void setCapabilityToken() {
// Create device using the capability token
mDevice = Twilio.createDevice(getUser().capabilityToken, this);
// Set pending intent for Twilio device
Intent intent = new Intent(this, IncomingCallActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mDevice.setIncomingIntent(pendingIntent);
// Broadcast that CallService is ready, to any registered receivers
Intent broadcastIntent = new Intent(App.ACTION__TWILIO_SERVICE_READY);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
}
public void connect() {
mConnection = mDevice.connect(null /* parameters */, null /* ConnectionListener */);
if (mConnection == null) {
...
} else {
...
}
}
private void answerCall(Device device, Connection connection) {
if (mConnection != null) {
mConnection.disconnect();
}
mConnection = connection;
mConnection.accept();
}
/**
* BroadcastReceiver
*/
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
switch (action) {
case App.ACTION__CAPABILITY_TOKEN_OBTAINED:
setCapabilityToken();
break;
case App.ACTION__CONNECT:
connect();
break;
}
}
};
@Override
public void onStartListening(Device device) {
}
@Override
public void onStopListening(Device device) {
}
@Override
public void onStopListening(Device device, int i, String s) {
}
@Override
public boolean receivePresenceEvents(Device device) {
return false;
}
@Override
public void onPresenceChanged(Device device, PresenceEvent presenceEvent) {
}
@Override
public void onConnecting(Connection connection) {
}
@Override
public void onConnected(Connection connection) {
}
@Override
public void onDisconnected(Connection connection) {
}
@Override
public void onDisconnected(Connection connection, int i, String s) {
}
}
为了澄清我如何宣布我的服务等,这是我的AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="au.com.encall.encall"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".IncomingCallActivity"
android:screenOrientation="portrait"/>
<service android:name=".services.CallService"/>
<service android:name=".services.DownloadService"/>
<service
android:name="com.twilio.client.TwilioClientService"
android:exported="false"
android:stopWithTask="false" />
<meta-data
... />
...
</application>
</manifest>
答案 0 :(得分:1)
如果您使用twilio演示而不是需要在Androidmenifest中提供服务
<service android:name="com.twilio.client.TwilioClientService" android:exported="false" android:stopWithTask="true"/>
它为我工作。
twilio provide他们自己的服务。所以你需要在menifest上声明它。所以不需要创建新的服务。
jusr删除此服务并将其放在android menifest.it将在app关闭后自动启动。
答案 1 :(得分:0)
它对我的工作无需额外服务
<service android:name="com.twilio.client.TwilioClientService" android:exported="false" android:stopWithTask="false"/>
但如果令牌已过期,我们如何处理?那时IncomingCallActivity
不再开始