Sinch Audio and Video Calling in Android - android

I am trying to use sinch audio and video calling in android but problem is that how to check that the incoming call is audio or video . I am using shared preference for that purpose.Video to video call works fine on both side and when incoming call is audio on other side video incoming call activity called instead of audio in other user phone. Any help would be Appreciated.
public class SinchService extends Service {
//set the shared preferences
private SharedPreferences mPickSharedPrefs;
private SharedPreferences.Editor mPickSharedPrefsEditor;
private static final String APP_KEY = "*******************";
private static final String APP_SECRET = "****************";
private static final String ENVIRONMENT = "sandbox.sinch.com";
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchService.class.getSimpleName();
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient;
private String mUserId;
private StartFailedListener mListener;
#Override
public void onCreate() {
super.onCreate();
mPickSharedPrefs = getSharedPreferences("mPickSharedPrefs", Context.MODE_PRIVATE);
mPickSharedPrefsEditor=mPickSharedPrefs.edit();
}
#Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminate();
}
super.onDestroy();
}
private void start(String userName) {
if (mSinchClient == null) {
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(userName)
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT).build();
mSinchClient.setSupportCalling(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
// Permission READ_PHONE_STATE is needed to respect native calls.
mSinchClient.getCallClient().setRespectNativeCalls(false);
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.start();
}
}
private void stop() {
if (mSinchClient != null) {
mSinchClient.terminate();
mSinchClient = null;
}
}
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
#Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public Call callUserVideo(String userId) {
// mPickSharedPrefsEditor=mPickSharedPrefs.edit();
mPickSharedPrefsEditor.putString("call_status","1");
mPickSharedPrefsEditor.commit();
return mSinchClient.getCallClient().callUserVideo(userId);
}
public Call callPhoneNumber(String phoneNumber) {
return mSinchClient.getCallClient().callPhoneNumber(phoneNumber);
}
public Call callUser(String userId) {
// mPickSharedPrefsEditor=mPickSharedPrefs.edit();
mPickSharedPrefsEditor.putString("call_status","0");
mPickSharedPrefsEditor.commit();
return mSinchClient.getCallClient().callUser(userId);
}
public String getUserName() {
return mUserId;
}
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName) {
start(userName);
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
public VideoController getVideoController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getVideoController();
}
public AudioController getAudioController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getAudioController();
}
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client,
ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
Log.d(TAG, "Incoming call");
Log.d(TAG,call.getRemoteUserId());
mPickSharedPrefs=getSharedPreferences("mPickSharedPrefs", Context.MODE_PRIVATE);
mPickSharedPrefsEditor=mPickSharedPrefs.edit();
String Check_Call_Status;
Check_Call_Status=mPickSharedPrefs.getString("call_status","");
Log.d(TAG,Check_Call_Status);
if(Check_Call_Status.equals("1")) {
Log.d(TAG,"Video Call");
Intent intent = new Intent(SinchService.this, IncomingCallScreenActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
mPickSharedPrefsEditor.clear();
}
else
if(Check_Call_Status.equals("0"))
{
Log.d(TAG,"Voice Call");
Intent intent = new Intent(SinchService.this, VoiceIncomingCallScreenActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
mPickSharedPrefsEditor.clear();
}
}
}
}

I did audio and video calling simultaneously using this below code.
In SinchService
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
if (call.getDetails().isVideoOffered()) {
Log.d(TAG, "Incoming video call");
Intent intent = new Intent(SinchService.this, VideoIncomingCallScreenActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
} else {
Log.d(TAG, "Incoming audio call");
Intent intent = new Intent(SinchService.this, IncomingCallScreenActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}
}
}

You cant do it like that, if its a video call you need to answer it video and if its a audio call you need to answer it like a Audio, the recipient cant decide. In the GA release we will have the possibility to not turn on the video but just audio when you are in a video call

you can check using
call.getDetails().isVideoOffered()
in onIncomingCall(){} function. if it returns true that mean it is a video call otherwise audio.

Related

Sinch video call not working in background

