MQTT Android Client Call CalBackListener Problems - android

I code a service to subscribe message from mqtt server. Service auto reconnect when internet connection on/off.
This code:
public class NotificationService extends Service{
private Handler connectBrokerHandler;
private ConnectBrokerTimerTask connectBrokerTimerTask;
private Timer connectBrokerTimer;
private MqttAndroidClient androidClient;
private MqttConnectOptions connectOptions;
private MemoryPersistence memPer;
private IMqttToken connectToken;
private CustomActionListener customActionListener;
private Context context;
private String CLIENT_STATUS = CLIENT_INIT;
private static final String TAG = "NotificationService";
private static final String USER_NAME = "chuxuanhy";
private static final String PASS_WORD = "0936160721";
private static final String URL_BROKER = "tcp://ntm.diyoracle.com:1883";
private static final String TOPIC_STAFF = "PROSHIP_STAFF";
private static final String DEVICE_ID = "FUCKYOU_002";
private static final int CONNECTION_TIMEOUT = 60;
private static final int KEEP_ALIVE_INTERVAL = 60*60;
private static final int TRY_CONNECTION_DELAY = 30; //seconds
private static final String CLIENT_INIT = "CLIENT_INIT";
private static final String CLIENT_CONNECTION_BROKER_START = "CLIENT_CONNECTION_BROKER_START";
private static final String CLIENT_CONNECTION_BROKER_FAIL = "CLIENT_CONNECTION_BROKER_FAIL";
private static final String CLIENT_CONNECTION_BROKER_SUCCESS = "CLIENT_CONNECTION_BROKER_SUCCESS";
private static final String CLIENT_LOST_CONNECTION = "CLIENT_LOST_CONNECTION";
private static final String CLIENT_SUBSCRIBE_TOPIC_START = "CLIENT_SUBSCRIBE_TOPIC_START";
private static final String CLIENT_SUBSCRIBE_TOPIC_FAIL = "CLIENT_SUBSCRIBE_TOPIC_FAIL";
private static final String CLIENT_SUBSCRIBE_TOPIC_SUCCESS = "CLIENT_SUBSCRIBE_TOPIC_SUCCESS";
private IntentFilter FilterNetwork;
private BroadcastReceiver ReceiverCheckInternet = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(isOnline()){
if(CLIENT_STATUS == CLIENT_LOST_CONNECTION || CLIENT_STATUS == CLIENT_CONNECTION_BROKER_FAIL || CLIENT_STATUS == CLIENT_SUBSCRIBE_TOPIC_FAIL) {
ConnectBroker();
}
}
}
};
private class ConnectBrokerTimerTask extends TimerTask{
#Override
public void run() {
connectBrokerHandler.post(ConnectBrokerRunable);
}
}
private Runnable ConnectBrokerRunable = new Runnable() {
#Override
public void run() {
ConnectBroker();
}
};
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
public void RestartNotificationService(){
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePendingIntent);
}
public void createNotification(String title, String body) {
Intent intent = new Intent(this, NotificationReceiver.class);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext());
Notification notification = mBuilder.setSmallIcon(R.drawable.train).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle().bigText(body))
.setContentIntent(pIntent)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setVibrate(new long[]{1000, 1000})
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.mipmap.ic_launcher))
.setContentText(body).build();
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(m, notification);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
try{
RestartNotificationService();
}catch (Exception e){
e.printStackTrace();
}
super.onTaskRemoved(rootIntent);
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(ReceiverCheckInternet);
Log.e(TAG, "onDestroy");
try{
if(androidClient.isConnected()){
this.androidClient.unsubscribe(TOPIC_STAFF);
this.androidClient.disconnect();
this.androidClient = null;
}
}catch (Exception e){
e.printStackTrace();
}
}
private void ConnectBroker(){
try {
CLIENT_STATUS = CLIENT_CONNECTION_BROKER_START;
connectToken = this.androidClient.connect(connectOptions,null,customActionListener);
}catch (Exception e){
//e.printStackTrace();
Log.e(TAG, "ConnectBroker Fail Exception");
}
}
private void SubscribeBrokerTopic(String topic){
try {
CLIENT_STATUS = CLIENT_SUBSCRIBE_TOPIC_START;
androidClient.subscribe(topic, 0, null, customActionListener);
} catch (Exception e) {
//e.printStackTrace();
Log.e(TAG, "SubscribeBrokerTopic Fail Exception");
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("NOTIFI","CALL ME onStartCommand");
this.connectBrokerHandler = new Handler();
this.connectBrokerTimer = new Timer();
this.connectBrokerTimerTask = new ConnectBrokerTimerTask();
this.customActionListener = new CustomActionListener();
this.memPer = new MemoryPersistence();
this.connectOptions = new MqttConnectOptions();
this.connectOptions.setCleanSession(true);
this.connectOptions.setUserName(USER_NAME);
this.connectOptions.setPassword(PASS_WORD.toCharArray());
this.connectOptions.setConnectionTimeout(CONNECTION_TIMEOUT);
this.connectOptions.setKeepAliveInterval(KEEP_ALIVE_INTERVAL);
this.androidClient = new MqttAndroidClient(getApplicationContext(),URL_BROKER,DEVICE_ID,memPer);
this.androidClient.setCallback(new CustomCallBack());
this.androidClient.setTraceCallback(new CustomTraceHandler());
//this.androidClient.
this.FilterNetwork = new IntentFilter();
this.FilterNetwork.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(ReceiverCheckInternet, FilterNetwork);
//this.androidClient.registerResources(getApplicationContext());
ConnectBroker();
return START_NOT_STICKY;
}
private class CustomTraceHandler implements MqttTraceHandler{
#Override
public void traceDebug(String source, String message) {
Log.e(TAG,"CustomConnectHandler - traceDebug\n"+source+" - "+message);
}
#Override
public void traceError(String source, String message) {
Log.e(TAG, "CustomConnectHandler - traceError\n" + source + " - " + message);
}
#Override
public void traceException(String source, String message, Exception e) {
Log.e(TAG, "CustomConnectHandler - traceException\n" + source + " - " + message);
e.printStackTrace();
}
}
private class CustomCallBack implements MqttCallback{
#Override
public void connectionLost(Throwable throwable) {
CLIENT_STATUS = CLIENT_LOST_CONNECTION;
if(!isOnline()){
Log.e(TAG, "ConnectCallBack connectionLost - No Internet Connection ");
}else {
//throwable.printStackTrace();
}
}
#Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
Log.e(TAG,"ConnectCallBack messageArrived\n"+s+" - "+mqttMessage.toString());
createNotification(s, mqttMessage.toString());
}
#Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
Log.e(TAG, "ConnectCallBack deliveryComplete");
}
}
private class CustomActionListener implements IMqttActionListener {
#Override
public void onSuccess(IMqttToken iMqttToken) {
if (CLIENT_STATUS == CLIENT_CONNECTION_BROKER_START) {
CLIENT_STATUS = CLIENT_CONNECTION_BROKER_SUCCESS;
if (iMqttToken.getTopics() == null) {
SubscribeBrokerTopic(TOPIC_STAFF);
}
Log.e(TAG, "CustomActionListener - CONNECT BROKER onSuccess");
} else if (CLIENT_STATUS == CLIENT_SUBSCRIBE_TOPIC_START) {
CLIENT_STATUS = CLIENT_SUBSCRIBE_TOPIC_SUCCESS;
Log.e(TAG, "CustomActionListener - SUBSCRIBE TOPIC onSuccess");
}
}
#Override
public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
if (CLIENT_STATUS == CLIENT_CONNECTION_BROKER_START) {
CLIENT_STATUS = CLIENT_CONNECTION_BROKER_FAIL;
Log.e(TAG, "CustomActionListener - CONNECT BROKER onFailure ");
} else if (CLIENT_STATUS == CLIENT_SUBSCRIBE_TOPIC_START) {
CLIENT_STATUS = CLIENT_SUBSCRIBE_TOPIC_FAIL;
Log.e(TAG, "CustomActionListener - SUBSCRIBE TOPIC onFailure ");
}
if (isOnline()) {
throwable.printStackTrace();
//connectBrokerTimer.scheduleAtFixedRate(connectBrokerTimerTask, 5000, TRY_CONNECTION_DELAY * 1000);
}else {
Log.e(TAG, "CustomActionListener onFailure - No Internet Connection ");
}
}
}
}
But i have a problem, every time internet connection lost, i reconnect server, callback call again.
Example:
Log.e(TAG, "ConnectCallBack connectionLost - No Internet Connection ");
call twice, 3 time, 4 time every disconnect internet
Sorry my english not good, thank for help.

