1*90c8c64dSAndroid Build Coastguard Worker /*
2*90c8c64dSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*90c8c64dSAndroid Build Coastguard Worker  *
4*90c8c64dSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*90c8c64dSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*90c8c64dSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*90c8c64dSAndroid Build Coastguard Worker  *
8*90c8c64dSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*90c8c64dSAndroid Build Coastguard Worker  *
10*90c8c64dSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*90c8c64dSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*90c8c64dSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*90c8c64dSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*90c8c64dSAndroid Build Coastguard Worker  * limitations under the License.
15*90c8c64dSAndroid Build Coastguard Worker  */
16*90c8c64dSAndroid Build Coastguard Worker 
17*90c8c64dSAndroid Build Coastguard Worker package com.example.android.midisynth;
18*90c8c64dSAndroid Build Coastguard Worker 
19*90c8c64dSAndroid Build Coastguard Worker import android.app.ActionBar;
20*90c8c64dSAndroid Build Coastguard Worker import android.app.Activity;
21*90c8c64dSAndroid Build Coastguard Worker import android.content.pm.PackageManager;
22*90c8c64dSAndroid Build Coastguard Worker import android.media.midi.MidiDevice.MidiConnection;
23*90c8c64dSAndroid Build Coastguard Worker import android.media.midi.MidiDeviceInfo;
24*90c8c64dSAndroid Build Coastguard Worker import android.media.midi.MidiManager;
25*90c8c64dSAndroid Build Coastguard Worker import android.os.Bundle;
26*90c8c64dSAndroid Build Coastguard Worker import android.view.Menu;
27*90c8c64dSAndroid Build Coastguard Worker import android.view.MenuItem;
28*90c8c64dSAndroid Build Coastguard Worker import android.view.WindowManager;
29*90c8c64dSAndroid Build Coastguard Worker import android.widget.Toast;
30*90c8c64dSAndroid Build Coastguard Worker import android.widget.Toolbar;
31*90c8c64dSAndroid Build Coastguard Worker 
32*90c8c64dSAndroid Build Coastguard Worker import com.example.android.common.midi.MidiOutputPortConnectionSelector;
33*90c8c64dSAndroid Build Coastguard Worker import com.example.android.common.midi.MidiPortConnector;
34*90c8c64dSAndroid Build Coastguard Worker import com.example.android.common.midi.MidiTools;
35*90c8c64dSAndroid Build Coastguard Worker 
36*90c8c64dSAndroid Build Coastguard Worker /**
37*90c8c64dSAndroid Build Coastguard Worker  * Simple synthesizer as a MIDI Device.
38*90c8c64dSAndroid Build Coastguard Worker  */
39*90c8c64dSAndroid Build Coastguard Worker public class MainActivity extends Activity {
40*90c8c64dSAndroid Build Coastguard Worker     static final String TAG = "MidiSynthExample";
41*90c8c64dSAndroid Build Coastguard Worker 
42*90c8c64dSAndroid Build Coastguard Worker     private MidiManager mMidiManager;
43*90c8c64dSAndroid Build Coastguard Worker     private MidiOutputPortConnectionSelector mPortSelector;
44*90c8c64dSAndroid Build Coastguard Worker 
45*90c8c64dSAndroid Build Coastguard Worker     @Override
onCreate(Bundle savedInstanceState)46*90c8c64dSAndroid Build Coastguard Worker     public void onCreate(Bundle savedInstanceState) {
47*90c8c64dSAndroid Build Coastguard Worker         super.onCreate(savedInstanceState);
48*90c8c64dSAndroid Build Coastguard Worker         setContentView(R.layout.main);
49*90c8c64dSAndroid Build Coastguard Worker         setActionBar((Toolbar) findViewById(R.id.toolbar));
50*90c8c64dSAndroid Build Coastguard Worker         ActionBar actionBar = getActionBar();
51*90c8c64dSAndroid Build Coastguard Worker         if (actionBar != null) {
52*90c8c64dSAndroid Build Coastguard Worker             actionBar.setDisplayShowTitleEnabled(false);
53*90c8c64dSAndroid Build Coastguard Worker         }
54*90c8c64dSAndroid Build Coastguard Worker 
55*90c8c64dSAndroid Build Coastguard Worker         if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI)) {
56*90c8c64dSAndroid Build Coastguard Worker             setupMidi();
57*90c8c64dSAndroid Build Coastguard Worker         }
58*90c8c64dSAndroid Build Coastguard Worker     }
59*90c8c64dSAndroid Build Coastguard Worker 
60*90c8c64dSAndroid Build Coastguard Worker     @Override
onCreateOptionsMenu(Menu menu)61*90c8c64dSAndroid Build Coastguard Worker     public boolean onCreateOptionsMenu(Menu menu) {
62*90c8c64dSAndroid Build Coastguard Worker         getMenuInflater().inflate(R.menu.main, menu);
63*90c8c64dSAndroid Build Coastguard Worker         setKeepScreenOn(menu.findItem(R.id.action_keep_screen_on).isChecked());
64*90c8c64dSAndroid Build Coastguard Worker         return true;
65*90c8c64dSAndroid Build Coastguard Worker     }
66*90c8c64dSAndroid Build Coastguard Worker 
67*90c8c64dSAndroid Build Coastguard Worker     @Override
onOptionsItemSelected(MenuItem item)68*90c8c64dSAndroid Build Coastguard Worker     public boolean onOptionsItemSelected(MenuItem item) {
69*90c8c64dSAndroid Build Coastguard Worker         switch (item.getItemId()) {
70*90c8c64dSAndroid Build Coastguard Worker             case R.id.action_keep_screen_on:
71*90c8c64dSAndroid Build Coastguard Worker                 boolean checked = !item.isChecked();
72*90c8c64dSAndroid Build Coastguard Worker                 setKeepScreenOn(checked);
73*90c8c64dSAndroid Build Coastguard Worker                 item.setChecked(checked);
74*90c8c64dSAndroid Build Coastguard Worker                 break;
75*90c8c64dSAndroid Build Coastguard Worker         }
76*90c8c64dSAndroid Build Coastguard Worker         return super.onOptionsItemSelected(item);
77*90c8c64dSAndroid Build Coastguard Worker     }
78*90c8c64dSAndroid Build Coastguard Worker 
setKeepScreenOn(boolean keepScreenOn)79*90c8c64dSAndroid Build Coastguard Worker     private void setKeepScreenOn(boolean keepScreenOn) {
80*90c8c64dSAndroid Build Coastguard Worker         if (keepScreenOn) {
81*90c8c64dSAndroid Build Coastguard Worker             getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
82*90c8c64dSAndroid Build Coastguard Worker         } else {
83*90c8c64dSAndroid Build Coastguard Worker             getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
84*90c8c64dSAndroid Build Coastguard Worker         }
85*90c8c64dSAndroid Build Coastguard Worker     }
86*90c8c64dSAndroid Build Coastguard Worker 
setupMidi()87*90c8c64dSAndroid Build Coastguard Worker     private void setupMidi() {
88*90c8c64dSAndroid Build Coastguard Worker         // Setup MIDI
89*90c8c64dSAndroid Build Coastguard Worker         mMidiManager = (MidiManager) getSystemService(MIDI_SERVICE);
90*90c8c64dSAndroid Build Coastguard Worker 
91*90c8c64dSAndroid Build Coastguard Worker         MidiDeviceInfo synthInfo = MidiTools.findDevice(mMidiManager, "AndroidTest",
92*90c8c64dSAndroid Build Coastguard Worker                 "SynthExample");
93*90c8c64dSAndroid Build Coastguard Worker         int portIndex = 0;
94*90c8c64dSAndroid Build Coastguard Worker         mPortSelector = new MidiOutputPortConnectionSelector(mMidiManager, this,
95*90c8c64dSAndroid Build Coastguard Worker                 R.id.spinner_synth_sender, synthInfo, portIndex);
96*90c8c64dSAndroid Build Coastguard Worker         mPortSelector.setConnectedListener(new MyPortsConnectedListener());
97*90c8c64dSAndroid Build Coastguard Worker     }
98*90c8c64dSAndroid Build Coastguard Worker 
closeSynthResources()99*90c8c64dSAndroid Build Coastguard Worker     private void closeSynthResources() {
100*90c8c64dSAndroid Build Coastguard Worker         if (mPortSelector != null) {
101*90c8c64dSAndroid Build Coastguard Worker             mPortSelector.close();
102*90c8c64dSAndroid Build Coastguard Worker         }
103*90c8c64dSAndroid Build Coastguard Worker     }
104*90c8c64dSAndroid Build Coastguard Worker 
105*90c8c64dSAndroid Build Coastguard Worker     // TODO A better way would be to listen to the synth server
106*90c8c64dSAndroid Build Coastguard Worker     // for open/close events and then disable/enable the spinner.
107*90c8c64dSAndroid Build Coastguard Worker     private class MyPortsConnectedListener
108*90c8c64dSAndroid Build Coastguard Worker             implements MidiPortConnector.OnPortsConnectedListener {
109*90c8c64dSAndroid Build Coastguard Worker         @Override
onPortsConnected(final MidiConnection connection)110*90c8c64dSAndroid Build Coastguard Worker         public void onPortsConnected(final MidiConnection connection) {
111*90c8c64dSAndroid Build Coastguard Worker             runOnUiThread(new Runnable() {
112*90c8c64dSAndroid Build Coastguard Worker                 @Override
113*90c8c64dSAndroid Build Coastguard Worker                 public void run() {
114*90c8c64dSAndroid Build Coastguard Worker                     if (connection == null) {
115*90c8c64dSAndroid Build Coastguard Worker                         Toast.makeText(MainActivity.this,
116*90c8c64dSAndroid Build Coastguard Worker                                 R.string.error_port_busy, Toast.LENGTH_SHORT)
117*90c8c64dSAndroid Build Coastguard Worker                                 .show();
118*90c8c64dSAndroid Build Coastguard Worker                         mPortSelector.clearSelection();
119*90c8c64dSAndroid Build Coastguard Worker                     } else {
120*90c8c64dSAndroid Build Coastguard Worker                         Toast.makeText(MainActivity.this,
121*90c8c64dSAndroid Build Coastguard Worker                                 R.string.port_open_ok, Toast.LENGTH_SHORT)
122*90c8c64dSAndroid Build Coastguard Worker                                 .show();
123*90c8c64dSAndroid Build Coastguard Worker                     }
124*90c8c64dSAndroid Build Coastguard Worker                 }
125*90c8c64dSAndroid Build Coastguard Worker             });
126*90c8c64dSAndroid Build Coastguard Worker         }
127*90c8c64dSAndroid Build Coastguard Worker     }
128*90c8c64dSAndroid Build Coastguard Worker 
129*90c8c64dSAndroid Build Coastguard Worker     @Override
onDestroy()130*90c8c64dSAndroid Build Coastguard Worker     public void onDestroy() {
131*90c8c64dSAndroid Build Coastguard Worker         closeSynthResources();
132*90c8c64dSAndroid Build Coastguard Worker         super.onDestroy();
133*90c8c64dSAndroid Build Coastguard Worker     }
134*90c8c64dSAndroid Build Coastguard Worker 
135*90c8c64dSAndroid Build Coastguard Worker }
136