I am an absolute beginner working on my first android app. I am working on an audio stream app and i implemented the mediaPlayer inside a service. There is a play-pause button that toggles if bound or not. The issue i have is that when isPlaying, and i change the screen orientation, though the service continues, the activity is recreated which makes the play button appear rather than the pause button. I know for me to retain the pause button, i need to override two methods - onSaveInstanceState and onRestoreInstanceState but i dont know the right logic to use in order to retain mainActivity's state.
Pls help me because the examples i saw didnt solve my problem.
This is my main activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//.......
if(savedInstanceState != null) {
boolean isPlaying = savedInstanceState.getBoolean("isPlaying");
if(!isPlaying){
imageButton2.setImageResource(R.drawable.stop);
} else {
imageButton2.setImageResource(R.drawable.play);
}
}
#Override
protected void onStart() {
// bind to the radio service
Intent intent = new Intent(this, RadioService.class);
startService(intent);
bindService(intent, mConnection, BIND_AUTO_CREATE);
super.onStart();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onStop() {
// unbind the radio
// service
if (boundToRadioService) {
unbindService(mConnection);
boundToRadioService = false;
}
super.onStop();
}
#Override
protected void onDestroy() {
radioService.hideNotification();
if (boundToRadioService) {
unbindService(mConnection);
boundToRadioService = false;
}
super.onDestroy();
}
public void setupMediaPlayer(View view) {
if (boundToRadioService) {
boundToRadioService = false;
imageButton2.setImageResource(R.drawable.stop);
radioService.play();
} else {
boundToRadioService = true;
imageButton2.setImageResource(R.drawable.play);
radioService.pause();
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean("isPlaying", boundToRadioService);
super.onSaveInstanceState(outState);
}
}
This is my Service
// Binder given to clients
private final IBinder mBinder = new RadioBinder();
}
public void pause() {
audioManager.abandonAudioFocus(audioFocusChangeListener);
unregisterReceiver(audioBecomingNoisy);
mediaPlayer.pause();
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(this, "Oops! Error Occured, Check your network connection", Toast.LENGTH_SHORT).show();
mediaPlayer.reset();
return false;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
#Override
public void onPrepared(MediaPlayer mp) {
{
mp.start();
}
}
public class RadioBinder extends Binder {
RadioService getService() {
// Return this instance of RadioBinder so clients can call public methods
return RadioService.this;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: ");
return mBinder;
}
public void play() {
registerReceiver(audioBecomingNoisy, noisyIntentFilter);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(stream);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.reset();
showNotification();
Toast.makeText(this, "loading... please wait", Toast.LENGTH_LONG).show();
Log.i(TAG, "onCreate, Thread name " + Thread.currentThread().getName());
}
class PlayerTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(stream);
mediaPlayer.prepareAsync();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
return prepared;
}
}
try this,
public class MainActivity extends AppCompatActivity {
private boolean boundToRadioService = false;
private ImageButton imageButton2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageButton2 = (ImageButton) findViewById(R.id.my_button);
if(savedInstanceState != null){
boundToRadioService = savedInstanceState.getBoolean("isPlaying", false);
if(boundToRadioService){
imageButton2.setImageResource(R.drawable.stop);
} else {
imageButton2.setImageResource(R.drawable.play);
}
} else {
// bind to the radio service
Intent intent = new Intent(this, RadioService.class);
startService(intent);
bindService(intent, mConnection, BIND_AUTO_CREATE);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean("isPlaying", boundToRadioService);
super.onSaveInstanceState(outState);
}
public void setupMediaPlayer(View view){
if (boundToRadioService) {
boundToRadioService = false;
imageButton2.setImageResource(R.drawable.play);
radioService.pause();
} else {
boundToRadioService = true;
imageButton2.setImageResource(R.drawable.stop);
radioService.play();
}
}
}
and add android:src="#drawable/play" to the imagebutton in your xml file.
Related
I want to send data from EditText in child activity to parent activity (MainActivity) and use it as a string parameter (URL) in other methods
Already I am able to send this using intent and extras, also I added textview in method to see if it works, but finally, this textview will be deleted, but I can't use it in other methods
public class MainActivity extends AppCompatActivity implements OnDataSendToActivity {
ImageView bg_state;
Button btn_rl;
TextView txt_network;
String url;
String my_url;
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bg_state = findViewById(R.id.bg_status);
txt_network = findViewById(R.id.txt_network);
Toolbar toolbar= findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tv=findViewById(R.id.tV);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if(isNetworkAvailable()){
bg_state.setImageResource(R.drawable.background);
txt_network.setText("");
}else{
bg_state.setImageResource(R.drawable.background_on);
txt_network.setText("Cound not connect to the server");
}
updateStatus();
handler.postDelayed(this, 2000);
}
}, 5000); //the time is in miliseconds
btn_rl = findViewById(R.id.sw_1);
btn_rl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String url_rl = my_url+"room_light";
SelectTask task = new SelectTask(url_rl);
task.execute();
updateStatus();
}
});
String url_rl = url+"bed_light";
SelectTask task = new SelectTask(url_rl);
task.execute();
updateStatus();
}
});*/
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater= getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if(id==R.id.conf){
Intent intent_conf = new Intent(MainActivity.this, Configuration.class);
startActivityForResult(intent_conf,1);
return false;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==1){
if(resultCode==RESULT_OK){
url=data.getStringExtra("url");
my_url="http://"+url;
tv.setText(my_url);
}
}
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
#Override
public void sendData(String str) {
updateButtonStatus(str);
}
private void updateStatus(){
String url_rl = my_url+"status";
StatusTask task = new StatusTask(url_rl, this);
task.execute();
}
//Function for updating Button Status
private void updateButtonStatus(String jsonStrings){
try {
JSONObject json = new JSONObject(jsonStrings);
String room_light = json.getString("rl");
if(room_light.equals("1")){
btn_rl.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, R.drawable.plug_90off);
}else{
btn_rl.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, R.drawable.plug_90on);
}
.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, R.drawable.power_off);
}
}catch (JSONException e){
e.printStackTrace();
}
}
}
childactivity
public class Configuration extends AppCompatActivity {
public String new_url;
EditText ip_text;
Button sub_btn;
String a;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_configuration);
Toolbar tool = findViewById(R.id.toolbar);
setSupportActionBar(tool);
ActionBar actionBar = getSupportActionBar();
if(actionBar!=null){
actionBar.setDisplayHomeAsUpEnabled(true);
}
findViewById(R.id.wifi_btn).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
goToUrl("https://192.168.4.1");
}
});
ip_text = findViewById(R.id.ip_text);
sub_btn= findViewById(R.id.sub_btn);
sub_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i=new Intent(Configuration.this,MainActivity.class);
new_url=ip_text.getText().toString();
i.putExtra("url",new_url);
setResult(RESULT_OK,i);
finish();
}
});
}
}
What I need is that if I write in Configuration class for example 192.168.xx.xx In mainactivity my_url will be my_url="https://192.168/ and it will be able to use in other methods as a parameter (for example in btn_rl.setOnClickListener).
I'm developing a game, I have used services to play music on all activities.
I want to stop the music when we hit the home key, it shouldn't stop playing music when moving from one activity to another.
public class backService extends Service {
private MediaPlayer mp;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mp.stop();
mp.release();
}
#Override
public void onCreate() {
super.onCreate();
mp = MediaPlayer.create(this, R.raw.all);
mp.setLooping(true);
mp.start();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
and my main activity file
public class Home extends AppCompatActivity {
private AdView mAdView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hide();
setContentView(R.layout.activity_home);
Intent i = new Intent(this, backService.class);
adv();
}
#Override
protected void onResume(){
super.onResume();
Intent i = new Intent(this, backService.class);
startService(i);
}
#Override
protected void onStop() {
super.onStop();
Intent i = new Intent(this, backService.class);
stopService(i);
}
#Override
protected void onDestroy(){
super.onDestroy();
Intent i = new Intent(this, backService.class);
stopService(i);
}
}
How can I stop the music when I hit the home key and keep playing the music when we switch between other activities
TIA
Please remove the stopService(i) inside onStop() method in Activity coz whenever you are going one Activity to Another Activity then onStop() method will be called, that's why your service is killing.
If you want to pause or stop music while press home button then implements ComponentCallbacks2 interface to Activity like this
#Override
public void onTrimMemory(final int level) {
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
if(mService != null){
mService.pauseMusic();
}
}
}
Try to stop the service in
#Override
public void onPause()
{
super.onPause();
// Check if app is in foreground
if(!isAppOnForeground(context))
{
stop music here
}
}
below is the method to check if the app is in foreground or not . just replace your package here "your package name here";
public static boolean isAppOnForeground(Context context)
{
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) {
return false;
}
final String packageName = "your package name here";
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}
I want to use my sound on all my activities not only main activity. I put this lines
MediaPlayer ring = MediaPlayer.create(MainActivity.this, R.raw.song);
ring.start();
but that works only in main Activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MediaPlayer ring = MediaPlayer.create(MainActivity.this, R.raw.song);
ring.start();
you can try something like this
1. add this code in your all activity
MediaPlayer ring = MediaPlayer.create(MainActivity.this,
R.raw.song);
ring.start();
2. create one method like this and call this msg from your activity in which you want to play music
public void Playmusic(Context context){
MediaPlayer ring = MediaPlayer.create(context, R.raw.song);
ring.start();
}
now just call this method like this
Playmusic(MainActivity.this);
play your songs in service and initialize the media player object there only
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.idil);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
Please call this service in Manifest
<service android:enabled="true" android:name=".BackgroundSoundService " />
I have already scanned all of the related questons&answers here, but I still couldn't find the solution.
the service class file:
public class otser extends Service {
private WindowManager windowManager;
private ImageView chatHead;
#Override public IBinder onBind(Intent intent) {
return null;
}
#Override public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
FileObserver observer = new FileObserver(android.os.Environment.getExternalStorageDirectory().toString() + "/Pictures/Screenshots") {
#Override
public void onEvent(int event, String file) {
event &= FileObserver.ALL_EVENTS;
if(event == FileObserver.CREATE){
Toast.makeText(getApplicationContext(), "screenshot taken",
Toast.LENGTH_LONG).show();
}
}
};
observer.startWatching(); // start the observer
Toast.makeText(getApplicationContext(), "service: OK",
Toast.LENGTH_SHORT).show();
}}
According to other posts, I double checked the path, via creating a file programatically, it does exist, and correct.
The Activity class:
public class Home extends Activity {
Button showChatHead;
Button stopService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
showChatHead = (Button) findViewById(R.id.gomb);
stopService= (Button) findViewById(R.id.gomb2);
showChatHead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), ChatHeadService.class);
startService(i);
}
});
stopService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), ChatHeadService.class);
stopService(i);
}
});
}}
The service class linked well, the last Toast message pops up, as a conclusion only the observer is being skipped.
Any ideas?
Thanks in advance!
newer release:
FileObserver fileObserver = new FileObserver(android.os.Environment.getExternalStorageDirectory().toString() + "/Pictures/Screenshots") {
#Override
public void onEvent(int event, String path) {
Toast.makeText(getApplicationContext(), "method entered", Toast.LENGTH_SHORT).show();
if (event == FileObserver.CREATE) {
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "File created", Toast.LENGTH_SHORT).show();
}
});
}
}
};
fileObserver.startWatching();
The onEvent method is not entered, the "method entered" Toast didn't appear.
in documentation of the onEvent-Method is mentioned, that it will run at another thread and you should consider this. using a handler, the Toast message should appear, like this:
private Handler handler = new Handler();
#Override
public void onCreate() {
fileObserver = new FileObserver("path") {
#Override
public void onEvent(int event, String path) {
if (event == FileObserver.CREATE) {
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(FileWatcher.this, "File created", Toast.LENGTH_SHORT).show();
}
});
}
}
};
fileObserver.startWatching();
I am writing an app that wants to allow user to answer their call by Proximity sensor. I have one class that named "main" and other Class "SensorService"
public class main extends PreferenceActivity{
SharedPreferences preferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.setting);
findPreference("AIR_CALL").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue.toString().equals("true")) {
Intent intent = new Intent(main.this, Sensor.class);
startService(intent);
} else {
Toast.makeText(getApplicationContext(), "CB: " + "false",
Toast.LENGTH_SHORT).show();
}
return true;
}
});
}}
and sensor :
public class Sensor extends Service implements SensorEventListener {
TelephonyManager telephonyManager;
private SensorManager mSensorManager;
private android.hardware.Sensor mSensor;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(android.hardware.Sensor.TYPE_PROXIMITY);
mSensorManager.registerListener(this, mSensor,SensorManager.SENSOR_DELAY_NORMAL);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.values[0] == 0) {
if ((!Prefrences.isAirAnswerOn) || (Prefrences.PHONE_STATE == null) || (Prefrences.PHONE_STATE.length() <= 0) || (!Prefrences.PHONE_STATE.equals(TelephonyManager.EXTRA_STATE_RINGING)))
{
Intent localIntent = new Intent("android.intent.action.MEDIA_BUTTON");
localIntent.putExtra("android.intent.extra.KEY_EVENT", new KeyEvent(1, 79));
getApplicationContext().sendOrderedBroadcast(localIntent, null);
}
}
}
#Override
public void onAccuracyChanged(android.hardware.Sensor sensor, int accuracy) {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
but when I click On check box no reaction for this , where is the problem?