According to the official document:
https://developer.android.com/reference/android/app/ActivityManager.html#setWatchHeapLimit(long)
I wrote a demo to see whether the HEAP_LIMIT would be triggered.But seems that it was not working,and here is my code.
public class ActivityManagerActivity extends Activity
{
private String TAG = this.getClass().getName();
private Button btnIncreaseMemory;
private BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_manager);
registerBroadcast();
registerHeapLimit();
iniComponent();
}
private void iniComponent()
{
btnIncreaseMemory = (Button) findViewById(R.id.btnIncreaseMemory);
btnIncreaseMemory.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Bitmap bitmap = ((BitmapDrawable) getDrawable(R.mipmap.image)).getBitmap();
Log.e(TAG, "bitmap size:" + bitmap.getByteCount());
((ImageView) findViewById(R.id.ivBitmap)).setImageBitmap(bitmap);
}
});
}
#Override
public void onDestroy()
{
super.onDestroy();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.clearWatchHeapLimit();
if (receiver != null)
{
unregisterReceiver(receiver);
receiver = null;
}
}
private void registerHeapLimit()
{
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.setWatchHeapLimit(2);
}
private void registerBroadcast()
{
IntentFilter filter = new IntentFilter();
filter.addAction("ACTION_REPORT_HEAP_LIMIT");
receiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
// not be called
Toast.makeText(ActivityManagerActivity.this, "get msg", Toast.LENGTH_SHORT).show();
}
};
registerReceiver(receiver, filter);
}
}
I change the code to:
public class ActivityManagerActivity extends Activity
{
private String TAG = this.getClass().getName();
private Button btnIncreaseMemory;
private BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_manager);
registerBroadcast();
registerHeapLimit();
iniComponent();
}
int index = 0;
private void iniComponent()
{
btnIncreaseMemory = (Button) findViewById(R.id.btnIncreaseMemory);
btnIncreaseMemory.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
if(index == 0)
{
Bitmap bitmap = ((BitmapDrawable) getDrawable(R.mipmap.img6802)).getBitmap();
Log.e(TAG, "bitmap1 size:" + bitmap.getByteCount());
((ImageView) findViewById(R.id.ivBitmap)).setImageBitmap(bitmap);
index = 1;
}
else if(index == 1)
{
Bitmap bitmap = ((BitmapDrawable) getDrawable(R.mipmap.img6803)).getBitmap();
Log.e(TAG, "bitmap2 size:" + bitmap.getByteCount());
((ImageView) findViewById(R.id.ivBitmap2)).setImageBitmap(bitmap);
index = 2;
}
else if(index == 2)
{
Bitmap bitmap = ((BitmapDrawable) getDrawable(R.mipmap.img6804)).getBitmap();
Log.e(TAG, "bitmap3 size:" + bitmap.getByteCount());
((ImageView) findViewById(R.id.ivBitmap3)).setImageBitmap(bitmap);
index = 3;
}
}
});
}
#Override
public void onDestroy()
{
super.onDestroy();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.clearWatchHeapLimit();
if (receiver != null)
{
unregisterReceiver(receiver);
receiver = null;
}
}
private void registerHeapLimit()
{
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.setWatchHeapLimit(157286400);//150MB
}
private void registerBroadcast()
{
IntentFilter filter = new IntentFilter();
filter.addAction("ACTION_REPORT_HEAP_LIMIT");
receiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
// not be called
Toast.makeText(ActivityManagerActivity.this, "get msg", Toast.LENGTH_SHORT).show();
}
};
registerReceiver(receiver, filter);
}
}
But still no notifies, even the used-heap passed the limit 150MB which I set.
Increase the pss limit to a reasonable value that will be crossed when clicking the button.
The value you provided (2k) is too small, and I believe your activity crosses this value even before you click the button.
Related
I created my layout for the ExoPlayer buttons
***
<ImageButton
android:id="#id/exo_play"
android:layout_width="50dp"
android:layout_height="50dp"
android:onClick="onPlayClick"
android:background="#drawable/btn_play" />
<ImageButton
android:id="#id/exo_pause"
android:layout_width="50dp"
android:layout_height="50dp"
android:onClick="onPauseClick"
android:background="#drawable/btn_pause" />
***
I have a program in my program that starts and stops from the PlayerActivity. How to make the service stop when clicking on the pause button in the EcxoPlayer, and when you click on play, the service was restarted?
Code PlayerActivity
public class PlayerActivity extends AppCompatActivity {
private int id;
private String title;
private String autor;
private String file;
private String img;
private String MAYBE_ACTION = "MAYBE_ACTION";
static boolean isPlay = false;
ImageButton btnPLayPause;
private TextView txtRadio;
private TextView txtTitle;
private RoundedImageView imgRadio;
private ImageButton exo_pause;
private ImageButton exo_play;
private String internetStatus = "";
BroadcastReceiver br;
BroadcastReceiver serviceReceiver;
public final static String SERVICE_PARAM = "param";
public final static int SERVICE_STATUS = 0;
public final static String BROADCAST_ACTION = "ru.myapps";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
id = getIntent().getExtras().getInt("id");
title = getIntent().getExtras().getString("title");
autor = getIntent().getExtras().getString("autor");
file = "link";
img = getIntent().getExtras().getString("img");
RadioPlayer.simpleExoPlayerView = new SimpleExoPlayerView(this);
RadioPlayer.simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player);
btnPLayPause = (ImageButton) findViewById(R.id.btnPLayPause);
txtRadio = (TextView) findViewById(R.id.txtRadio);
imgRadio = (RoundedImageView) findViewById(R.id.imgRadio);
exo_pause = (ImageButton) findViewById(R.id.exo_pause);
exo_play = (ImageButton) findViewById(R.id.exo_play);
setTitle(title);
txtRadio.setText(title);
br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
IntentFilter intentFilter = new IntentFilter(MAYBE_ACTION);
registerReceiver(br, intentFilter);
if (NetworkUtil.getConnectivityStatus(this) != 0) {
startPlayerService();
exo_pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isPlay) {
stopPlayerService();
}
}
});
exo_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (NetworkUtil.getConnectivityStatus(PlayerActivity.this) != 0 ) {
if (!isPlay) {
startPlayerService();
}
}
}
});
}
}
#Override
protected void onStart() {
super.onStart();
}
public void startPlayerService() {
Intent serviceIntent = new Intent(PlayerActivity.this, PlayerService.class);
serviceIntent.putExtra(PlayerService.KEY_STREAM, file);
serviceIntent.putExtra(PlayerService.KEY_RADIO, title);
serviceIntent.setAction(PlayerConstants.ACTION.STARTFOREGROUND_ACTION);
startService(serviceIntent);
isPlay = true;
btnPLayPause.setImageResource(R.drawable.icon_stop);
exo_pause.setVisibility(View.VISIBLE);
exo_play.setVisibility(View.GONE);
}
private void stopPlayerService() {
Intent serviceIntent = new Intent(PlayerActivity.this, PlayerService.class);
serviceIntent.setAction(PlayerConstants.ACTION.STOPFOREGROUND_ACTION);
stopService(serviceIntent);
isPlay = false;
btnPLayPause.setImageResource(R.drawable.icon_play);
exo_pause.setVisibility(View.GONE);
exo_play.setVisibility(View.VISIBLE);
}
private BroadcastReceiver NetworkChangeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
internetStatus = NetworkUtil.getConnectivityStatusString(context);
//Toast.makeText(context, internetStatus, Toast.LENGTH_LONG).show();
}
};
#Override
protected void onResume() {
super.onResume();
serviceReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int serviceStatus = intent.getIntExtra(SERVICE_PARAM, 0);
if (serviceStatus == SERVICE_STATUS) {
btnPLayPause.setImageResource(R.drawable.icon_play);
}
}
};
IntentFilter filter = new IntentFilter(BROADCAST_ACTION);
registerReceiver(serviceReceiver, filter);
registerReceiver(NetworkChangeReceiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
registerReceiver(NetworkChangeReceiver, new IntentFilter("android.net.wifi.WIFI_STATE_CHANGED"));
}
#Override
protected void onStop() {
super.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (NetworkChangeReceiver != null) unregisterReceiver(NetworkChangeReceiver);
unregisterReceiver(br);
unregisterReceiver(serviceReceiver);
}
}
I tried to implement the actions of buttons in onresume but when I pause the service it stops and the play button does not play
Your OnClickListener should be in OnCreate, try this and let me know:
public class PlayerActivity extends AppCompatActivity {
private int id;
private String title;
private String autor;
private String file;
private String img;
private String MAYBE_ACTION = "MAYBE_ACTION";
static boolean isPlay = false;
ImageButton btnPLayPause;
private TextView txtRadio;
private TextView txtTitle;
private RoundedImageView imgRadio;
private SimpleExoPlayerView simpleExoPlayerView;
private SimpleExoPlayer player;
private ImageButton exo_pause;
private ImageButton exo_play;
public static String LOG_TAG = "my_log";
private String internetStatus = "";
BroadcastReceiver br;
BroadcastReceiver serviceReceiver;
private AsyncTask jsonTask;
public final static String SERVICE_PARAM = "param";
public final static int SERVICE_STATUS = 0;
public final static String BROADCAST_ACTION = "ru.myapps";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
id = getIntent().getExtras().getInt("id");
title = getIntent().getExtras().getString("title");
autor = getIntent().getExtras().getString("autor");
file = "link_mp3_files";
img = getIntent().getExtras().getString("img");
RadioPlayer.simpleExoPlayerView = new SimpleExoPlayerView(this);
RadioPlayer.simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player);
btnPLayPause = (ImageButton) findViewById(R.id.btnPLayPause);
txtRadio = (TextView) findViewById(R.id.txtRadio);
imgRadio = (RoundedImageView) findViewById(R.id.imgRadio);
exo_pause = (ImageButton) findViewById(R.id.exo_pause);
exo_play = (ImageButton) findViewById(R.id.exo_play);
setTitle(title);
txtRadio.setText(title);
if (NetworkUtil.getConnectivityStatus(this) != 0) {
startPlayerService();
}
exo_pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!isPlay) {
stopPlayerService();
}
}
});
exo_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (NetworkUtil.getConnectivityStatus(PlayerActivity.this) != 0 ) {
if (isPlay) {
startPlayerService();
}
}
}
});
br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
IntentFilter intentFilter = new IntentFilter(MAYBE_ACTION);
registerReceiver(br, intentFilter);
}
#Override
protected void onStart() {
super.onStart();
}
public void startPlayerService() {
Intent serviceIntent = new Intent(PlayerActivity.this, PlayerService.class);
serviceIntent.putExtra(PlayerService.KEY_STREAM, file);
serviceIntent.putExtra(PlayerService.KEY_RADIO, title);
serviceIntent.setAction(PlayerConstants.ACTION.STARTFOREGROUND_ACTION);
startService(serviceIntent);
isPlay = true;
btnPLayPause.setImageResource(R.drawable.icon_stop);
if(exo_play.getVisibility() == View.VISIBLE) {
exo_play.setVisibility(View.GONE);
exo_pause.setVisibility(View.VISIBLE);
}
}
private void stopPlayerService() {
Intent serviceIntent = new Intent(PlayerActivity.this, PlayerService.class);
serviceIntent.setAction(PlayerConstants.ACTION.STOPFOREGROUND_ACTION);
stopService(serviceIntent);
isPlay = false;
btnPLayPause.setImageResource(R.drawable.icon_play);
if(exo_pause.getVisibility() == View.VISIBLE) {
exo_pause.setVisibility(View.GONE);
exo_play.setVisibility(View.VISIBLE);
}
}
private BroadcastReceiver NetworkChangeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
internetStatus = NetworkUtil.getConnectivityStatusString(context);
//Toast.makeText(context, internetStatus, Toast.LENGTH_LONG).show();
}
};
#Override
protected void onResume() {
super.onResume();
serviceReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int serviceStatus = intent.getIntExtra(SERVICE_PARAM, 0);
if (serviceStatus == SERVICE_STATUS) {
btnPLayPause.setImageResource(R.drawable.icon_play);
}
}
};
IntentFilter filter = new IntentFilter(BROADCAST_ACTION);
registerReceiver(serviceReceiver, filter);
registerReceiver(NetworkChangeReceiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
registerReceiver(NetworkChangeReceiver, new IntentFilter("android.net.wifi.WIFI_STATE_CHANGED"));
}
#Override
protected void onStop() {
super.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (NetworkChangeReceiver != null) unregisterReceiver(NetworkChangeReceiver);
unregisterReceiver(br);
unregisterReceiver(serviceReceiver);
}
}
In OnResume you can check if it is running or not then stoo it if you would like to.
Your problem is that you never called startPlayerService(); when exo_play is tapped. Please see exo_play.setOnClickListener. I also removed the else statement as it is unnecessary.
I have little problem with overlap of time in ProgressBar. I have list card. When click this item show activity with display detail Card show progress bar with counts down the time. When time is over, Counts again. When add next Card and click this card show time previous Card. I don't idea why new Card
has the same time as old Card.
ProgressBarService.class
public class ProgressBarService extends IntentService {
private int interval;
public static final String KEY_EXTRA_PROGRESS = "progress";
public ProgressBarService() {
super(ProgressBarService.class.getSimpleName());
}
#Override
protected void onHandleIntent(Intent intent) {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(ProgressBarService.KEY_EXTRA_PROGRESS);
if (intent != null) {
interval = intent.getIntExtra("interval", 0);
for (int i = interval; i >= 0; i--) {
broadcastIntent.putExtra("progress", i);
sendBroadcast(broadcastIntent);
SystemClock.sleep(1000);
}
}
}
}
CardDeatlisActitvty.class
public class CardDetailsActivity extends AppCompatActivity {
private Intent service;
private ResponseReceiver receiver = new ResponseReceiver();
private ProgressBar progressBar;
private TextView secondTimeTextView;
private int interval;
public class ResponseReceiver extends BroadcastReceiver {
// on broadcast received
#Override
public void onReceive(Context context, Intent intent) {
// Check action name.
if (intent.getAction().equals(ProgressBarService.KEY_EXTRA_PROGRESS)) {
int value = intent.getIntExtra("progress", 0);
new ShowProgressBarTask().execute(value);
}
}
}
class ShowProgressBarTask extends AsyncTask<Integer, Integer, Integer> {
#Override
protected Integer doInBackground(Integer... args) {
return args[0];
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
progressBar.setProgress(result);
secondTimeTextView.setText(" " + result + " ");
if (result == 0) {
service = new Intent(CardDetailsActivity.this, ProgressBarService.class);
service.putExtra("interval", interval);
startService(service);
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_card_details);
Bundle extras = getIntent().getExtras();
if (extras != null) {
intervalTotpEncrypt = extras.getString("intervalTotp");
}
interval = Integer.parseInt(intervalTotpDecrypt);
progressBar.setMax(interval);
progressBar.setProgress(interval);
service = new Intent(this, ProgressBarService.class);
service.putExtra("interval", interval);
startService(service);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(
ProgressBarService.KEY_EXTRA_PROGRESS));
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
Your ProgressBarService doesn't know that the "Card" CardDetailsActivity was changed. If for (int i = interval; i >= 0; i--) {...} loop doesn't run out and if (result == 0) { } is not true then it will behave as you described becouse ProgressBarService counter still counts.
#Override
protected void onPause() {
// notify ProgressBarService that the card will be changed (reset the counter)
}
Mind that when you call CardDetailsActivity for the second time (next card) onCreate() could be not called.
I am writing a class to control start and stop timer in Android. The controller is an Activity that will send start or stop value. In the TimerControl class, I write two functions that use to start and stop the timer. I can start the timer, but I cannot stop it. How can I solve it? This is my code
//In Controller class
//===========Start========
Intent smsTimer = new Intent(getApplicationContext(), TimmerControl.class);
smsTimer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
smsTimer.putExtra("input_timer", "start");
getApplicationContext().startActivity(smsTimer);
//===========Stop========
Intent smsTimer = new Intent(getApplicationContext(), TimmerControl.class);
smsTimer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
smsTimer.putExtra("input_timer", "stop");
getApplicationContext().startActivity(smsTimer);
This is my code of TimerControl
public class TimmerControl extends Activity {
private CountDownTimer timer_SMS;
private String TAG="TimmerControl";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null &&intent.getExtras() != null) {
Bundle bundle = intent.getExtras();
if (!bundle.getString("input_timer").equals(null)) {
String input_timer = bundle.getString("input_timer");
if(input_timer.equals("start")) {// start
startSMSTimer();
}
else if(input_timer.equals("stop")) {// stop
stopSMSTimer();
}
else{}
}
}
finish();
}
public void startSMSTimer(){
if (timer_SMS != null) {
timer_SMS.cancel();
timer_SMS = null;
}
timer_SMS = new CountDownTimer(100000, 20000) {
#Override
public void onTick(long millisUntilFinished) {
long timOver = 100000 - millisUntilFinished;
Log.d(TAG, String.valueOf(timOver));
}
#Override
public void onFinish() { }
};
timer_SMS.start();
}
public void stopSMSTimer(){
if (timer_SMS != null) {
timer_SMS.cancel();
timer_SMS = null;
}
}
}
You need to send "stop" while sending intent for stop as follows :
//In Controller class
//===========Start========
Intent smsTimer = new Intent(getApplicationContext(), TimmerControl.class);
smsTimer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
smsTimer.putExtra("input_timer", "start"); // start
getApplicationContext().startActivity(smsTimer);
//===========Stop========
Intent smsTimer = new Intent(getApplicationContext(), TimmerControl.class);
smsTimer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
smsTimer.putExtra("input_timer", "stop"); // stop
getApplicationContext().startActivity(smsTimer);
public class TimmerControl extends Service {
CountDownTimer timer_SMS;
private BroadcastReceiver mReceiver;
#Override
public void onCreate() {
super.onCreate();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("start");
intentFilter.addAction("stop");
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//extract our message from intent
if (intent.getAction().equals("start")) {
startSMSTimer();
}
if (intent.getAction().equals("stop")) {
stopSMSTimer();
}
}
};
this.registerReceiver(mReceiver, intentFilter);
}
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
this.unregisterReceiver(this.mReceiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void startSMSTimer() {
if (timer_SMS != null) {
timer_SMS.cancel();
timer_SMS = null;
}
timer_SMS = new CountDownTimer(100000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
long timOver = 100000 - millisUntilFinished;
Log.e("Time: ", ""+timOver);
}
#Override
public void onFinish() {
Log.e("finished: ","");
}
};
timer_SMS.start();
}
public void stopSMSTimer() {
if (timer_SMS != null) {
timer_SMS.cancel();
timer_SMS = null;
Log.e("Stop: ","");
}
stopSelf();
}
}
SMSControllerActivity.java
public class SMSControllerActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smscontroller);
findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!isServiceRunning(TimmerControl.class))
startService(new Intent(SMSControllerActivity.this, TimmerControl.class));
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
sendBroadcast(new Intent("start"));
}
}, 500);
}
});
findViewById(R.id.btn_stop).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendBroadcast(new Intent("stop"));
}
});
;
}
private boolean isServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
activity_smscontroller.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/btn_start"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Start" />
<Button
android:id="#+id/btn_stop"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Stop" />
</LinearLayout>
I managed to start a conference call cut it closes right after I start it with HUNG_UP cause and I got this in my log:
11-03 17:28:08.940: E/sinch-android-rtc(19101): peermediaconnection: virtual void rebrtc::SetSDPObserver::OnFailure(const string&)Failed to set remote answer sdp: Offer and answer descriptions m-lines are not matching. Rejecting answer.
11-03 17:28:08.940: E/sinch-android-rtc(19101): mxp: Failed to set remote answer sdp: Offer and answer descriptions m-lines are not matching. Rejecting answer.
can anybody help me solve this please?
Edit:
my scenario is when a user clicks the call button I ask him if he wants to start a new call or join an already created one.
I managed to make my code from this question (Sinch conference call error) work as my GroupService class had some bugs.
I start my call like this:
Intent intent1 = new Intent(CreateGroupCallActivity.this,SinchClientService.class);
intent1.setAction(SinchClientService.ACTION_GROUP_CALL);
String id = String.valueOf(uid) + "-" + call_id.getText().toString();
intent1.putExtra(SinchClientService.INTENT_EXTRA_ID,id);
startService(intent1);
and in my SinchClientService:
if(intent.getAction().equals(ACTION_GROUP_CALL))
{
String id = intent.getStringExtra(INTENT_EXTRA_ID);
if(id != null)
groupCall(id);
}
public void groupCall(String id) {
if (mCallClient != null) {
Call call = mCallClient.callConference(id);
CurrentCall.currentCall = call;
Log.d("call", "entered");
Intent intent = new Intent(this, GroupCallService.class);
startService(intent);
}
}
nd here is my GroupCallService
public class GroupCallScreenActivity extends AppCompatActivity implements ServiceConnection {
private SinchClientService.MessageServiceInterface mMessageService;
private GroupCallService.GroupCallServiceInterface mCallService;
private UpdateReceiver mUpdateReceiver;
private ImageButton mEndCallButton;
private TextView mCallDuration;
private TextView mCallState;
private TextView mCallerName;
//private TextView locationview;
private ImageView user_pic;
private long mCallStart;
private Timer mTimer;
private UpdateCallDurationTask mDurationTask;
ImageButton chat;
ImageButton speaker;
ImageButton mic;
boolean speaker_on = false;
boolean mic_on = true;
PowerManager mPowerManager;
WakeLock mProximityWakeLock;
final static int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;
com.galsa.example.main.ImageLoader mImageLoader;
/*String location;
String longitude;
String latitude;*/
private class UpdateCallDurationTask extends TimerTask {
#Override
public void run() {
GroupCallScreenActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
updateCallDuration();
}
});
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
setContentView(R.layout.callscreen);
doBind();
mCallDuration = (TextView) findViewById(R.id.callDuration);
mCallerName = (TextView) findViewById(R.id.remoteUser);
mCallState = (TextView) findViewById(R.id.callState);
//locationview = (TextView) findViewById(R.id.location);
mEndCallButton = (ImageButton) findViewById(R.id.hangupButton);
chat = (ImageButton) findViewById(R.id.chat);
chat.setVisibility(View.GONE);
speaker = (ImageButton) findViewById(R.id.speaker);
mic = (ImageButton) findViewById(R.id.mic);
user_pic = (ImageView) findViewById(R.id.user_pic);
/*location = getIntent().getStringExtra("location");
longitude = getIntent().getStringExtra("longitde");
latitude = getIntent().getStringExtra("latitude");
locationview.setText(location);*/
mImageLoader = new com.galsa.example.main.ImageLoader(GroupCallScreenActivity.this, R.dimen.caller_image_height);
//mCallerName.setText(mCall.getRemoteUserId());
mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
mProximityWakeLock = mPowerManager.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, Utils.TAG);
/*chat.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(GroupCallScreenActivity.this, MessagingActivity.class);
intent.putExtra(SinchClientService.INTENT_EXTRA_ID, mCallService.getCallerId());
intent.putExtra(SinchClientService.INTENT_EXTRA_NAME, mCallService.getCallerName());
startActivity(intent);
}
});*/
speaker.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(speaker_on)
{
mMessageService.speakerOn(speaker_on);
speaker_on = false;
speaker.setImageResource(R.drawable.speaker_off);
}
else
{
mMessageService.speakerOn(speaker_on);
speaker_on = true;
speaker.setImageResource(R.drawable.speaker_on);
}
}
});
mic.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mic_on)
{
mMessageService.micOn(mic_on);
mic_on = false;
mic.setImageResource(R.drawable.mic_off);
}
else
{
mMessageService.micOn(mic_on);
mic_on = true;
mic.setImageResource(R.drawable.mic_on);
}
}
});
mEndCallButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mCallService.endCall();
}
});
mCallStart = System.currentTimeMillis();
}
private void doBind() {
Intent intent = new Intent(this, SinchClientService.class);
bindService(intent, this, BIND_AUTO_CREATE);
intent = new Intent(this, GroupCallService.class);
bindService(intent, this, BIND_AUTO_CREATE);
}
private void doUnbind() {
unbindService(this);
}
#Override
protected void onStart() {
super.onStart();
mUpdateReceiver = new UpdateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(GroupCallService.ACTION_FINISH_CALL_ACTIVITY);
filter.addAction(GroupCallService.ACTION_CHANGE_AUDIO_STREAM);
filter.addAction(GroupCallService.ACTION_UPDATE_CALL_STATE);
LocalBroadcastManager.getInstance(this).registerReceiver(mUpdateReceiver, filter);
}
#Override
public void onResume() {
super.onResume();
if(mProximityWakeLock != null && !mProximityWakeLock.isHeld()){
mProximityWakeLock.acquire();
}
mTimer = new Timer();
mDurationTask = new UpdateCallDurationTask();
mTimer.schedule(mDurationTask, 0, 500);
}
#Override
public void onPause() {
super.onPause();
if(isFinishing() && mProximityWakeLock != null && mProximityWakeLock.isHeld()){
mProximityWakeLock.release();
}
mDurationTask.cancel();
}
#Override
protected void onStop() {
super.onStop();
if(isFinishing() && mProximityWakeLock != null && mProximityWakeLock.isHeld()){
mProximityWakeLock.release();
}
if(mUpdateReceiver != null)
{
LocalBroadcastManager.getInstance(this).unregisterReceiver(mUpdateReceiver);
mUpdateReceiver = null;
}
}
#Override
public void onBackPressed() {
// User should exit activity by ending call, not by going back.
}
private void updateCallDuration() {
mCallDuration.setText(Utils.formatTimespan(System.currentTimeMillis() - mCallStart));
}
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
if(iBinder instanceof GroupCallService.GroupCallServiceInterface)
{
mCallService = (GroupCallService.GroupCallServiceInterface) iBinder;
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
ActionBar actionBar = getSupportActionBar();
if(mCallService.getCallerName() != null)
actionBar.setTitle(mCallService.getCallerName());
else
actionBar.setTitle("Group call");
actionBar.setIcon(R.drawable.callscreen);
if(mCallService.getCallerName() != null)
mCallerName.setText(mCallService.getCallerName());
else
mCallerName.setText("Group call");
mCallState.setText(mCallService.getCallState());
String pic = ChatDatabaseHandler.getInstance(this).getFriendpic(mCallService.getCallerId());
mImageLoader.displayImage(UserFunctions.hostImageDownloadURL + pic, user_pic);
}
else
mMessageService = (SinchClientService.MessageServiceInterface) iBinder;
mMessageService.enableMic();
mMessageService.disableSpeaker();
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mMessageService = null;
mCallService = null;
}
#Override
public void onDestroy() {
if(mUpdateReceiver != null)
{
LocalBroadcastManager.getInstance(this).unregisterReceiver(mUpdateReceiver);
mUpdateReceiver = null;
}
doUnbind();
super.onDestroy();
}
private class UpdateReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if(GroupCallService.ACTION_FINISH_CALL_ACTIVITY.equals(intent.getAction()))
{
finish();
}
else if(GroupCallService.ACTION_CHANGE_AUDIO_STREAM.equals(intent.getAction()))
{
setVolumeControlStream(intent.getIntExtra("STREAM_TYPE", AudioManager.USE_DEFAULT_STREAM_TYPE));
}
else if(GroupCallService.ACTION_UPDATE_CALL_STATE.equals(intent.getAction()))
{
mCallState.setText(intent.getStringExtra("STATE"));
}
}
}
}
I start the call with the same way whether the user will start a new call or join a created one.
I use the following code to stop the music that plays in loop in the app background when the app goes to background, it works on the emulator, not so much on the phone. Even when I exit the app the sound still plays, anyone got a solution for that? I'd be very thankful
#Override
protected void onPause() {
super.onPause();
Context context = getApplicationContext();
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
if (!taskInfo.isEmpty()) {
ComponentName topActivity = taskInfo.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
MusicManager.getInstance().stopMusic();
Toast.makeText(MainActivity.this, "YOU LEFT YOUR APP", Toast.LENGTH_SHORT).show();
}
}
UPDATE:
MusicManager:
public class MusicManager {
MediaPlayer mp = null;
private static MusicManager refrence = null;
public static MusicManager getInstance(){
if(refrence==null){
refrence = new MusicManager();
}
return refrence;
}
public void initializeMediaPlayer(Context context, int musicID){
mp = MediaPlayer.create(context, R.raw.rock);
mp.setLooping(true);
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void playMusic(){
mp.start();
}
public void stopMusic(){
if (mp != null) {
mp.stop();
mp.release();
}
}
}
Main:
MusicManager.getInstance().initializeMediaPlayer(this, R.raw.rock);
MusicManager.getInstance().playMusic();
Here's the code
Main:
public class MainActivity extends Activity{
ImageView startB;
Bitmap b = null;
int keyCode = 0;
boolean onKeyDown = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getApplication().registerActivityLifecycleCallbacks(new MYLifeCycleHandler(getApplication())); // New error:the constructor MYLifeCycleHandler is undefined
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
/* adapt the image to the size of the display */
Display d = getWindowManager().getDefaultDisplay();
Point p = new Point();
d.getSize(p);
b = Bitmap.createScaledBitmap(
BitmapFactory.decodeResource(getResources(), R.drawable.screen1),//b
p.x, p.y, true);
setContentView(R.layout.activity_main);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl1);
rl.setBackgroundDrawable(new BitmapDrawable(getResources(), b));
ImageView startB = (ImageView) findViewById(R.id.startbutton);
MusicManager.getInstance().initializeMediaPlayer(this, R.raw.rock);
MusicManager.getInstance().playMusic();
if(keyCode == KeyEvent.KEYCODE_HOME)
{
onKeyDown = true;
}
startB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent myIntent = new Intent(getApplicationContext(), WorkoutPlace2.class);
startActivity(myIntent);
finish();
}
});
}
#Override
public void onBackPressed(){
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
public void onHomePressed(){
if (onKeyDown = true){
AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
manager.setStreamMute(AudioManager.STREAM_MUSIC, true);
android.os.Process.killProcess(android.os.Process.myPid());
}
}
/*#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_HOME)
{
android.os.Process.killProcess(android.os.Process.myPid());
}
return super.onKeyDown(keyCode, event);
}*/
#Override
protected void onPause() {
super.onPause();
Context context = getApplicationContext();
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
if (!taskInfo.isEmpty()) {
ComponentName topActivity = taskInfo.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
MusicManager.getInstance().stopMusic();
Toast.makeText(MainActivity.this, "YOU LEFT YOUR APP", Toast.LENGTH_SHORT).show();
AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
manager.setStreamMute(AudioManager.STREAM_MUSIC, true);
}
}
if (b != null){
b.recycle();
b = null;
}
}
#Override
protected void onResume(){
super.onResume();
MusicManager.getInstance().playMusic();
}
}
MYLifeCycleHadler:
Exactly as in your updated post
You should use activitylifecyclecallbacks to check whether app is foreground or background. It was added in api level 14.
You may use the following code
#SuppressLint("NewApi")
public class MYLifeCycleHandler implements ActivityLifecycleCallbacks
{
private static int resumed;
private static int paused;
private static int started;
private static int stopped;
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState)
{
}
#Override
public void onActivityDestroyed(Activity activity)
{
}
#Override
public void onActivityResumed(Activity activity)
{
++resumed;
}
#Override
public void onActivityPaused(Activity activity)
{
++paused;
}
#Override
public void onActivityStarted(Activity activity) {
++started;
if(started > stopped)
{
//start music player if not already running
MusicManager.getInstance().playMusic();
}
}
public boolean isApplicationInForeground()
{
return resumed > paused;
}
#Override
public void onActivityStopped(Activity activity) {
++stopped;
//if application in background
if(stopped == started)
{
//stop music player if running
MusicManager.getInstance().stopMusic();
}
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState)
{
}
}
You should register for callbacks as follows
getApplication().registerActivityLifecycleCallbacks(new MPLifeCycleHandler());
Ideally register in the onCreate of your first activity