I implemented Sinch video calling in my current app. When the app is in the foreground everything is OK for the incoming call. But when I closed the app and tried to receive an incoming call, it does not show any incoming call. How to do video Sinch calling when application is closed for incoming calls? following is my FCMMessageReceiverService class.
public class FCMMessageReceiverService extends FirebaseMessagingService implements ServiceConnection {
Context context;
private SinchService.SinchServiceInterface mSinchServiceInterface;
HashMap dataHashMap;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
context = this;
if (SinchHelpers.isSinchPushPayload(remoteMessage.getData())) {
Map data = remoteMessage.getData();
dataHashMap = (data instanceof HashMap) ? (HashMap) data : new HashMap<>(data);
if (SinchHelpers.isSinchPushPayload(dataHashMap)) {
getApplicationContext().bindService(new Intent(getApplicationContext(), SinchService.class), this, Context.BIND_AUTO_CREATE);
}
} else {
Intent intent;
PendingIntent pendingIntent = null;
if (remoteMessage.getData().size() > 0) {
String identifier = remoteMessage.getData().get("identifier");
if (identifier.equals("0")) {
intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
}
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setWhen(System.currentTimeMillis());
notificationBuilder.setContentTitle(remoteMessage.getNotification().getTitle());
notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
notificationBuilder.setDefaults(Notification.DEFAULT_ALL | Notification.DEFAULT_LIGHTS | Notification.FLAG_SHOW_LIGHTS | Notification.DEFAULT_SOUND);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
public static boolean foregrounded() {
ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
ActivityManager.getMyMemoryState(appProcessInfo);
return (appProcessInfo.importance == appProcessInfo.IMPORTANCE_FOREGROUND || appProcessInfo.importance == appProcessInfo.IMPORTANCE_VISIBLE);
}
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
if (SinchService.class.getName().equals(componentName.getClassName())) {
mSinchServiceInterface = (SinchService.SinchServiceInterface) iBinder;
}
// it starts incoming call activity which does not show incoming caller name and picture
NotificationResult result = mSinchServiceInterface.relayRemotePushNotificationPayload(dataHashMap);
if (result.isValid() && result.isCall()) {
CallNotificationResult callResult = result.getCallResult();
if (callResult.isCallCanceled() || callResult.isTimedOut()) {
createNotification("Missed Call from : ", callResult.getRemoteUserId());
return;
} else {
if (callResult.isVideoOffered()) {
Intent intent = new Intent(this, IncomingCallScreenActivity.class);
intent.putExtra(SinchService.CALL_ID, callResult.getRemoteUserId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
}
} else if (result.isValid() && result.isMessage()) {
//i want to get message content here
MessageNotificationResult notificationResult = result.getMessageResult();
createNotification("Received Message from : ", notificationResult.getSenderId());
}
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
unbindService(this);
}
private void createNotification(String contentTitle, String userId) {
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext()).setSmallIcon(R.mipmap.ic_launcher).setContentTitle(contentTitle).setContentText(userId);
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
here is my since service code:
public class SinchService extends Service {
private static final String APP_KEY = "***********";
private static final String APP_SECRET = "***********";
private static final String ENVIRONMENT = "clientapi.sinch.com";
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchService.class.getSimpleName();
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient;
private String mUserId;
private PersistedSettings mSettings;
private StartFailedListener mListener;
#Override
public void onCreate() {
super.onCreate();
mSettings = new PersistedSettings(getApplicationContext());
String userName = mSettings.getUsername();
if (!userName.isEmpty()) {
Intent intent=new Intent(this,placecallActvity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
start(userName);
}
}
#Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminate();
}
super.onDestroy();
}
private void start(String userName) {
if (mSinchClient == null) {
mSettings.setUsername(userName);
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(userName).applicationKey(APP_KEY).applicationSecret(APP_SECRET).environmentHost(ENVIRONMENT).build();
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportManagedPush(true);
mSinchClient.checkManifest();
mSinchClient.setSupportActiveConnectionInBackground(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().setRespectNativeCalls(false);
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.getVideoController().setResizeBehaviour(VideoScalingType.ASPECT_FILL);
mSinchClient.start();
}
}
private void stop() {
if (mSinchClient != null) {
mSinchClient.terminate();
mSinchClient = null;
}
mSettings.setUsername("");
}
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
#Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public Call callUserVideo(String userId) {
return mSinchClient.getCallClient().callUserVideo(userId);
}
public NotificationResult relayRemotePushNotificationPayload(final Map payload) {
if (mSinchClient == null && !mSettings.getUsername().isEmpty()) {
start(mSettings.getUsername());
} else if (mSinchClient == null && mSettings.getUsername().isEmpty()) {
return null;
}
return mSinchClient.relayRemotePushNotificationPayload(payload);
}
public String getUserName() {
return mUserId;
}
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName) {
start(userName);
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
public VideoController getVideoController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getVideoController();
}
public AudioController getAudioController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getAudioController();
}
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client,
ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
Log.d(TAG, "Incoming call");
Intent intent = new Intent(SinchService.this, IncomingCallScreenActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}
}
private class PersistedSettings {
private SharedPreferences mStore;
private static final String PREF_KEY = "Sinch";
public PersistedSettings(Context context) {
mStore = context.getSharedPreferences(PREF_KEY, MODE_PRIVATE);
}
public String getUsername() {
return mStore.getString("Username", "");
}
public void setUsername(String username) {
SharedPreferences.Editor editor = mStore.edit();
editor.putString("Username", username);
editor.commit();
}
}
}
add FCM to your project
add following code
public class SinchService extends Service {
static final String APP_KEY = "************";
static final String APP_SECRET = "***********";
static final String ENVIRONMENT = "clientapi.sinch.com";
public static final int MESSAGE_PERMISSIONS_NEEDED = 1;
public static final String REQUIRED_PERMISSION = "REQUIRED_PESMISSION";
public static final String MESSENGER = "MESSENGER";
private Messenger messenger;
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchService.class.getSimpleName();
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient;
private String mUserId;
private StartFailedListener mListener;
private PersistedSettings mSettings;
private AudioPlayer audioPlayer;
private Handler handler;
#Override
public void onCreate() {
super.onCreate();
super.onCreate();
mSettings = new PersistedSettings(getApplicationContext());
String userName = mSettings.getUsername();
if (!userName.isEmpty()) {
start(userName);
}
handler = new Handler();
}
private void createClient(String username) {
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(username)
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT).build();
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportManagedPush(true);
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.setPushNotificationDisplayName("User " + username);
}
#Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminateGracefully();
}
super.onDestroy();
}
private boolean hasUsername() {
if (mSettings.getUsername().isEmpty()) {
Log.e(TAG, "Can't start a SinchClient as no username is available!");
return false;
}
return true;
}
private void createClientIfNecessary() {
if (mSinchClient != null)
return;
if (!hasUsername()) {
throw new IllegalStateException("Can't create a SinchClient as no username is available!");
}
createClient(mSettings.getUsername());
}
private void start(String userName) {
boolean permissionsGranted = true;
if (mSinchClient == null) {
mSettings.setUsername(userName);
createClient(userName);
}
createClientIfNecessary();
try {
//mandatory checks
mSinchClient.checkManifest();
if (getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
throw new MissingPermissionException(Manifest.permission.CAMERA);
}
} catch (MissingPermissionException e) {
permissionsGranted = false;
if (messenger != null) {
Message message = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString(REQUIRED_PERMISSION, e.getRequiredPermission());
message.setData(bundle);
message.what = MESSAGE_PERMISSIONS_NEEDED;
try {
messenger.send(message);
} catch (RemoteException e1) {
e1.printStackTrace();
}
}
}
if (permissionsGranted) {
Log.d(TAG, "Starting SinchClient");
try {
mSinchClient.start();
} catch (IllegalStateException e) {
Log.w(TAG, "Can't start SinchClient - " + e.getMessage());
}
}
}
private void stop() {
if (mSinchClient != null) {
mSinchClient.terminateGracefully();
mSinchClient = null;
}
}
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
#Override
public IBinder onBind(Intent intent) {
messenger = intent.getParcelableExtra(MESSENGER);
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public Call callUserVideo(String userId) {
return mSinchClient.getCallClient().callUserVideo(userId);
}
public String getUserName() {
return mSettings.getUsername();
}
public void setUsername(String username) {
mSettings.setUsername(username);
}
public void retryStartAfterPermissionGranted() {
SinchService.this.attemptAutoStart();
}
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName) {
start(userName);
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
public VideoController getVideoController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getVideoController();
}
public AudioController getAudioController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getAudioController();
}
public NotificationResult relayRemotePushNotificationPayload(final Map payload) {
if (!hasUsername()) {
Log.e(TAG, "Unable to relay the push notification!");
return null;
}
createClientIfNecessary();
return mSinchClient.relayRemotePushNotificationPayload(payload);
}
}
private void attemptAutoStart() {
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client,
ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
Log.d(TAG, "onIncomingCall: " + call.getCallId());
audioPlayer = AudioPlayer.getInstance(getApplicationContext());
call.addCallListener(new SinchCallListener());
Intent intent = new Intent(SinchService.this, IncomingCallScreenActivity.class);
intent.putExtra(EXTRA_ID, MESSAGE_ID);
intent.putExtra(CALL_ID, call.getCallId());
boolean inForeground = isAppOnForeground(getApplicationContext());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (inForeground) {
SinchService.this.startActivity(intent);
} else {
if (!audioPlayer.isPlayedRingtone()) {
audioPlayer.playRingtone();
}
((NotificationManager) Objects.requireNonNull(getSystemService(NOTIFICATION_SERVICE))).notify(MESSAGE_ID, createIncomingCallNotification(call.getRemoteUserId(), intent));
}
}
private boolean isAppOnForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = null;
if (activityManager != null) {
appProcesses = activityManager.getRunningAppProcesses();
}
if (appProcesses == null) {
return false;
}
final String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}
private Bitmap getBitmap(Context context, int resId) {
int largeIconWidth = (int) context.getResources()
.getDimension(R.dimen.height);
int largeIconHeight = (int) context.getResources()
.getDimension(R.dimen.height);
Drawable d = context.getResources().getDrawable(resId);
Bitmap b = Bitmap.createBitmap(largeIconWidth, largeIconHeight, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
d.setBounds(0, 0, largeIconWidth, largeIconHeight);
d.draw(c);
return b;
}
private PendingIntent getPendingIntent(Intent intent, String action) {
intent.setAction(action);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 111, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
#TargetApi(29)
private Notification createIncomingCallNotification(String userId, Intent fullScreenIntent) {
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 112, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder =
new NotificationCompat.Builder(getApplicationContext(), FcmListenerService.CHANNEL_ID)
.setContentTitle("Incoming call")
.setContentText(userId)
.setLargeIcon(getBitmap(getApplicationContext(), R.drawable.call_normal))
.setSmallIcon(R.drawable.call_pressed)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentIntent(pendingIntent)
.setFullScreenIntent(pendingIntent, true)
.addAction(R.drawable.button_accept, "Answer", getPendingIntent(fullScreenIntent, ACTION_ANSWER))
.addAction(R.drawable.button_decline, "Ignore", getPendingIntent(fullScreenIntent, ACTION_IGNORE))
.setOngoing(true);
return builder.build();
}
}
private class SinchCallListener implements CallListener {
#Override
public void onCallEnded(Call call) {
cancelNotification();
if (audioPlayer != null && audioPlayer.isPlayedRingtone()) {
audioPlayer.stopRingtone();
}
}
#Override
public void onCallEstablished(Call call) {
Log.d(TAG, "Call established");
if (audioPlayer != null && audioPlayer.isPlayedRingtone()) {
audioPlayer.stopRingtone();
}
}
#Override
public void onCallProgressing(Call call) {
Log.d(TAG, "Call progressing");
}
#Override
public void onShouldSendPushNotification(Call call, List<PushPair> pushPairs) {
// no need to implement for managed push
}
}
public void cancelNotification() {
NotificationManager nMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (nMgr != null) {
nMgr.cancel(MESSAGE_ID);
}
}
private static class PersistedSettings {
private SharedPreferences mStore;
private static final String PREF_KEY = "Sinch";
public PersistedSettings(Context context) {
mStore = context.getSharedPreferences(PREF_KEY, MODE_PRIVATE);
}
public String getUsername() {
return mStore.getString("Username", "");
}
public void setUsername(String username) {
SharedPreferences.Editor editor = mStore.edit();
editor.putString("Username", username);
editor.apply();
}
}
}
and crete FcmListenerService and add following code
public class FcmListenerService extends FirebaseMessagingService {
public static String CHANNEL_ID = "Sinch Push Notification Channel";
private final String PREFERENCE_FILE = "com.sinch.android.rtc.sample.push.shared_preferences";
SharedPreferences sharedPreferences;
#Override
public void onMessageReceived(RemoteMessage remoteMessage){
Map data = remoteMessage.getData();
if (SinchHelpers.isSinchPushPayload(data)) {
new ServiceConnection() {
private Map payload;
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Context context = getApplicationContext();
sharedPreferences = context.getSharedPreferences(PREFERENCE_FILE, Context.MODE_PRIVATE);
if (payload != null) {
SinchService.SinchServiceInterface sinchService = (SinchService.SinchServiceInterface) service;
if (sinchService != null) {
NotificationResult result = sinchService.relayRemotePushNotificationPayload(payload);
// handle result, e.g. show a notification or similar
// here is example for notifying user about missed/canceled call:
if (result!=null && result.isValid() && result.isCall()) {
CallNotificationResult callResult = result.getCallResult();
if (callResult != null && result.getDisplayName() != null) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(callResult.getRemoteUserId(), result.getDisplayName());
editor.apply();
}
if (callResult != null && callResult.isCallCanceled()) {
String displayName = result.getDisplayName();
if (displayName == null) {
displayName = sharedPreferences.getString(callResult.getRemoteUserId(), "n/a");
}
createMissedCallNotification(!displayName.isEmpty() ? displayName : callResult.getRemoteUserId());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
context.deleteSharedPreferences(PREFERENCE_FILE);
}
}
}
}
}
payload = null;
}
#Override
public void onServiceDisconnected(ComponentName name) {}
public void relayMessageData(Map<String, String> data) {
payload = data;
createNotificationChannel(NotificationManager.IMPORTANCE_MAX);
getApplicationContext().bindService(new Intent(getApplicationContext(), SinchService.class), this, BIND_AUTO_CREATE);
}
}.relayMessageData(data);
}
}
private void createNotificationChannel(int importance) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Amar LPG";
String description = "Incoming call notification";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
}
private void createMissedCallNotification(String userId) {
createNotificationChannel(NotificationManager.IMPORTANCE_DEFAULT);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0,
new Intent(getApplicationContext(), IncomingCallScreenActivity.class), 0);
NotificationCompat.Builder builder =
new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
.setSmallIcon(R.drawable.icon)
.setContentTitle("Missed call from ")
.setContentText(userId)
.setContentIntent(contentIntent)
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if (mNotificationManager != null) {
mNotificationManager.notify(1, builder.build());
}
}
}
in the incoming call screen add the following code
public class IncomingCallScreenActivity extends BaseActivity {
static final String TAG = IncomingCallScreenActivity.class.getSimpleName();
private String mCallId;
private AudioPlayer mAudioPlayer;
public static final String ACTION_ANSWER = "answer";
public static final String ACTION_IGNORE = "ignore";
public static final String EXTRA_ID = "id";
public static int MESSAGE_ID = 14;
private String mAction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_incoming_call_screen);
Button answer = (Button) findViewById(R.id.answerButton);
answer.setOnClickListener(mClickListener);
Button decline = (Button) findViewById(R.id.declineButton);
decline.setOnClickListener(mClickListener);
mAudioPlayer = new AudioPlayer(this);
mAudioPlayer.playRingtone();
mCallId = getIntent().getStringExtra(SinchService.CALL_ID);
mAction = "";
}
#Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
if (intent != null) {
if (intent.getStringExtra(SinchService.CALL_ID) != null) {
mCallId = getIntent().getStringExtra(SinchService.CALL_ID);
}
final int id = intent.getIntExtra(EXTRA_ID, -1);
if (id > 0) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(id);
}
mAction = intent.getAction();
}
}
#Override
protected void onServiceConnected() {
Call call = getSinchServiceInterface().getCall(mCallId);
if (call != null) {
call.addCallListener(new SinchCallListener());
TextView remoteUser = (TextView) findViewById(R.id.remoteUser);
remoteUser.setText(call.getRemoteUserId());
if (ACTION_ANSWER.equals(mAction)) {
mAction = "";
answerClicked();
} else if (ACTION_IGNORE.equals(mAction)) {
mAction = "";
declineClicked();
}
} else {
Log.e(TAG, "Started with invalid callId, aborting");
finish();
}
}
private void answerClicked() {
if (mAudioPlayer!=null && mAudioPlayer.isPlayedRingtone()){
mAudioPlayer.stopRingtone();
}
Call call = getSinchServiceInterface().getCall(mCallId);
if (call != null) {
Log.d(TAG, "Answering call");
call.answer();
Intent intent = new Intent(this, CallScreenActivity.class);
intent.putExtra(SinchService.CALL_ID, mCallId);
startActivity(intent);
} else {
finish();
}
}
private void declineClicked() {
if (mAudioPlayer!=null && mAudioPlayer.isPlayedRingtone()){
mAudioPlayer.stopRingtone();
}
Call call = getSinchServiceInterface().getCall(mCallId);
if (call != null) {
call.hangup();
}
finish();
}
private class SinchCallListener implements VideoCallListener {
#Override
public void onCallEnded(Call call) {
CallEndCause cause = call.getDetails().getEndCause();
Log.d(TAG, "Call ended, cause: " + cause.toString());
mAudioPlayer.stopRingtone();
finish();
}
#Override
public void onCallEstablished(Call call) {
Log.d(TAG, "Call established");
}
#Override
public void onCallProgressing(Call call) {
Log.d(TAG, "Call progressing");
}
#Override
public void onShouldSendPushNotification(Call call, List<PushPair> pushPairs) {
}
#Override
public void onVideoTrackAdded(Call call) {
// Display some kind of icon showing it's a video call
}
#Override
public void onVideoTrackPaused(Call call) {
}
#Override
public void onVideoTrackResumed(Call call) {
}
}
private View.OnClickListener mClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.answerButton:
answerClicked();
break;
case R.id.declineButton:
declineClicked();
break;
}
}
};
}
in the login activity add the following code.
public class MainActivity extends BaseActivity implements SinchService.StartFailedListener, PushTokenRegistrationCallback, UserRegistrationCallback {
private Button mLoginButton;
private EditText mLoginName;
private ProgressDialog mSpinner;
private String mUserId;
private long mSigningSequence = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.READ_PHONE_STATE},100);
}
mLoginName = (EditText) findViewById(R.id.loginName);
mLoginButton = (Button) findViewById(R.id.loginButton);
mLoginButton.setEnabled(false);
mLoginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loginClicked();
}
});
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onServiceConnected() {
mLoginButton.setEnabled(true);
getSinchServiceInterface().setStartListener(this);
}
#Override
protected void onPause() {
if (mSpinner != null) {
mSpinner.dismiss();
}
super.onPause();
}
#Override
public void onStartFailed(SinchError error) {
Toast.makeText(this, error.toString(), Toast.LENGTH_LONG).show();
if (mSpinner != null) {
mSpinner.dismiss();
}
}
#Override
public void onStarted() {
openPlaceCallActivity();
}
private void loginClicked() {
String userName = mLoginName.getText().toString();
if (userName.isEmpty()) {
Toast.makeText(this, "Please enter a name", Toast.LENGTH_LONG).show();
return;
}
if (!getSinchServiceInterface().isStarted()) {
getSinchServiceInterface().startClient(userName);
showSpinner();
} else {
openPlaceCallActivity();
}
mUserId = userName;
UserController uc = Sinch.getUserControllerBuilder()
.context(getApplicationContext())
.applicationKey(APP_KEY)
.userId(mUserId)
.environmentHost(ENVIRONMENT)
.build();
uc.registerUser(this, this);
}
private void openPlaceCallActivity() {
Intent mainActivity = new Intent(this, PlaceCallActivity.class);
startActivity(mainActivity);
finish();
}
private void showSpinner() {
mSpinner = new ProgressDialog(this);
mSpinner.setTitle("Logging in");
mSpinner.setMessage("Please wait...");
mSpinner.show();
}
private void dismissSpinner() {
if (mSpinner != null) {
mSpinner.dismiss();
mSpinner = null;
}
}
#Override
public void tokenRegistered() {
dismissSpinner();
startClientAndOpenPlaceCallActivity();
}
private void startClientAndOpenPlaceCallActivity() {
// start Sinch Client, it'll result onStarted() callback from where the place call activity will be started
if (!getSinchServiceInterface().isStarted()) {
getSinchServiceInterface().startClient("");
showSpinner();
}
}
#Override
public void tokenRegistrationFailed(SinchError sinchError) {
dismissSpinner();
Toast.makeText(this, "Push token registration failed - incoming calls can't be received!", Toast.LENGTH_LONG).show();
}
#Override
public void onCredentialsRequired(ClientRegistration clientRegistration) {
String toSign = mUserId + APP_KEY + mSigningSequence + APP_SECRET;
String signature;
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("SHA-1");
byte[] hash = messageDigest.digest(toSign.getBytes("UTF-8"));
signature = Base64.encodeToString(hash, Base64.DEFAULT).trim();
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e.getCause());
}
clientRegistration.register(signature, mSigningSequence++);
}
#Override
public void onUserRegistered() {
}
#Override
public void onUserRegistrationFailed(SinchError sinchError) {
dismissSpinner();
Toast.makeText(this, "Registration failed!", Toast.LENGTH_LONG).show();
}
}
on our SDK package you will find under the Samples folder multiple sample files, the one called sinch-rtc-sample-video-push does what you wnat.
You should also check our docs here:
https://developers.sinch.com/docs/voice-android-push-notifications
Best regards

