diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index bf5d8757d48b2eee7d9e71c8e85125f3b995fc3c..56782a090a1c9ee371ecb01820a8bd3bf899838f 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -31,7 +31,6 @@ - \ No newline at end of file diff --git a/wear/src/main/java/james/metronome/MainActivity.java b/wear/src/main/java/james/metronome/MainActivity.java index ced192ff6435f516831e43ca28e12fe64b5742e3..287b98ba4bcb6f958acc4c13889d798048fd7154 100644 --- a/wear/src/main/java/james/metronome/MainActivity.java +++ b/wear/src/main/java/james/metronome/MainActivity.java @@ -1,12 +1,18 @@ package james.metronome; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; +import android.content.SharedPreferences; import android.graphics.Color; +import android.media.AudioAttributes; +import android.media.AudioManager; +import android.media.SoundPool; +import android.os.Build; import android.os.Bundle; -import android.os.IBinder; +import android.os.Handler; +import android.os.PowerManager; +import android.os.VibrationEffect; +import android.os.Vibrator; +import android.preference.PreferenceManager; import android.support.wearable.activity.WearableActivity; import android.support.wearable.view.BoxInsetLayout; import android.view.View; @@ -16,7 +22,10 @@ import android.widget.TextView; import java.util.Locale; -public class MainActivity extends WearableActivity implements ServiceConnection, MetronomeService.TickListener { +public class MainActivity extends WearableActivity implements Runnable { + + public static final String PREF_VIBRATION = "vibration"; + public static final String PREF_INTERVAL = "interval"; private BoxInsetLayout container; private ImageView vibrationView; @@ -24,8 +33,19 @@ public class MainActivity extends WearableActivity implements ServiceConnection, private TextView bpmView; private SeekBar seekBar; - private MetronomeService service; - private boolean isBound; + private PowerManager.WakeLock wakeLock; + + private SharedPreferences prefs; + private int bpm; + private long interval; + + private SoundPool soundPool; + private Handler handler; + private int soundId = -1; + private boolean isPlaying; + private boolean isVibration; + + private Vibrator vibrator; @Override protected void onCreate(Bundle savedInstanceState) { @@ -33,34 +53,69 @@ public class MainActivity extends WearableActivity implements ServiceConnection, setContentView(R.layout.activity_main); setAmbientEnabled(); + PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); + if (powerManager != null) { + wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "idiot.metronome.MainActivity"); + wakeLock.acquire(); + } + + prefs = PreferenceManager.getDefaultSharedPreferences(this); + + vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + soundPool = new SoundPool.Builder() + .setMaxStreams(1) + .setAudioAttributes(new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) + .build()) + .build(); + } else soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); + + isVibration = prefs.getBoolean(PREF_VIBRATION, true); + if (!isVibration) + soundId = soundPool.load(this, R.raw.click, 1); + + interval = prefs.getLong(PREF_INTERVAL, 500); + bpm = Utils.toBpm(interval); + + handler = new Handler(); + container = findViewById(R.id.container); vibrationView = findViewById(R.id.vibration); playView = findViewById(R.id.play); bpmView = findViewById(R.id.bpm); seekBar = findViewById(R.id.seekBar); - if (isBound()) { - vibrationView.setImageResource(service.isVibration() ? R.drawable.ic_vibration : R.drawable.ic_sound); - playView.setImageResource(service.isPlaying() ? R.drawable.ic_pause : R.drawable.ic_play); - bpmView.setText(String.format(Locale.getDefault(), getString(R.string.bpm), String.valueOf(service.getBpm()))); - seekBar.setProgress(service.getBpm()); - } + vibrationView.setImageResource(isVibration ? R.drawable.ic_vibration : R.drawable.ic_sound); + playView.setImageResource(isPlaying ? R.drawable.ic_pause : R.drawable.ic_play); + bpmView.setText(String.format(Locale.getDefault(), getString(R.string.bpm), String.valueOf(bpm))); + seekBar.setProgress(bpm); vibrationView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - service.setVibration(!service.isVibration()); - vibrationView.setImageResource(service.isVibration() ? R.drawable.ic_vibration : R.drawable.ic_sound); + isVibration = !isVibration; + prefs.edit().putBoolean(PREF_VIBRATION, isVibration).apply(); + + if (!isVibration) + soundId = soundPool.load(MainActivity.this, R.raw.click, 1); + else soundId = -1; + + vibrationView.setImageResource(isVibration ? R.drawable.ic_vibration : R.drawable.ic_sound); } }); playView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (isBound()) { - if (service.isPlaying()) - service.pause(); - else service.play(); + isPlaying = !isPlaying; + if (isPlaying) { + handler.post(MainActivity.this); + playView.setImageResource(R.drawable.ic_pause); + } else { + handler.removeCallbacks(MainActivity.this); + playView.setImageResource(R.drawable.ic_play); } } }); @@ -68,7 +123,10 @@ public class MainActivity extends WearableActivity implements ServiceConnection, seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int i, boolean b) { - setBpm(i); + bpm = i; + interval = Utils.toInterval(bpm); + bpmView.setText(String.format(Locale.getDefault(), getString(R.string.bpm), String.valueOf(bpm))); + prefs.edit().putLong(PREF_INTERVAL, interval).apply(); } @Override @@ -83,15 +141,18 @@ public class MainActivity extends WearableActivity implements ServiceConnection, }); } - private void setBpm(int bpm) { - if (isBound()) { - service.setBpm(bpm); - bpmView.setText(String.format(Locale.getDefault(), getString(R.string.bpm), String.valueOf(bpm))); - } + @Override + protected void onPause() { + super.onPause(); + isPlaying = false; } - private boolean isBound() { - return isBound && service != null; + @Override + protected void onDestroy() { + super.onDestroy(); + handler.removeCallbacks(this); + if (wakeLock != null) + wakeLock.release(); } @Override @@ -119,55 +180,15 @@ public class MainActivity extends WearableActivity implements ServiceConnection, } @Override - protected void onStart() { - Intent intent = new Intent(this, MetronomeService.class); - startService(intent); - bindService(intent, this, Context.BIND_AUTO_CREATE); - - super.onStart(); - } - - @Override - protected void onStop() { - if (isBound) { - unbindService(this); - isBound = false; + public void run() { + if (isPlaying) { + handler.postDelayed(this, interval); + + if (soundId != -1) + soundPool.play(soundId, 1.0f, 1.0f, 0, 0, 1.0f); + else if (Build.VERSION.SDK_INT >= 26) + vibrator.vibrate(VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE)); + else vibrator.vibrate(50); } - super.onStop(); - } - - @Override - public void onServiceConnected(ComponentName componentName, IBinder iBinder) { - MetronomeService.LocalBinder binder = (MetronomeService.LocalBinder) iBinder; - service = binder.getService(); - service.setTickListener(this); - isBound = true; - - if (vibrationView != null) - vibrationView.setImageResource(service.isVibration() ? R.drawable.ic_vibration : R.drawable.ic_sound); - - if (playView != null) - playView.setImageResource(service.isPlaying() ? R.drawable.ic_pause : R.drawable.ic_play); - - if (bpmView != null) - bpmView.setText(String.format(Locale.getDefault(), getString(R.string.bpm), String.valueOf(service.getBpm()))); - - if (seekBar != null) - seekBar.setProgress(service.getBpm()); - } - - @Override - public void onServiceDisconnected(ComponentName componentName) { - isBound = false; - } - - @Override - public void onStartTicks() { - playView.setImageResource(R.drawable.ic_pause); - } - - @Override - public void onStopTicks() { - playView.setImageResource(R.drawable.ic_play); } } diff --git a/wear/src/main/java/james/metronome/MetronomeService.java b/wear/src/main/java/james/metronome/MetronomeService.java deleted file mode 100644 index 58b6ff68d2cb2ea47b69a1812372eed7e63bc15f..0000000000000000000000000000000000000000 --- a/wear/src/main/java/james/metronome/MetronomeService.java +++ /dev/null @@ -1,195 +0,0 @@ -package james.metronome; - -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.media.AudioAttributes; -import android.media.AudioManager; -import android.media.SoundPool; -import android.os.Binder; -import android.os.Build; -import android.os.Handler; -import android.os.IBinder; -import android.os.VibrationEffect; -import android.os.Vibrator; -import android.preference.PreferenceManager; -import android.support.annotation.Nullable; -import android.support.v4.app.NotificationCompat; - -public class MetronomeService extends Service implements Runnable { - - public static final String ACTION_PAUSE = "james.metronome.ACTION_PAUSE"; - - public static final String PREF_VIBRATION = "vibration"; - public static final String PREF_INTERVAL = "interval"; - - private final IBinder binder = new LocalBinder(); - - private SharedPreferences prefs; - private int bpm; - private long interval; - - private SoundPool soundPool; - private Handler handler; - private int soundId = -1; - private boolean isPlaying; - private boolean isVibration; - - private Vibrator vibrator; - - private TickListener listener; - - @Override - public void onCreate() { - super.onCreate(); - prefs = PreferenceManager.getDefaultSharedPreferences(this); - - vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - soundPool = new SoundPool.Builder() - .setMaxStreams(1) - .setAudioAttributes(new AudioAttributes.Builder() - .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) - .build()) - .build(); - } else soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); - - isVibration = prefs.getBoolean(PREF_VIBRATION, true); - if (!isVibration) - soundId = soundPool.load(this, R.raw.click, 1); - - interval = prefs.getLong(PREF_INTERVAL, 500); - bpm = toBpm(interval); - - handler = new Handler(); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (intent != null && intent.getAction() != null) { - switch (intent.getAction()) { - case ACTION_PAUSE: - pause(); - } - } - return START_STICKY; - } - - private static int toBpm(long interval) { - return (int) (60000 / interval); - } - - private static long toInterval(int bpm) { - return (long) 60000 / bpm; - } - - public void play() { - handler.post(this); - isPlaying = true; - - Intent intent = new Intent(this, MetronomeService.class); - intent.setAction(ACTION_PAUSE); - - startForeground(530, - new NotificationCompat.Builder(this) - .setContentTitle(getString(R.string.notification_title)) - .setContentText(getString(R.string.notification_desc)) - .setSmallIcon(R.drawable.ic_notification) - .setContentIntent(PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)) - .build() - ); - - if (listener != null) - listener.onStartTicks(); - } - - public void pause() { - handler.removeCallbacks(this); - stopForeground(true); - isPlaying = false; - - if (listener != null) - listener.onStopTicks(); - } - - public void setBpm(int bpm) { - this.bpm = bpm; - interval = toInterval(bpm); - prefs.edit().putLong(PREF_INTERVAL, interval).apply(); - } - - public void setVibration(boolean vibration) { - isVibration = vibration; - if (!isVibration) - soundId = soundPool.load(this, R.raw.click, 1); - else soundId = -1; - - prefs.edit().putBoolean(PREF_VIBRATION, isVibration).apply(); - } - - public boolean isPlaying() { - return isPlaying; - } - - public long getInterval() { - return interval; - } - - public int getBpm() { - return bpm; - } - - public boolean isVibration() { - return isVibration; - } - - public void setTickListener(TickListener listener) { - this.listener = listener; - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - return binder; - } - - @Override - public boolean onUnbind(Intent intent) { - listener = null; - return super.onUnbind(intent); - } - - @Override - public void onDestroy() { - handler.removeCallbacks(this); - super.onDestroy(); - } - - @Override - public void run() { - if (isPlaying) { - if (soundId != -1) - soundPool.play(soundId, 1.0f, 1.0f, 0, 0, 1.0f); - else if (Build.VERSION.SDK_INT >= 26) - vibrator.vibrate(VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE)); - else vibrator.vibrate(50); - - handler.postDelayed(this, interval); - } - } - - public class LocalBinder extends Binder { - public MetronomeService getService() { - return MetronomeService.this; - } - } - - public interface TickListener { - void onStartTicks(); - - void onStopTicks(); - } -} diff --git a/wear/src/main/java/james/metronome/Utils.java b/wear/src/main/java/james/metronome/Utils.java new file mode 100644 index 0000000000000000000000000000000000000000..6b1667696cfa481dcb97da94e88f9c96d3560c1e --- /dev/null +++ b/wear/src/main/java/james/metronome/Utils.java @@ -0,0 +1,13 @@ +package james.metronome; + +public class Utils { + + public static int toBpm(long interval) { + return (int) (60000 / interval); + } + + public static long toInterval(int bpm) { + return (long) 60000 / bpm; + } + +} diff --git a/wear/src/main/res/drawable-hdpi/ic_notification.png b/wear/src/main/res/drawable-hdpi/ic_notification.png deleted file mode 100644 index 5a77d4c02144444e068075b823409fc127dec16a..0000000000000000000000000000000000000000 Binary files a/wear/src/main/res/drawable-hdpi/ic_notification.png and /dev/null differ diff --git a/wear/src/main/res/drawable-mdpi/ic_notification.png b/wear/src/main/res/drawable-mdpi/ic_notification.png deleted file mode 100644 index c51e577b62675d9e0fc723e26d1b7be4c3d44e9a..0000000000000000000000000000000000000000 Binary files a/wear/src/main/res/drawable-mdpi/ic_notification.png and /dev/null differ diff --git a/wear/src/main/res/drawable-xhdpi/ic_notification.png b/wear/src/main/res/drawable-xhdpi/ic_notification.png deleted file mode 100644 index 4aa838340e3c968258a954ee4b9f010dee54bc69..0000000000000000000000000000000000000000 Binary files a/wear/src/main/res/drawable-xhdpi/ic_notification.png and /dev/null differ diff --git a/wear/src/main/res/drawable-xxhdpi/ic_notification.png b/wear/src/main/res/drawable-xxhdpi/ic_notification.png deleted file mode 100644 index 7e46e5bdc1fe6f988b406caebf92836f39d266af..0000000000000000000000000000000000000000 Binary files a/wear/src/main/res/drawable-xxhdpi/ic_notification.png and /dev/null differ