From 3fe69eef905112556bf51fee3e8e4be7b4330451 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Mon, 28 Mar 2016 22:16:34 +0300 Subject: [PATCH] add service --- app/src/main/AndroidManifest.xml | 1 + .../activities/RecordingActivity.java | 109 +++--------- .../services/RecordingService.java | 160 ++++++++++++++++++ 3 files changed, 185 insertions(+), 85 deletions(-) create mode 100644 app/src/main/java/com/github/axet/audiorecorder/services/RecordingService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 26855dd..2d94f30 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,6 +15,7 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> + diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java index 15c771b..41c99ab 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java @@ -50,6 +50,7 @@ import com.github.axet.audiorecorder.encoders.FileEncoder; import com.github.axet.audiorecorder.encoders.Format3GP; import com.github.axet.audiorecorder.encoders.FormatM4A; import com.github.axet.audiorecorder.encoders.FormatWAV; +import com.github.axet.audiorecorder.services.RecordingService; import com.github.axet.audiorecorder.widgets.PitchView; import java.io.File; @@ -58,16 +59,10 @@ public class RecordingActivity extends AppCompatActivity { public static int MAXIMUM_ALTITUDE = 5000; public static final String TAG = RecordingActivity.class.getSimpleName(); - public static final String START_RECORDING = RecordingActivity.class.getCanonicalName() + ".START_RECORDING"; - public static final String CLOSE_ACTIVITY = RecordingActivity.class.getCanonicalName() + ".CLOSE_ACTIVITY"; - public static final int NOTIFICATION_RECORDING_ICON = 0; - public static String SHOW_ACTIVITY = RecordingActivity.class.getCanonicalName() + ".SHOW_ACTIVITY"; - public static String PAUSE = RecordingActivity.class.getCanonicalName() + ".PAUSE"; public static String START_PAUSE = RecordingActivity.class.getCanonicalName() + ".START_PAUSE"; public static final String PHONE_STATE = "android.intent.action.PHONE_STATE"; - RecordingReceiver receiver; PhoneStateChangeListener pscl = new PhoneStateChangeListener(); Handler handle = new Handler(); FileEncoder encoder; @@ -104,24 +99,6 @@ public class RecordingActivity extends AppCompatActivity { Storage storage; Sound sound; - public class RecordingReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { - // showRecordingActivity(); - } - if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { - // do nothing. do not annoy user. he will see alarm screen on next screen on event. - } - if (intent.getAction().equals(SHOW_ACTIVITY)) { - showRecordingActivity(); - } - if (intent.getAction().equals(PAUSE)) { - pauseButton(); - } - } - } - class PhoneStateChangeListener extends PhoneStateListener { public boolean wasRinging; public boolean pausedByCall; @@ -175,14 +152,6 @@ public class RecordingActivity extends AppCompatActivity { title.setText(targetFile.getName()); - receiver = new RecordingReceiver(); - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.addAction(Intent.ACTION_SCREEN_OFF); - filter.addAction(SHOW_ACTIVITY); - filter.addAction(PAUSE); - registerReceiver(receiver, filter); - SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); if (shared.getBoolean(MainApplication.PREFERENCE_CALL, false)) { @@ -250,6 +219,26 @@ public class RecordingActivity extends AppCompatActivity { start = false; stopRecording("pause"); } + if (a != null && a.equals(RecordingService.PAUSE_BUTTON)) { + start = false; + stopRecording("pause"); + } + + RecordingService.startService(this, targetFile.getName(), thread != null); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + + String a = intent.getAction(); + + if (a != null && a.equals(START_PAUSE)) { + stopRecording("pause"); + } + if (a != null && a.equals(RecordingService.PAUSE_BUTTON)) { + pauseButton(); + } } void loadSamples() { @@ -288,17 +277,6 @@ public class RecordingActivity extends AppCompatActivity { return "goldfish".equals(Build.HARDWARE); } - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - } - - public void showRecordingActivity() { - Intent intent = new Intent(this, RecordingActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - } - void pauseButton() { if (thread != null) { stopRecording("pause"); @@ -343,7 +321,7 @@ public class RecordingActivity extends AppCompatActivity { stopRecording(); - showNotificationAlarm(true); + RecordingService.startService(this, targetFile.getName(), thread != null); pitch.setOnTouchListener(new View.OnTouchListener() { @Override @@ -521,18 +499,13 @@ public class RecordingActivity extends AppCompatActivity { stopRecording(); - if (receiver != null) { - unregisterReceiver(receiver); - receiver = null; - } + RecordingService.stopService(this); if (pscl != null) { TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); tm.listen(pscl, PhoneStateListener.LISTEN_NONE); pscl = null; } - - showNotificationAlarm(false); } void startRecording() { @@ -671,7 +644,7 @@ public class RecordingActivity extends AppCompatActivity { }, "RecordingThread"); thread.start(); - showNotificationAlarm(true); + RecordingService.startService(this, targetFile.getName(), thread != null); } // calcuale buffer length dynamically, this way we can reduce thread cycles when activity in background @@ -706,40 +679,6 @@ public class RecordingActivity extends AppCompatActivity { return pa; } - // alarm dismiss button - public void showNotificationAlarm(boolean show) { - NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - - if (!show) { - notificationManager.cancel(NOTIFICATION_RECORDING_ICON); - } else { - PendingIntent main = PendingIntent.getBroadcast(this, 0, - new Intent(SHOW_ACTIVITY), - PendingIntent.FLAG_UPDATE_CURRENT); - - PendingIntent pe = PendingIntent.getBroadcast(this, 0, - new Intent(PAUSE), - PendingIntent.FLAG_UPDATE_CURRENT); - - RemoteViews view = new RemoteViews(getPackageName(), R.layout.notifictaion_recording); - view.setOnClickPendingIntent(R.id.status_bar_latest_event_content, main); - view.setTextViewText(R.id.notification_text, ".../" + targetFile.getName()); - view.setOnClickPendingIntent(R.id.notification_pause, pe); - view.setImageViewResource(R.id.notification_pause, thread == null ? R.drawable.play : R.drawable.pause); - - NotificationCompat.Builder builder = new NotificationCompat.Builder(this) - .setOngoing(true) - .setContentTitle("Recording") - .setSmallIcon(R.drawable.ic_mic_24dp) - .setContent(view); - - if (Build.VERSION.SDK_INT >= 21) - builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); - - notificationManager.notify(NOTIFICATION_RECORDING_ICON, builder.build()); - } - } - @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); diff --git a/app/src/main/java/com/github/axet/audiorecorder/services/RecordingService.java b/app/src/main/java/com/github/axet/audiorecorder/services/RecordingService.java new file mode 100644 index 0000000..d6d4117 --- /dev/null +++ b/app/src/main/java/com/github/axet/audiorecorder/services/RecordingService.java @@ -0,0 +1,160 @@ +package com.github.axet.audiorecorder.services; + +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Build; +import android.os.IBinder; +import android.support.annotation.Nullable; +import android.support.v4.app.NotificationCompat; +import android.util.Log; +import android.widget.RemoteViews; + +import com.github.axet.audiorecorder.R; +import com.github.axet.audiorecorder.activities.RecordingActivity; + +/** + * RecordingActivity more likly to be removed from memory when paused then service. Notification button + * does not handle getActvity without unlocking screen. The only option is to have Service. + *

+ * So, lets have it. + *

+ * Maybe later this class will be converted for fully feature recording service with recording thread. + */ +public class RecordingService extends Service { + public static final String TAG = RecordingService.class.getSimpleName(); + + public static final int NOTIFICATION_RECORDING_ICON = 0; + + public static String SHOW_ACTIVITY = RecordingService.class.getCanonicalName() + ".SHOW_ACTIVITY"; + public static String PAUSE_BUTTON = RecordingService.class.getCanonicalName() + ".PAUSE_BUTTON"; + + RecordingReceiver receiver; + + String targetFile; + boolean recording; + + public class RecordingReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { + // showRecordingActivity(); + } + if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { + // do nothing. do not annoy user. he will see alarm screen on next screen on event. + } + } + } + + public static void startService(Context context, String targetFile, boolean recording) { + context.startService(new Intent(context, RecordingService.class) + .putExtra("targetFile", targetFile) + .putExtra("recording", recording)); + } + + public static void stopService(Context context) { + context.stopService(new Intent(context, RecordingService.class)); + } + + public RecordingService() { + } + + @Override + public void onCreate() { + super.onCreate(); + Log.d(TAG, "onCreate"); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.d(TAG, "onStartCommand"); + + receiver = new RecordingReceiver(); + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_SCREEN_OFF); + registerReceiver(receiver, filter); + + String a = intent.getAction(); + + if (a == null) { + targetFile = intent.getStringExtra("targetFile"); + recording = intent.getBooleanExtra("recording", false); + showNotificationAlarm(true); + } else if (a.equals(PAUSE_BUTTON)) { + Intent i = new Intent(this, RecordingActivity.class); + i.setAction(PAUSE_BUTTON); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + startActivity(i); + } else if (a.equals(SHOW_ACTIVITY)) { + Intent i = new Intent(this, RecordingActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + startActivity(i); + } + + return super.onStartCommand(intent, flags, startId); + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + public class Binder extends android.os.Binder { + public RecordingService getService() { + return RecordingService.this; + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.d(TAG, "onDestory"); + + showNotificationAlarm(false); + + unregisterReceiver(receiver); + } + + // alarm dismiss button + public void showNotificationAlarm(boolean show) { + NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + + if (!show) { + notificationManager.cancel(NOTIFICATION_RECORDING_ICON); + } else { + PendingIntent main = PendingIntent.getService(this, 0, + new Intent(this, RecordingService.class).setAction(SHOW_ACTIVITY), + PendingIntent.FLAG_UPDATE_CURRENT); + + PendingIntent pe = PendingIntent.getService(this, 0, + new Intent(this, RecordingService.class).setAction(PAUSE_BUTTON), + PendingIntent.FLAG_UPDATE_CURRENT); + + RemoteViews view = new RemoteViews(getPackageName(), R.layout.notifictaion_recording); + view.setOnClickPendingIntent(R.id.status_bar_latest_event_content, main); + view.setTextViewText(R.id.notification_text, ".../" + targetFile); + view.setOnClickPendingIntent(R.id.notification_pause, pe); + view.setImageViewResource(R.id.notification_pause, !recording ? R.drawable.play : R.drawable.pause); + + NotificationCompat.Builder builder = new NotificationCompat.Builder(this) + .setOngoing(true) + .setContentTitle("Recording") + .setSmallIcon(R.drawable.ic_mic_24dp) + .setContent(view); + + if (Build.VERSION.SDK_INT >= 21) + builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); + + notificationManager.notify(NOTIFICATION_RECORDING_ICON, builder.build()); + } + } +} +