Android service not working with bindService()

Actually I want to do speech to text continuously in the background so actually I am using the solution which is given in the below link but i m not getting how can i implement it.
link
I have done this so far but still my service is not running and i am not getting any output
So I think that i have done something wrong in its implementation.Please help me and correct my code in order to run service and get my output
This is my mainactivity.java
public class MainActivity extends AppCompatActivity {
private int mBindFlag ;
private Messenger mServiceMessenger ;
private Button btStartService;
private TextView tvText;
#Override
protected void onStart() {
super.onStart();
Log.d("check", "onStart: ");
bindService(new Intent(getApplicationContext(), MyService.class), mServiceConnection, mBindFlag);
}
#Override
protected void onStop() {
super.onStop();
if (mServiceMessenger != null) {
unbindService(mServiceConnection);
mServiceMessenger = null;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent service = new Intent(this, MyService.class);
this.startService(service);
mBindFlag = Context.BIND_ABOVE_CLIENT;
Log.d("check", "onCreate: "+mBindFlag);
btStartService = (Button) findViewById(R.id.btStartService);
tvText = (TextView) findViewById(R.id.tvText);
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
Manifest.permission.RECORD_AUDIO
};
if (!hasPermissions(this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
}
public static boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
private final ServiceConnection mServiceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName name, IBinder service)
{
if (DEBUG) {
Log.d("check", "onServiceConnected");} //$NON-NLS-1$
mServiceMessenger = new Messenger(service);
Message msg = new Message();
msg.what = MyService.MSG_RECOGNIZER_START_LISTENING;
try
{
mServiceMessenger.send(msg);
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
#Override
public void onServiceDisconnected(ComponentName name)
{
if (DEBUG) {Log.d("check", "onServiceDisconnected");} //$NON-NLS-1$
mServiceMessenger = null;
}
};
}
This is the code for my background service
public class MyService extends Service
{
protected AudioManager mAudioManager;
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
protected final Messenger mServerMessenger = new Messenger(new IncomingHandler(this));
protected boolean mIsListening;
protected volatile boolean mIsCountDownOn;
static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;
#Override
public void onCreate()
{
super.onCreate();
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(new SpeechRecognitionListener());
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
Log.d("check", "onCreate: "+"service");
}
protected static class IncomingHandler extends Handler
{
private WeakReference<MyService> mtarget;
IncomingHandler(MyService target)
{
mtarget = new WeakReference<MyService>(target);
}
#Override
public void handleMessage(Message msg)
{
final MyService target = mtarget.get();
switch (msg.what)
{
case MSG_RECOGNIZER_START_LISTENING:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
// turn off beep sound
target.mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
}
if (!target.mIsListening)
{
target.mSpeechRecognizer.startListening(target.mSpeechRecognizerIntent);
target.mIsListening = true;
Log.d("check", "message start listening"); //$NON-NLS-1$
}
break;
case MSG_RECOGNIZER_CANCEL:
target.mSpeechRecognizer.cancel();
target.mIsListening = false;
Log.d("check", "message canceled recognizer"); //$NON-NLS-1$
break;
}
}
}
// Count down timer for Jelly Bean work around
protected CountDownTimer mNoSpeechCountDown = new CountDownTimer(5000, 5000)
{
#Override
public void onTick(long millisUntilFinished)
{
// TODO Auto-generated method stub
}
#Override
public void onFinish()
{
mIsCountDownOn = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_CANCEL);
try
{
mServerMessenger.send(message);
message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
mServerMessenger.send(message);
}
catch (RemoteException e)
{
}
}
};
#Override
public void onDestroy()
{
super.onDestroy();
if (mIsCountDownOn)
{
mNoSpeechCountDown.cancel();
}
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
}
}
protected class SpeechRecognitionListener implements RecognitionListener
{
private static final String TAG = "check";
#Override
public void onBeginningOfSpeech()
{
// speech input will be processed, so there is no need for count down anymore
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
//Log.d(TAG, "onBeginingOfSpeech"); //$NON-NLS-1$
}
#Override
public void onBufferReceived(byte[] buffer)
{
}
#Override
public void onEndOfSpeech()
{
//Log.d(TAG, "onEndOfSpeech"); //$NON-NLS-1$
}
#Override
public void onError(int error)
{
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
mIsListening = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
try
{
mServerMessenger.send(message);
}
catch (RemoteException e)
{
}
//Log.d(TAG, "error = " + error); //$NON-NLS-1$
}
#Override
public void onEvent(int eventType, Bundle params)
{
}
#Override
public void onPartialResults(Bundle partialResults)
{
}
#Override
public void onReadyForSpeech(Bundle params)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
mIsCountDownOn = true;
mNoSpeechCountDown.start();
mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
}
Log.d("check", "onReadyForSpeech");
}
#Override
public void onResults(Bundle results)
{
Toast.makeText(getApplicationContext(),results.toString(),Toast.LENGTH_LONG).show();
}
#Override
public void onRmsChanged(float rmsdB)
{
}
}
#Override
public IBinder onBind(Intent arg0) {
return mServerMessenger.getBinder();
}
}
I got my answer I have not enabled the service from the manifest

