One of the functions of the app which I'm building had a record function. I do this by starting a MediaRecorder object in a service:
Intent intent = new Intent(v.getContext(), RecordService.class);
Messenger messenger = new Messenger(handler);
intent.putExtra("COUNT", basic);
intent.putExtra("MESSENGER", messenger);
v.getContext().startService(intent);
//service
//...
mRecorder = new MediaRecorder();
//...
Now I introduced a notification which had to let the user know what the status is of the recording itself because if you go the the home or hit the backbutton, it has to keep recording. Therefore, if you hit the notification, you go back to the app.
That is where I am struggling, if I click the notification, I go back to the app but everything is set to the initial state (Timer is back 00:00:00 and I can hit the record button again instead of the pause button) What I should accomplish is of course that it keeps recording and that I can see the ongoing timer + stop button. note: the Timer is not a service right now.. Any ideas how I should handle this?
EDIT
Suppose I shut the app down, the service is still running. Reopening the app (and thus activity where the service was initially called from) can we do with:
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) myContext.getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (MyService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
So I partly have that covered, but, the variables passed from that Service to that activity are now gone. It seems that my Handler in my Activity is not picking them up after reopening that Activity?
private Handler handler = new Handler() {
public void handleMessage(Message message) {
//..
Bundle bundle = message.getData();
fileName = bundle.getString("FILENAME");
tvFileName.setText(fileName);
Log.e("Filename", "transfered: " + fileName);
};
};
//EDIT
Fragment:
public class LayoutOne extends Fragment implements OnClickListener {
//vars
@Override
public void onPause() {
super.onPause();
if (mRecorder != null) {
mRecorder.release();
mRecorder = null;
}
if (mPlayer != null) {
mPlayer.release();
mPlayer = null;
}
}
private Handler handler = new Handler() {
public void handleMessage(Message message) {
int i = message.arg1;
Bundle bundle = message.getData();
fileName = bundle.getString("FILENAME");
tvFileName.setText(fileName);
Log.e("Handler", "Succesfully transfered: " + (Integer.toString(i)));
Log.e("Filename", "Succesfully transfered: " + fileName);
};
};
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bRecord:
if (mStartRecording) {
mStartRecording = false;
Intent intent = new Intent(v.getContext(), RecordService.class);
Messenger messenger = new Messenger(handler);
intent.putExtra("MESSENGER", messenger);
v.getContext().startService(intent);
} else {
mRecordButton.setText("Record");
Intent stopIntent = new Intent(v.getContext(),
RecordService.class);
try {
v.getContext().stopService(stopIntent);
} catch (Exception e) {
e.printStackTrace();
}
mStartRecording = true;
}
break;
case R.id.bStop:
Intent stopIntent = new Intent(v.getContext(), RecordService.class);
v.getContext().stopService(stopIntent);
break;
}
}
public static Fragment newInstance(Context context) {
LayoutOne f = new LayoutOne();
return f;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
root = (ViewGroup) inflater.inflate(R.layout.layout_one, null);
myContext = container.getContext();
//buttons
mgr = (NotificationManager) myContext.getSystemService(Context.NOTIFICATION_SERVICE);
return root;
}
public void notifyMe(View v) {
Notification note = new Notification(R.drawable.ic_launcher,
getString(R.string.notificationbar), System.currentTimeMillis());
PendingIntent i = PendingIntent.getActivity(myContext, 0, new Intent(
myContext, ViewPagerStyle1Activity.class), 0);
note.setLatestEventInfo(myContext, getString(R.string.app_name),
getString(R.string.notification), i);
note.number = ++count;
note.vibrate = new long[] { 500L, 200L, 200L, 500L };
note.flags |= Notification.FLAG_AUTO_CANCEL;
mgr.notify(NOTIFY_ME_ID, note);
}
public void clearNotification(View v) {
mgr.cancel(NOTIFY_ME_ID);
}
// /SHARED PREFERENCES SETTINGS///
//…
private void initiatePopupWindow() {
//..
}
@Override
public void onResume() {
super.onResume();
Intent intent = new Intent(myContext, RecordService.class);
myContext.startService(intent);
myContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
LocalBinder binder = (LocalBinder) service;
myService = binder.getService();
//myService.setBound(true);
initializeUI();
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
protected void initializeUI() {
//..
}
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
myContext.unbindService(mServiceConnection);
}
@Override
public void onStop() {
// TODO Auto-generated method stub
myContext.unbindService(mServiceConnection);
}
}
//SERVICE
public class RecordService extends Service {
//vars
public class LocalBinder extends Binder {
RecordService getService() {
return RecordService.this;
}
}
@Override
public void onCreate() {
Log.i("Oncreate", "Service onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle extras = intent.getExtras();
if (extras != null) {
messenger = (Messenger) extras.get("MESSENGER");
count = Integer.toString(extras.getInt("COUNT"));
try {
Message message = new Message();
int arg = 0;
message.arg1 = arg;
mFileNamePass=”test”;
Bundle bundle = new Bundle();
bundle.putString("FILENAME", mFileNamePass);
message.setData(bundle);
messenger.send(message);
} catch (android.os.RemoteException e1) {
Log.w(getClass().getName(), "Exception sending message", e1);
}
}
else {
Log.i("Extras","Didn't find extras");
}
Runnable r = new Runnable() {
@Override
public void run() {
checkIfFolderExists();
String dateFull = calculateDate();
mFileName = Environment.getExternalStorageDirectory()
.getAbsolutePath();
mFileName += "test.3gp";
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
Log.i("Service", "Service running");
}
};
Thread t = new Thread(r);
t.start();
return RecordService.START_STICKY;
}
@Override
public void onDestroy() {
Runnable stopRecord = new Runnable() {
@Override
public void run() {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
};
Thread stopRecordThread = new Thread(stopRecord);
stopRecordThread.start();
Log.i("Service", "Service stopped");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
First of all, you don't need to check if your Service
is running by some ActivityManager
method. If you call startService() && bindService()
in your onResume()
, Android is smart enough to just bind to the Service
if it's already running, and if not, it will create the Service
going through it's proper documented lifecycle and then bind to it.
What you could do here is this:
@Override
public void onResume() {
super.onResume();
Intent intent = new Intent(this, YourService.class);
startService(intent);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
Now, lets say your Service is already running and you want to get it's proper values. In the onServiceConnected()
method of your ServiceConnection()
, you can call a method like initializeUI()
when the binding is done:
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
LocalBinder binder = (LocalBinder) service;
myService = binder.getService();
myService.setBound(true);
initializeUI();
}
public void onServiceDisconnected(ComponentName className) {
}
};
And now, you have the myService
variable that points to your Service
object which you can call your getters
on, like myService.getTimer()
and myService.isRecording()
.
public void initializeUI() {
timerTextview.setText( myService.getTime() );
someOtherUiElement.setText( myService.getSomething() );
if( myService.isRecording() )
recordButton.setImageResource( R.drawable.pause );
} //etc...
By the way, I don't know if you're also struggling on keeping your Service running when you exit the app
If you do, using startService(intent)
will keep your Service
running as long as Android has enough memory. You MUST have a piece of code in which you can call myService.stopService()
, otherwise, the Service will run for a very long time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With