Don't handle the re-connection manually, newer version of paho has option to auto reconnect in MqttConnectOptions class.
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1'
compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'

Related

i want to call an api function continously 24*7 with the timer of 1 minute in background , it works fine in intial time ,after 15 minutes it stops

please help i am new to Android , I want to call this API background continuously 24*7(all time),
but this code runs few minutes and then it stops working, is there any other solution to work this code continuously(non-stop) background with timer?. here I'm using foreground service but no use.
SmsForegroundService.class
public class SmsForegroundService extends Service{
Context mContext;
private BroadcastReceiver receiver;
private static final String SENT = "SMS_SENT";
private static final String TAG = "TEST123";
private APIInterface apiInterface;
public static Handler handler;
public static Runnable myRunnable;
private SMSReceiver smsReceiver;
private AppPreferences appPreferences;
private IntentFilter mIntentFilter;
String responseTimer = "1";
private int j = 1 ;
private Runnable runnable;
private static final String TAGs = SmsForegroundService.class.getSimpleName();
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: ");
handler = new Handler();
appPreferences = new AppPreferences(this);
apiInterface = APIClient.getClient().create(APIInterface.class);
handler = new Handler();
runnable = new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Service is still running",
Toast.LENGTH_LONG).show();
callKeepAliveNotifyApi();
}
};
handler.postDelayed(runnable, 0);
}
#Override
public void onDestroy() {
Log.d(TAG, "onDestroy: service destroyed");
super.onDestroy();
handler.removeCallbacks(myRunnable);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG ,"service running");
final String CHANNEL_ID = "foreground Service ID";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
CHANNEL_ID,
NotificationManager.IMPORTANCE_HIGH
);
getSystemService(NotificationManager.class).createNotificationChannel(channel);
Notification.Builder notification = new Notification.Builder(this,CHANNEL_ID)
.setContentText("Service is running")
.setContentTitle("Service is enabled")
.setSmallIcon(R.drawable.alert);
startForeground(1001, notification.build());
}
return START_STICKY;
}
private void callKeepAliveNotifyApi() {
try{
String token = appPreferences.getRegisterToken();
System.out.println("token "+token);
Call<KeepAliveResponse> response = apiInterface.KeepAliveNotification(token);
response.enqueue(new Callback<KeepAliveResponse>() {
#RequiresApi(api = Build.VERSION_CODES.P)
#Override
public void onResponse(#NonNull Call<KeepAliveResponse> call, #NonNull Response<KeepAliveResponse> response) {
if (response.code() == 200) {
KeepAliveResponse resObj = response.body();
assert resObj != null;
if(resObj.getStatus().equals("success"))
{
Toast.makeText(getApplicationContext(), "keep-alive " + j, Toast.LENGTH_SHORT).show();
System.out.println( "delay : " + j);
j++;
appPreferences.setTimer(resObj.getTimeInterval());
int correctTimer = Integer.parseInt(appPreferences.getTimer());
correctTimer = correctTimer * 60000;
handler.postDelayed(runnable, correctTimer);
System.out.println("timer :"+appPreferences.getTimer());
}else {
Toast.makeText(getApplicationContext(), resObj.getStatusMessage(), Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(), "response error", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(#NonNull Call<KeepAliveResponse> call, #NonNull Throwable t)
{
Log.d("Response", "fail");
call.clone().enqueue(this);
}
});
System.out.println( "sdsd" +appPreferences.getTimer());
}
catch(Exception e)
{
e.printStackTrace();
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: ");
return null;
}
}
in Mainactivity.class here I added code to call that foreground service class.
public class MainActivity extends AppCompatActivity {
private LinearLayout notification,settings,exitApp;
private ImageView backButton,logoutButton;
private TextView ScreenTitle;
private AppPreferences appPreferences;
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
appPreferences = new AppPreferences(this);
Intent serviceIntent = new Intent(this, SmsForegroundService.class);
ContextCompat.startForegroundService(this,serviceIntent);
}
inside Manifest file added this foreground class.
<service
android:name="com.xyz.app.services.SmsForegroundService"
android:enabled="true"
android:exported="false" />

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

I am creating a music player in Android, but unfortunately Mediaplayer stops unexpectedly. Why?

I am creating a music player in Android, but unfortunately Mediaplayer stops unexpectedly. If app being opened, there is no problem. But when app go to background, it stops without showing any logs.
Does anyone know what is the reason?
Thanks in advance
public class MusicService extends Service implements MediaPlayer.OnPreparedListener,
MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
private boolean checkError = true;
public MediaPlayer mPlayer;
private Uri mSongUri;
private Bitmap mSongBitmap;
public static PlayingFragment playingFragment;
private int songDuration;
private ArrayList<Song> mListSongs;
private int SONG_POS = 0;
private final IBinder musicBind = new PlayerBinder();
private final String ACTION_STOP = "com.emptylist.tabplayer.STOP";
private final String ACTION_NEXT = "com.emptylist.tabplayer.NEXT";
private final String ACTION_PREVIOUS = "com.emptylist.tabplayer.PREVIOUS";
private final String ACTION_PAUSE = "com.emptylist.tabplayer.PAUSE";
public static final int STATE_PAUSED = 1;
public static final int STATE_PLAYING = 2;
public int mState = 0;
private static final int REQUEST_CODE_PAUSE = 101;
private static final int REQUEST_CODE_PREVIOUS = 102;
private static final int REQUEST_CODE_NEXT = 103;
private static final int REQUEST_CODE_STOP = 104;
public static int NOTIFICATION_ID = 11;
private Notification.Builder notificationBuilder;
private Notification mNotification;
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
public class PlayerBinder extends Binder {
public MusicService getService() {
Log.d("test", "getService()");
return MusicService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
Log.d("test", "onBind Called ");
return musicBind;
}
#Override
public void onCreate() {
super.onCreate();
mPlayer = new MediaPlayer();
initPlayer();
mPlayer.setOnPreparedListener(this);
mPlayer.setOnCompletionListener(this);
mPlayer.setOnErrorListener(this);
notificationBuilder = new Notification.Builder(getApplicationContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
String action = intent.getAction();
if (!TextUtils.isEmpty(action)) {
if (action.equals(ACTION_PAUSE)) {
playPauseSong();
} else if (action.equals(ACTION_NEXT)) {
nextSong();
} else if (action.equals(ACTION_PREVIOUS)) {
previousSong();
} else if (action.equals(ACTION_STOP)) {
stopSong();
stopSelf();
}
}
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public boolean onUnbind(Intent intent) {
mPlayer.stop();
mPlayer.release();
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
if (checkError == false) {
startSong(mListSongs.get(SONG_POS).getSongUri(), mListSongs.get(SONG_POS).getSongName(), mListSongs.get(SONG_POS).getmSongAlbumArt(), SONG_POS);
checkError = true;
} else {
mPlayer.reset();
try {
if (SONG_POS != mListSongs.size() - 1) {
SONG_POS++;
setSongDetails(SONG_POS);
} else {
SONG_POS = 0;
setSongDetails(SONG_POS);
}
mPlayer.setDataSource(getApplicationContext(), mListSongs.get(SONG_POS).getSongUri());
} catch (Exception e) {
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
mPlayer.prepareAsync();
if (mState == STATE_PLAYING) {
MainActivity.imgPlayPause.setImageResource(R.drawable.pause);
} else
MainActivity.imgPlayPause.setImageResource(R.drawable.play);
editor = getSharedPreferences("MusicPref", MODE_PRIVATE).edit();
editor.putInt("SongPosition", SONG_POS);
editor.putString("SongURI", mListSongs.get(SONG_POS).getSongUri().toString());
editor.commit();
}
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d("EEE", String.valueOf(what) + "," + String.valueOf(extra));
checkError = false;
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
new ProgressUpdater();
}
private void initPlayer() {
mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.KITKAT) {
try {
Class<?> cMediaTimeProvider = Class.forName("android.media.MediaTimeProvider");
Class<?> cSubtitleController = Class.forName("android.media.SubtitleController");
Class<?> iSubtitleControllerAnchor = Class.forName("android.media.SubtitleController$Anchor");
Class<?> iSubtitleControllerListener = Class.forName("android.media.SubtitleController$Listener");
Constructor constructor = cSubtitleController.getConstructor(new Class[]{Context.class, cMediaTimeProvider, iSubtitleControllerListener});
Object subtitleInstance = constructor.newInstance(getApplicationContext(), null, null);
Field f = cSubtitleController.getDeclaredField("mHandler");
f.setAccessible(true);
try {
f.set(subtitleInstance, new Handler());
} catch (IllegalAccessException e) {
} finally {
f.setAccessible(false);
}
Method setsubtitleanchor = mPlayer.getClass().getMethod("setSubtitleAnchor", cSubtitleController, iSubtitleControllerAnchor);
setsubtitleanchor.invoke(mPlayer, subtitleInstance, null);
//Log.e("", "subtitle is setted :p");
} catch (Exception e) {
}
}
}
public void startSong(Uri songuri, String songName, Bitmap bitmap, int position) {
//Set data & start playing music
setSongDetails(position);
mPlayer.reset();
mState = STATE_PLAYING;
mSongUri = songuri;
mSongBitmap = bitmap;
try {
mPlayer.setDataSource(getApplicationContext(), mSongUri);
} catch (Exception e) {
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
mPlayer.prepareAsync();
if (mState == STATE_PLAYING) {
MainActivity.imgPlayPause.setImageResource(R.drawable.pause);
} else {
MainActivity.imgPlayPause.setImageResource(R.drawable.play);
}
Log.d("EEESonfPOs", String.valueOf(position));
editor = getSharedPreferences("MusicPref", MODE_PRIVATE).edit();
editor.putInt("SongPosition", SONG_POS);
editor.putString("SongURI", mListSongs.get(SONG_POS).getSongUri().toString());
editor.commit();
updateNotification(songName);
}
public void playPauseSong() {
if (mState == STATE_PAUSED) {
mState = STATE_PLAYING;
mPlayer.start();
MainActivity.imgPlayPause.setImageResource(R.drawable.pause);
} else {
mState = STATE_PAUSED;
mPlayer.pause();
MainActivity.imgPlayPause.setImageResource(R.drawable.play);
}
}
public boolean isPlayingg() {
return mPlayer.isPlaying();
}
public int getPosn() {
return mPlayer.getCurrentPosition();
}
public int getDur() {
int n = songDuration;
return songDuration;
}
public void pausePlayer() {
mPlayer.pause();
}
private void setSongDetails(int position) {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
byte[] rawArt;
Bitmap art = null;
BitmapFactory.Options bfo = new BitmapFactory.Options();
mmr.setDataSource(getApplicationContext(), mListSongs.get(position).getSongUri());
rawArt = mmr.getEmbeddedPicture();
// if rawArt is null then no cover art is embedded in the file or is not
// recognized as such.
if (null != rawArt) {
Bitmap bm = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(rawArt, 0, rawArt.length, bfo),
100, 100,
true);
MainActivity.imgSongArt.setImageBitmap(bm);
MainActivity.tvSongName.setText(mListSongs.get(position).getSongName());
MainActivity.tvSongArtist.setText(mListSongs.get(position).getmSongArtist());
} else {
MainActivity.imgSongArt.setImageResource(R.drawable.default_album_art);
MainActivity.tvSongName.setText(mListSongs.get(position).getSongName());
MainActivity.tvSongArtist.setText(mListSongs.get(position).getmSongArtist());
}
}
public void stopSong() {
mPlayer.stop();
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(NOTIFICATION_ID);
//System.exit(0);
}
public void nextSong() {
if (SONG_POS != mListSongs.size() - 1) {
startSong(mListSongs.get(SONG_POS + 1).getSongUri(), mListSongs.get(SONG_POS + 1).getSongName(), mListSongs.get(SONG_POS + 1).getmSongAlbumArt(), SONG_POS + 1);
SONG_POS++;
} else {
SONG_POS = 0;
startSong(mListSongs.get(0).getSongUri(), mListSongs.get(0).getSongName(), mListSongs.get(0).getmSongAlbumArt(), 0);
}
editor = getSharedPreferences("MusicPref", MODE_PRIVATE).edit();
editor.putInt("SongPosition", SONG_POS);
editor.putString("SongURI", mListSongs.get(SONG_POS).getSongUri().toString());
editor.commit();
}
public void previousSong() {
if (SONG_POS != 0) {
startSong(mListSongs.get(SONG_POS - 1).getSongUri(), mListSongs.get(SONG_POS - 1).getSongName(), mListSongs.get(SONG_POS - 1).getmSongAlbumArt(), SONG_POS - 1);
SONG_POS--;
} else {
startSong(mListSongs.get(mListSongs.size() - 1).getSongUri(), mListSongs.get(mListSongs.size() - 1).getSongName(), mListSongs.get(mListSongs.size() - 1).getmSongAlbumArt(), mListSongs.size() - 1);
SONG_POS = mListSongs.size() - 1;
}
editor = getSharedPreferences("MusicPref", MODE_PRIVATE).edit();
editor.putInt("SongPosition", SONG_POS);
editor.putString("SongURI", mListSongs.get(SONG_POS).getSongUri().toString());
editor.commit();
}
public void setSongURI(Uri uri) {
this.mSongUri = uri;
}
public void setmSongBitmap(Bitmap mSongBitmap) {
this.mSongBitmap = mSongBitmap;
}
public void setSelectedSong(int pos, int notification_id) {
SONG_POS = pos;
NOTIFICATION_ID = notification_id;
setSongURI(mListSongs.get(SONG_POS).getSongUri());
setmSongBitmap(mListSongs.get(SONG_POS).getmSongAlbumArt());
showNotification();
startSong(mListSongs.get(SONG_POS).getSongUri(), mListSongs.get(SONG_POS).getSongName(), mListSongs.get(SONG_POS).getmSongAlbumArt(), SONG_POS);
}
public void setSongList(ArrayList<Song> listSong) {
mListSongs = listSong;
}
public void showNotification() {
PendingIntent pendingIntent;
Intent intent;
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
RemoteViews notificationView = new RemoteViews(getPackageName(), R.layout.notification_mediacontroller);
notificationView.setTextViewText(R.id.notify_song_name, mListSongs.get(SONG_POS).getSongName());
intent = new Intent(ACTION_STOP);
pendingIntent = PendingIntent.getService(getApplicationContext(), REQUEST_CODE_STOP, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationView.setOnClickPendingIntent(R.id.notify_btn_stop, pendingIntent);
intent = new Intent(ACTION_PAUSE);
pendingIntent = PendingIntent.getService(getApplicationContext(), REQUEST_CODE_PAUSE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationView.setOnClickPendingIntent(R.id.notify_btn_pause, pendingIntent);
intent = new Intent(ACTION_PREVIOUS);
pendingIntent = PendingIntent.getService(getApplicationContext(), REQUEST_CODE_PREVIOUS, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationView.setOnClickPendingIntent(R.id.notify_btn_previous, pendingIntent);
intent = new Intent(ACTION_NEXT);
pendingIntent = PendingIntent.getService(getApplicationContext(), REQUEST_CODE_NEXT, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationView.setOnClickPendingIntent(R.id.notify_btn_next, pendingIntent);
mNotification = notificationBuilder
.setSmallIcon(R.drawable.ic_launcher).setOngoing(true)
.setWhen(System.currentTimeMillis())
.setContent(notificationView)
.setDefaults(Notification.FLAG_NO_CLEAR)
.build();
notificationManager.notify(NOTIFICATION_ID, mNotification);
}
private void updateNotification(String songName) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotification.contentView.setTextViewText(R.id.notify_song_name, songName);
mNotification.contentView.setImageViewBitmap(R.id.img_notification, mListSongs.get(SONG_POS).getmSongAlbumArt());
notificationManager.notify(NOTIFICATION_ID, mNotification);
}
}
I think you need to release media player reference in the onPause method. Try it out. It may work!

Android background service and wake lock

I have android background service to connect with my RabbitMQ server. My background service listen incoming rabbitmq message. Everything is working well but the problem is appear while screen goes off. My android client disconnect when phone screen goes off. What should I do to always connected with my android rabbitmq client and rabbitmq server ?
My code are below :
public class RabbitmqPushService extends Service{
private Thread subscribeThread;
private ConnectionFactory factory;
private Connection connectionSubscribe;
private Channel channelSubscribe;
private NotificationManager mNotificationManager;
public static int NOTIFICATION_ID = 0;
private static final String HOST_NAME = Constant.HOST_NAME; //Rabbitmq Host Name
private static final int PORT_ADDRESS = 5672;
private static final String EXCHANGE_NAME = "fanout_msg";
private static String QUEUE_NAME = Constant.phone_number+"_queue"; //Queue Name
private static String[] ROUTE_KEY = {"all", Constant.phone_number};
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
NOTIFICATION_ID = 0;
setupConnectionFactory();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(connectionSubscribe != null)
{
if(!connectionSubscribe.isOpen())
{
connect();
}
}
else
{
connect();
}
return Service.START_STICKY;
}
#Override
public void onDestroy() {
if(connectionSubscribe != null)
{
disconnectSubscribe();
}
NOTIFICATION_ID = 0;
}
private void setupConnectionFactory() {
factory = new ConnectionFactory();
factory.setHost(HOST_NAME);
factory.setPort(PORT_ADDRESS);
factory.setUsername(Constant.USERNAME);
factory.setPassword(Constant.PASSWORD);
factory.setRequestedHeartbeat(60);
}
private void connect()
{
final Handler incomingMessageHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String message = msg.getData().getString("msg");
try {
JSONObject jsonObject = new JSONObject(message);
BeepHelper.msgBeep(getApplicationContext());
sendNotification("From : " + jsonObject.getString("from"), jsonObject.getString("message"));
} catch (JSONException e) {
e.printStackTrace();
}
}
};
subscribe(incomingMessageHandler);
publishToAMQP();
}
private void disconnectSubscribe()
{
subscribeThread.interrupt();
try {
channelSubscribe.close();
connectionSubscribe.close();
} catch (IOException e) {
e.printStackTrace();
}
catch (TimeoutException e) {
e.printStackTrace();
}
}
void subscribe(final Handler handler)
{
subscribeThread = new Thread()
{
#Override
public void run() {
while(true) {
try {
connectionSubscribe = factory.newConnection();
channelSubscribe = connectionSubscribe.createChannel();
channelSubscribe.exchangeDeclare(EXCHANGE_NAME, "fanout");
channelSubscribe.queueDeclare(QUEUE_NAME, true, false, false, null);
for(int i = 0; i<ROUTE_KEY.length; i++)
{
channelSubscribe.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTE_KEY[i]);
}
QueueingConsumer consumer = new QueueingConsumer(channelSubscribe);
channelSubscribe.basicConsume(QUEUE_NAME, false, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
Message msg = handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putString("msg", message);
msg.setData(bundle);
handler.sendMessage(msg);
channelSubscribe.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
} catch (InterruptedException e) {
break;
} catch (Exception e1) {
try {
Thread.sleep(4000); //sleep and then try again
} catch (InterruptedException e) {
break;
}
}
}
}
};
subscribeThread.start();
}
#Override
public void publishMessage(String message) {
try {
queue.putLast(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void sendNotification(String title, String msg) {
mNotificationManager = (NotificationManager)
getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
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(title)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID++, mBuilder.build());
}
}
You need a Wake Lock to keep the phone running when screen is off. Wake locks allow your application to control the power state of the host device.
Add the WAKE_LOCK permission to your application's manifest file:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Then add the following in onCreate():
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakelock= pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getCanonicalName());
wakelock.acquire();
If your app includes a broadcast receiver that uses a service to do some work, you can manage your wake lock through a WakefulBroadcastReceiver. This is the preferred approach. If your app doesn't follow that pattern, you set a wake lock directly.

how to call service from receiver

In my application I want to call service from Receiver.
This is my NotificationReceiver.java
public class NotificationReceiver extends BroadcastReceiver {
NotificationReceiver _this = this;
private static Context _context;
public static final String ACTION_REFRESH_SCHEDULE_ALARM = "com.example.receiver.ACTION_REFRESH_SCHEDULE_ALARM";
String SERVER_URL = "http://192.168.1.7:8080";
#Override
public void onReceive(final Context context, Intent intent) {
_context = context;
initClient();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(_context);
if (settings.getString("userId",null) != null){
gotNotification(new ClientListener(){
#Override
public void onSuccess(String response) {
try {
JSONObject object = new JSONObject(response);
System.out.println("Service object = "+ object);
} catch (JSONException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
#Override
public void onFail(int error) {
}
#Override
public void onCancel() {
}
},settings.getString("userId",null));
}
}
private void initClient(){
NotifierRestClient.init(SERVER_URL + "/api");
}
private void gotNotification (final ClientListener clientListener, final String uId) {
new Thread() {
#Override
public void run() {
try {
final String responseText = NotifierRestClient.getUserNotifications(uId,null);
if (clientListener != null) {
clientListener.onSuccess(responseText);
}
} catch (final Exception e) {
e.printStackTrace();
if (clientListener != null) {
clientListener.onFail(505);
}
}
}
}.start();
}
}
And this is my NotifiactionService.java
public class NotificationService extends Service {
private AlarmManager alarmManagerPositioning;
private PendingIntent pendingIntent;
#Override
public void onCreate() {
super.onCreate();
alarmManagerPositioning = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
final Intent intentToNotificate = new Intent(NotificationReceiver.ACTION_REFRESH_SCHEDULE_ALARM);
pendingIntent = PendingIntent.getBroadcast(this, 0, intentToNotificate, 0);
}
#Override
public void onStart(Intent intent, int startId) {
try {
long notificationInterval = 5002;
alarmManagerPositioning.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), notificationInterval, pendingIntent);
} catch (NumberFormatException e) {
Toast.makeText(this, "error running services: " + e.getMessage(), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "error running services: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onDestroy() {
this.alarmManagerPositioning.cancel(pendingIntent);
}
}
My question is how to call NotificationService in NotificationReceiver and change interval? Any help will be useful Thanks
Start Service in your receiver using
Intent in = new Intent(context,NotificationService.class);
in.putExtra("interval",5001);
context.startService(in);
In your service code,
long notificationInterval = intent.getLongExtra("interval", defaultValue)
to get Data from your receiver, Please use onStartCommand(Intent intent, int flags, int startId), onStart has been deprecated.

Categories

Resources