Sinch push samples not working on android 8.0 and higher when app is in background

i am implementing sinch in my project. I started testing sinch sample if its working. I found sinch push samples are not working on android 8.0 and higher and are working on lower versions. I tested my FCM implementation and is working fine but sinch push is not working when the app is not running.
Please help as i have tested all the solutions available on this site and none of the solutions worked.
public class SinchService extends Service {
private static final String APP_KEY = "my app key here";
private static final String APP_SECRET = "my app secret here";
private static final String ENVIRONMENT = "sandbox.sinch.com";
public static final int MESSAGE_PERMISSIONS_NEEDED = 1;
public static final String REQUIRED_PERMISSION = "REQUIRED_PESMISSION";
public static final String MESSENGER = "MESSENGER";
private Messenger messenger;
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchService.class.getSimpleName();
private PersistedSettings mSettings;
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient;
private StartFailedListener mListener;
#Override
public void onCreate() {
super.onCreate();
mSettings = new PersistedSettings(getApplicationContext());
attemptAutoStart();
}
private void attemptAutoStart() {
String userName = mSettings.getUsername();
if (!userName.isEmpty() && messenger != null) {
start(userName);
}
}
private void createClient(String username) {
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(username)
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT).build();
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportManagedPush(true);
mSinchClient.setSupportActiveConnectionInBackground(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
}
#Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminate();
}
super.onDestroy();
}
private void start(String username) {
boolean permissionsGranted = true;
if (mSinchClient == null) {
mSettings.setUsername(username);
createClient(username);
}
try {
//mandatory checks
mSinchClient.checkManifest();
} catch (MissingPermissionException e) {
permissionsGranted = false;
if (messenger != null) {
Message message = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString(REQUIRED_PERMISSION, e.getRequiredPermission());
message.setData(bundle);
message.what = MESSAGE_PERMISSIONS_NEEDED;
try {
messenger.send(message);
} catch (RemoteException e1) {
e1.printStackTrace();
}
}
}
if (permissionsGranted) {
Log.d(TAG, "Starting SinchClient");
mSinchClient.start();
}
}
private void stop() {
if (mSinchClient != null) {
mSinchClient.terminate();
mSinchClient = null;
}
}
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
#Override
public IBinder onBind(Intent intent) {
messenger = intent.getParcelableExtra(MESSENGER);
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public Call callUser(String userId) {
return mSinchClient.getCallClient().callUser(userId);
}
public String getUserName() {
return mSinchClient != null ? mSinchClient.getLocalUserId() : "";
}
public void retryStartAfterPermissionGranted() { SinchService.this.attemptAutoStart(); }
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName) {
start(userName);
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
public AudioController getAudioController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getAudioController();
}
public NotificationResult relayRemotePushNotificationPayload(final Map payload) {
if (mSinchClient == null && !mSettings.getUsername().isEmpty()) {
createClient(mSettings.getUsername());
} else if (mSinchClient == null && mSettings.getUsername().isEmpty()) {
Log.e(TAG, "Can't start a SinchClient as no username is available, unable to relay push.");
return null;
}
return mSinchClient.relayRemotePushNotificationPayload(payload);
}
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client,
ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
Log.d(TAG, "onIncomingCall: " + call.getCallId());
Intent intent = new Intent(SinchService.this, IncomingCallScreenActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}
}
private class PersistedSettings {
private SharedPreferences mStore;
private static final String PREF_KEY = "Sinch";
public PersistedSettings(Context context) {
mStore = context.getSharedPreferences(PREF_KEY, MODE_PRIVATE);
}
public String getUsername() {
return mStore.getString("Username", "");
}
public void setUsername(String username) {
SharedPreferences.Editor editor = mStore.edit();
editor.putString("Username", username);
editor.commit();
}
}
}
public class FcmListenerService extends FirebaseMessagingService {
private final String PREFERENCE_FILE = "com.sinch.android.rtc.sample.push.shared_preferences";
SharedPreferences sharedPreferences;
#Override
public void onMessageReceived(RemoteMessage remoteMessage){
Map data = remoteMessage.getData();
if (SinchHelpers.isSinchPushPayload(data)) {
new ServiceConnection() {
private Map payload;
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Context context = getApplicationContext();
sharedPreferences = context.getSharedPreferences(PREFERENCE_FILE, Context.MODE_PRIVATE);
if (payload != null) {
SinchService.SinchServiceInterface sinchService = (SinchService.SinchServiceInterface) service;
if (sinchService != null) {
NotificationResult result = sinchService.relayRemotePushNotificationPayload(payload);
// handle result, e.g. show a notification or similar
// here is example for notifying user about missed/canceled call:
if (result.isValid() && result.isCall()) {
CallNotificationResult callResult = result.getCallResult();
if (callResult != null && result.getDisplayName() != null) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(callResult.getRemoteUserId(), result.getDisplayName());
editor.commit();
}
if (callResult.isCallCanceled()) {
String displayName = result.getDisplayName();
if (displayName == null) {
displayName = sharedPreferences.getString(callResult.getRemoteUserId(),"n/a");
}
createNotification(displayName != null && !displayName.isEmpty() ? displayName : callResult.getRemoteUserId());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
context.deleteSharedPreferences(PREFERENCE_FILE);
}
}
}
}
}
payload = null;
}
#Override
public void onServiceDisconnected(ComponentName name) {}
public void relayMessageData(Map<String, String> data) {
payload = data;
getApplicationContext().bindService(new Intent(getApplicationContext(), SinchService.class), this, BIND_AUTO_CREATE);
}
}.relayMessageData(data);
}
}
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Sinch";
String description = "Incoming Sinch Push Notifications.";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(getResources().getString(R.string.default_notification_channel_id), name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
private void createNotification(String userId) {
createNotificationChannel();
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0,
new Intent(getApplicationContext(), LoginActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(getApplicationContext(), getResources().getString(R.string.default_notification_channel_id))
.setSmallIcon(R.drawable.icon)
.setContentTitle("Missed call from:")
.setContentText(userId);
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}

Android speech recognizer works fine on 5.0.1 but doesn't work on 5.1

I am working on create a speech recognition service on android and followed previous works from others here. The old version was based on android 5.0.1 and it worked perfectly fine.
However, when I try to move it to android 5.1, it always stops in the onError function in the recognition listener with a error code 7, which means ERROR_NO_MATCH.
I don't know why this happened. is there any difference on using speech recognizer in Android 5.0.1 and 5.1?
If someone can help me, I will be very appreciated. Thanks.
Here is my code:
public class speechrecognitionService extends Service
{
protected static AudioManager mAudioManager;
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
protected final Messenger mServerMessenger = new Messenger(new IncomingHandler(this));
protected boolean mIsListening;
protected volatile boolean mIsCountDownOn;
private static boolean mIsStreamSolo;
private static String voiceCommand;
static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;
public static final String TAG = null;
public static final String FEEDBACK = "com.kut.kutcamera";
public static final String COMMAND = "command";
public static final String standardVoiceCommand = "take a photo";
public static final String voiceCommandAlt1 = "take photo";
public static final String voiceCommandAlt2 = "photo";
public static final String voiceCommandAlt3 = "take";
#Override
public void onCreate()
{
super.onCreate();
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(new SpeechRecognitionListener());
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
Toast.makeText(this, "Service is created", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Toast.makeText(this, "Say your command loud and clear please.", Toast.LENGTH_LONG).show();
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
//startListenting(true);
//int result = super.onStartCommand(intent,flags,startId);
return super.onStartCommand(intent, flags, startId);
}
protected static class IncomingHandler extends Handler
{
private WeakReference<speechrecognitionService> mtarget;
IncomingHandler(speechrecognitionService target)
{
mtarget = new WeakReference<speechrecognitionService>(target);
}
#Override
public void handleMessage(Message msg)
{
final speechrecognitionService target = mtarget.get();
switch (msg.what)
{
case MSG_RECOGNIZER_START_LISTENING:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
// turn off beep sound
if (!mIsStreamSolo)
{
mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);
mIsStreamSolo = true;
}
}
if (!target.mIsListening)
{
target.mSpeechRecognizer.startListening(target.mSpeechRecognizerIntent);
target.mIsListening = true;
//Log.d(TAG, "message start listening"); //$NON-NLS-1$
}
break;
case MSG_RECOGNIZER_CANCEL:
if (mIsStreamSolo)
{
mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, false);
mIsStreamSolo = false;
}
target.mSpeechRecognizer.cancel();
target.mIsListening = false;
//Log.d(TAG, "message canceled recognizer"); //$NON-NLS-1$
break;
}
}
}
// Count down timer for Jelly Bean work around
protected CountDownTimer mNoSpeechCountDown = new CountDownTimer(30000, 1000)
{
#Override
public void onTick(long millisUntilFinished)
{
// TODO Auto-generated method stub
}
#Override
public void onFinish()
{
mIsCountDownOn = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_CANCEL);
try
{
mServerMessenger.send(message);
message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
mServerMessenger.send(message);
}
catch (RemoteException e)
{
}
}
};
#Override
public void onDestroy()
{
super.onDestroy();
if (mIsCountDownOn)
{
mNoSpeechCountDown.cancel();
}
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
//Toast.makeText(speechrecognitionService.this, "the recognizer is destroyed", Toast.LENGTH_LONG).show();
}
}
protected class SpeechRecognitionListener implements RecognitionListener
{
#Override
public void onBeginningOfSpeech()
{
// speech input will be processed, so there is no need for count down anymore
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
//Log.d(TAG, "onBeginingOfSpeech"); //$NON-NLS-1$
}
#Override
public void onBufferReceived(byte[] buffer)
{
}
#Override
public void onEndOfSpeech()
{
//Log.d(TAG, "onEndOfSpeech"); //$NON-NLS-1$
}
#Override
public void onError(int error)
{
Log.d(TAG, "onError: " + error);
if ((error == SpeechRecognizer.ERROR_NO_MATCH)
|| (error == SpeechRecognizer.ERROR_SPEECH_TIMEOUT)){
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
mIsListening = false;
Log.d("TESTING: SPEECH SERVICE: CALL START", "onError()");
startListening(true);
}
}
#Override
public void onEvent(int eventType, Bundle params)
{
}
#Override
public void onPartialResults(Bundle partialResults)
{
}
#Override
public void onReadyForSpeech(Bundle params)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
mIsCountDownOn = true;
mNoSpeechCountDown.start();
}
//Toast.makeText(speechrecognitionService.this, "Please say your command loudly and clearly", Toast.LENGTH_LONG).show();
}
#Override
public void onResults(Bundle results)
{
//Log.d(TAG, "onResults"); //$NON-NLS-1$
ArrayList strlist = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
voiceCommand = (String) strlist.get(0);
Toast.makeText(speechrecognitionService.this, voiceCommand, Toast.LENGTH_LONG).show();
if (voiceCommand.equals(standardVoiceCommand) || voiceCommand.equals(voiceCommandAlt1)
|| voiceCommand.equals(voiceCommandAlt2)||voiceCommand.equals(voiceCommandAlt3))
publishResults();
else {
Toast.makeText(speechrecognitionService.this, "Say the command again please.", Toast.LENGTH_LONG).show();
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
}
}
#Override
public void onRmsChanged(float rmsdB)
{
}
private void startListening(boolean bMuteSound){
Log.d("TESTING: SPEECH SERVICE: startListening()", mIsListening? "true":"false");
if (bMuteSound==true && Build.VERSION.SDK_INT >= 16)//Build.VERSION_CODES.JELLY_BEAN)
{
// turn off beep sound
mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
}
if (!mIsListening)
{
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
//recognizeSpeechDirectly ();
mIsListening = true;
}
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private void publishResults() {
Intent intent = new Intent(FEEDBACK);
intent.putExtra(COMMAND, voiceCommand);
//intent.putExtra(RESULT, result);
sendBroadcast(intent);
}
}

Is it possible to pass Chromcast connection info between Activities?

I am developing an app that connects to a Chromecast, everything works fine when I do it from one activity, the problem is, that I want that activity to be fullscreen with no action bar, and no soft buttons. I am achiving that, hiding them when the users connects to the Chromecast, but it would be better if the users connect from the first activity (with action bar) and then goes to the second activity and the magic occurs there. But I can't pass the session between the activities. I have follow this tutorial to make the communication with the chromecast but tried to change a little to make the 2 acitivites communication.
Of course I have tested it and it returns a NullPointerException.
ConnectionFailedListener.java
public class ConnectionFailedListener implements GoogleApiClient.OnConnectionFailedListener {
private String TAG;
private MyConnectionCallbacks myConnectionCB;
public ConnectionFailedListener(String _TAG)
{
this.TAG=_TAG;
}
private void setMyConnectionCallBack(MyConnectionCallbacks _ConnectionCallbacks)
{
this.myConnectionCB = _ConnectionCallbacks;
}
#Override
public void onConnectionFailed(ConnectionResult result)
{
Log.e(TAG, "onConnectionFailed ");
myConnectionCB.teardown();
}
}
Channel.java
public class EventChannel implements Cast.MessageReceivedCallback
{
private Context myContext;
private String TAG;
/**
* #return custom namespace
*/
public EventChannel(Context _context, String _TAG)
{
this.myContext = _context;
this.TAG = _TAG;
}
public String getNamespace()
{
return myContext.getString(R.string.namespace);
}
/*
* Receive message from the receiver app
*/
#Override
public void onMessageReceived(CastDevice castDevice, String namespace,String message)
{
Log.d(TAG, "onMessageReceived: " + message);
}
}
ConnectionCallbacks.java
public class MyConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks
{
private String TAG;
private Context myContext;
public CastDevice mSelectedDevice;
private GoogleApiClient mApiClient;
private boolean mWaitingForReconnect;
private EventChannel mEventChannel;
private String mSessionId;
private boolean mApplicationStarted;
private EventChannel myChannel;
public MyConnectionCallbacks(Context _context, String _TAG)
{
this.myContext=_context;
this.TAG = _TAG;
}
public void setApiClient(GoogleApiClient _newApiClient)
{
this.mApiClient = _newApiClient;
}
#Override
public void onConnected(Bundle connectionHint)
{
Log.d(TAG, "onConnected");
if (mApiClient == null)
{
// We got disconnected while this runnable was pending execution.
return;
}
try
{
if (mWaitingForReconnect)
{
mWaitingForReconnect = false;
// Check if the receiver app is still running
if ((connectionHint != null) && connectionHint.getBoolean(Cast.EXTRA_APP_NO_LONGER_RUNNING))
{
Log.d(TAG, "App is no longer running");
teardown();
}
else
{// Re-create the custom message channel
try
{
Cast.CastApi.setMessageReceivedCallbacks(mApiClient,mEventChannel.getNamespace(),mEventChannel);
}
catch (IOException e)
{
Log.e(TAG, "Exception while creating channel", e);
}
}
}
else
{// Launch the receiver app because is connected
Cast.CastApi.launchApplication(mApiClient,myContext.getString(R.string.app_id), false).setResultCallback(
new ResultCallback<Cast.ApplicationConnectionResult>()
{
#Override
public void onResult(Cast.ApplicationConnectionResult result) {
Status status = result.getStatus();
Log.d(TAG,"ApplicationConnectionResultCallback.onResult: statusCode"+ status.getStatusCode());
if (status.isSuccess())
{
ApplicationMetadata applicationMetadata = result.getApplicationMetadata();
mSessionId = result.getSessionId();
String applicationStatus = result.getApplicationStatus();
boolean wasLaunched = result.getWasLaunched();
Log.d(TAG,"application name: "+ applicationMetadata.getName()
+ ", status: "+ applicationStatus
+ ", sessionId: "+ mSessionId
+ ", wasLaunched: "+ wasLaunched);
mApplicationStarted = true;
// Create the custom message channel
mEventChannel = new EventChannel(myContext,TAG);
try
{
Cast.CastApi.setMessageReceivedCallbacks(mApiClient,mEventChannel.getNamespace(),mEventChannel);
}
catch (IOException e)
{
Log.e(TAG,"Exception while creating channel",e);
}
// set the initial instructions on the receiver
sendMessage("starting from mobile");
}
else
{
Log.e(TAG,"application could not launch");
teardown();
}
}
});
}
}
catch (Exception e)
{
Log.e(TAG, "Failed to launch application", e);
}
}
#Override
public void onConnectionSuspended(int cause)
{
Log.d(TAG, "onConnectionSuspended");
mWaitingForReconnect = true;
}
public void sendMessage(String message)
{
if (mApiClient != null && mEventChannel != null)
{
try
{
Cast.CastApi.sendMessage(mApiClient,mEventChannel.getNamespace(), message)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status result)
{
if (!result.isSuccess())
{
Log.e(TAG, "Sending message failed");
}
}
});
}
catch (Exception e)
{
Log.e(TAG, "Exception while sending message", e);
}
}
else
{
Toast.makeText(myContext, message, Toast.LENGTH_SHORT).show();
}
}
public void teardown()
{
Log.d(TAG, "teardown");
if (mApiClient != null)
{
if (mApplicationStarted)
{
if (mApiClient.isConnected() || mApiClient.isConnecting())
{
try
{
Cast.CastApi.stopApplication(mApiClient, mSessionId);
if (myChannel != null)
{
Cast.CastApi.removeMessageReceivedCallbacks(mApiClient,myChannel.getNamespace());
myChannel = null;
}
}
catch (IOException e)
{
Log.e(TAG, "Exception while removing channel", e);
}
mApiClient.disconnect();
}
mApplicationStarted = false;
}
mApiClient = null;
}
mSelectedDevice = null;
mWaitingForReconnect = false;
mSessionId = null;
}
}
MediaRouterCallback.java
public class MyMediaRouterCallback extends MediaRouter.Callback {
private GoogleApiClient mApiClient;
private Cast.Listener mCastListener;
private Context myContext;
private ConnectionFailedListener mConnectionFailedListener;
public MyConnectionCallbacks mConnectionCallbacks;
public String TAG;
//private String mSessionId;
public MyMediaRouterCallback(Context _context, String _TAG)
{
this.myContext = _context;
this.TAG = _TAG;
mConnectionCallbacks = new MyConnectionCallbacks(myContext,TAG);
}
#Override
public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) {
Log.d(TAG, "onRouteSelected");
mConnectionCallbacks.mSelectedDevice = CastDevice.getFromBundle(info.getExtras());
launchReceiver();
}
#Override
public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) {
Log.d(TAG, "onRouteUnselected: info=" + info);
mConnectionCallbacks.teardown();
mConnectionCallbacks.mSelectedDevice = null;
}
private void launchReceiver()
{
try
{
mCastListener = new Cast.Listener() {
#Override
public void onApplicationDisconnected(int errorCode) {
Log.d(TAG, "application has stopped");
mConnectionCallbacks.teardown();
}
};
//Constructors for Google Play Services Connection
//mConnectionCallbacks = new MyConnectionCallbacks(myContext,TAG);
mConnectionFailedListener = new ConnectionFailedListener(TAG);
Cast.CastOptions.Builder apiOptionsBuilder =
Cast.CastOptions.builder(mConnectionCallbacks.mSelectedDevice, mCastListener);
// ApiClient to Connect to Google Play services
mApiClient = new GoogleApiClient.Builder(myContext)
.addApi(Cast.API, apiOptionsBuilder.build())
.addConnectionCallbacks(mConnectionCallbacks)
.addOnConnectionFailedListener(mConnectionFailedListener)
.build();
mConnectionCallbacks.setApiClient(mApiClient);//setting ApiClient to achieve sendMessage
//Connect to Google Play services
mApiClient.connect();
}
catch (Exception e)
{
Log.e(TAG, "Failed launchReceiver", e);
}
}
}
FirstActivity (where the chromecast is connected)
public class ConnectCastActivity extends ActionBarActivity {
private static final String TAG = ConnectCastActivity.class.getSimpleName();
private MediaRouter mMediaRouter;
private MediaRouteSelector mMediaRouteSelector;
private MediaRouter.Callback mMediaRouterCallback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));
setContentView(R.layout.activity_connect_cast);
// Configure Cast device discovery
mMediaRouter = MediaRouter.getInstance(getApplicationContext());
mMediaRouteSelector = new MediaRouteSelector.Builder().addControlCategory(CastMediaControlIntent.categoryForCast(getResources().getString(R.string.app_id))).build();
mMediaRouterCallback = new MyMediaRouterCallback(getApplicationContext(),TAG);
TextView myTextView = (TextView)findViewById(R.id.txt_helloworld);
myTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(),MainActivity.class);
startActivity(i);
}
});
}
#Override
protected void onStart() {
super.onStart();
// Start media router discovery
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
}
#Override
protected void onStop() {
// End media router discovery
Log.w(TAG, "onStop");
//mMediaRouter.removeCallback(mMediaRouterCallback);
super.onStop();
}
#Override
public void onDestroy() {
Log.w(TAG, "onDestroy");
// mMediaRouterCallback.onRouteUnselected(mMediaRouter,null);
super.onDestroy();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_connect_cast, menu);
MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem);
// Set the MediaRouteActionProvider selector for device discovery.
mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector);
return true;
}
}
SecondActivity (the one that will send the message)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MediaRouter mMediaRouter = MediaRouter.getInstance(getApplicationContext());
mConnectionCallbacks = new MyConnectionCallbacks(getApplicationContext(),TAG);
setContentView(R.layout.activity_main);
//What should I put here?
}
If you have an application with multiple activities, you are better off if you do not tie the cast connectivity and related states to any of those activities, instead you can have a singleton, or use your Application instance or use a background service or ... to maintain the connection and access the required pieces that are maintained in that global place. If it fits your requirement, you might want to use the CastCompanionLibrary that already does most of the routine stuff for you; if not, you can take a look at it and the see how the CastVideos sample app uses that and try to do something similar for your application.

Categories

Resources