// Copyright 2012 (C) Matthew Brejza // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. package com.brejza.matt.habmodem; import java.io.IOException; import java.util.List; import com.brejza.matt.habmodem.Dsp_service; import com.brejza.matt.habmodem.Dsp_service.LocalBinder; import rtty.fsk_receiver; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; import android.preference.PreferenceManager; import android.app.Activity; import android.app.DialogFragment; import android.app.FragmentManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.hardware.usb.UsbManager; import android.text.method.ScrollingMovementMethod; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class StatusScreen extends Activity implements AddPayloadFragment.NoticeDialogListener,LocationSelectFragment.NoticeDialogListener { // private AudioRecord mRecorder; // int buffsize; // boolean isRecording = false; // private Handler handler; // rtty_receiver rcv = new rtty_receiver(); // TextView t; ListView list; TextView txtchars; ImageView wfview; Menu _menu; // private GraphView graphView; // private GraphViewSeries viewseries; private StringRxReceiver strrxReceiver; private CharRxReceiver charrxReceiver; private FFTUpdateReceiver fftupdateReceiver; protected PowerManager.WakeLock mWakeLock; Dsp_service mService; boolean mBound = false; boolean isReg = false; boolean initList = false; ArrayAdapter<String> adapter; Waterfall wf; Handler handler; Handler handler2; int lastScrollLength = 0; final int txtViewLines = 15; ///////////////////// //////// MENU /////// ///////////////////// @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); _menu = menu; Boolean s = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("pref_test_enable", false); if (s == false){ MenuItem item = menu.findItem(R.id.btconnect_screen); item.setVisible(false); //this.invalidateOptionsMenu(); } if (mService != null){ if (mService.enableUploader) _menu.findItem(R.id.toggle_online).setChecked(true); } return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection Intent intent; if (item.getItemId() == R.id.status_screen) { return true; } else if (item.getItemId() == R.id.map_screen) { finish(); return true; } else if (item.getItemId() == R.id.location_dialog) { FragmentManager fm = getFragmentManager(); LocationSelectFragment di = new LocationSelectFragment(); di.enChase = mService.getEnableChase(); di.enPos = mService.getEnablePosition(); di.show(fm, "Location Settings"); return true; } else if (item.getItemId() == R.id.refresh_button) { mService.updateActivePayloadsHabitat(); return true; } else if (item.getItemId() == R.id.btconnect_screen) { if (Build.VERSION.SDK_INT >= 18){ intent = new Intent(this, BtScreen.class); startActivity(intent); }else{ Toast.makeText(this, "BTLE not supported on this device".toString(), Toast.LENGTH_SHORT).show(); } return true; } else if (item.getItemId() == R.id.graphs_button) { if ( mService.getActivePayloadList().size() > 0) { showGraphDialog(mService.getActivePayloadList().get(0)); }} else if (item.getItemId() == R.id.log_screen) { FragmentManager fm = getFragmentManager(); ViewLogFragment di = new ViewLogFragment(); di.setLogList(mService.getLog()); di.show(fm, "View Logs");} else if (item.getItemId() == R.id.settings_screen) { intent = new Intent(this,Preferences_activity.class); startActivity(intent); return true;} else if (item.getItemId() == R.id.toggle_online){ //CheckBox chk = (CheckBox) findViewById(R.id.toggle_online); if (mService.enableUploader){ mService.enableUploader = false; item.setChecked(false); }else{ mService.enableUploader = true; item.setChecked(true); } return true;} return super.onOptionsItemSelected(item); } protected void showGraphDialog(String call_startup) { List<String> ls = mService.getActivePayloadList(); if (ls.size() > 0){ FragmentManager fm = getFragmentManager(); GraphsFragment di = new GraphsFragment(); di.setStartCall(call_startup); di.setActivePayloads(ls,mService.getPayloadList()); di.show(fm, "View Graphs"); } } ///////////////////// ////// BUTTONS ////// ///////////////////// ///////////////////// ///// LIFECYCLE ///// ///////////////////// @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_status_screen); PreferenceManager.setDefaultValues(this, R.xml.preferences, false); handler = new Handler(); handler2 = new Handler(); // rcv.addStringRecievedListener(this); // handler = new Handler(); // t = (TextView)findViewById(R.id.txttest); wfview = (ImageView)findViewById(R.id.imgViWF); // list = (ListView)findViewById(R.id.listRxDecodedStrings); txtchars = (TextView)findViewById(R.id.txtRawRxChars); // txtchars.setEnabled(false); initGraph(); wf = new Waterfall(BitmapFactory.decodeResource(this.getResources(), R.drawable.grad), 200); txtchars.setMovementMethod(ScrollingMovementMethod.getInstance()); } @Override protected void onStart() { super.onStart(); // // Bind to LocalService // Intent intent = new Intent(this, Dsp_service.class); // startService(intent); // Bind to LocalService Intent intent = new Intent(this, Dsp_service.class); //bindService(intent, mConnection, Context.BIND_AUTO_CREATE); startService(intent); // mBound = true; } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } } @Override public void onResume() { super.onResume(); // Bind to LocalService if (!mBound){ Intent intent = new Intent(this, Dsp_service.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } if (mService != null && _menu != null){ if (mService.enableUploader) _menu.findItem(R.id.toggle_online).setChecked(true); } //string receiver if (strrxReceiver == null) strrxReceiver = new StringRxReceiver(); IntentFilter intentFilter1 = new IntentFilter(Dsp_service.TELEM_RX); if (!isReg) { registerReceiver(strrxReceiver, intentFilter1); } //char receiver if (charrxReceiver == null) charrxReceiver = new CharRxReceiver(); IntentFilter intentFilter2 = new IntentFilter(Dsp_service.CHAR_RX); if (!isReg) { registerReceiver(charrxReceiver, intentFilter2); } //fftreceiver if (fftupdateReceiver == null) fftupdateReceiver = new FFTUpdateReceiver(); IntentFilter intentFilter3 = new IntentFilter(Dsp_service.FFT_UPDATED); if (!isReg) { registerReceiver(fftupdateReceiver, intentFilter3); } isReg = true; //boolean mic = this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE); //if (mic) // Toast.makeText(this, "MIC AVAILABLE", Toast.LENGTH_LONG).show(); //else // Toast.makeText(this, "MIC NOT AVAILABLE :o", Toast.LENGTH_LONG).show(); Boolean s = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("pref_keep_screen", true); //Toast.makeText(this, s.toString(), Toast.LENGTH_LONG).show(); if (s){ final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag"); mWakeLock.acquire(); } } @Override public void onPause(){ super.onPause(); if (isReg) { if (strrxReceiver != null) unregisterReceiver(strrxReceiver); if (charrxReceiver != null) unregisterReceiver(charrxReceiver); if (fftupdateReceiver != null) unregisterReceiver(fftupdateReceiver); } isReg = false; if (mService != null) { mService.rcv.enableFFT = false; if (mWakeLock != null){ try{ this.mWakeLock.release(); } catch(Throwable th) { mService.logEvent("Warning, code 01.2",false); } } } // if (mBound) { // unbindService(mConnection); // mBound = false; // } } /////////////// public void updateListView() { if (mService.listRxStr == null) return; if (mService.listRxStr.size() < 1) return; handler2.post(new Runnable() { @Override public void run() { if (!initList) { list = (ListView) findViewById(R.id.listRxDecodedStrings); initAdapter(); // Assign adapter to ListView list.setAdapter(adapter); list.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); initList = true; } else adapter.notifyDataSetChanged(); } }); } private void initGraph() { /* // draw sin curve int num = 150; GraphViewData[] data = new GraphViewData[num]; double v=0; for (int i=0; i<num; i++) { v += 0.2; data[i] = new GraphViewData(i, Math.sin(v)); } GraphView graphView = new LineGraphView( this , "GraphViewDemo" ); // add data viewseries = new GraphViewSeries(data); graphView.addSeries(viewseries); // graphView.setScrollable(false); // optional - activate scaling / zooming graphView.setScalable(true); LinearLayout layout = (LinearLayout) findViewById(R.id.llgraph); layout.addView(graphView); */ /* exampleSeries1 = new GraphViewSeries(new GraphViewData[] { new GraphViewData(1, 2.0d) , new GraphViewData(2, 1.5d) , new GraphViewData(2.5, 3.0d) // another frequency , new GraphViewData(3, 2.5d) , new GraphViewData(4, 1.0d) , new GraphViewData(5, 3.0d) }); // graph with dynamically genereated horizontal and vertical labels GraphView graphView = new LineGraphView( this // context , "GraphViewDemo" // heading ); graphView.addSeries(exampleSeries1); // data LinearLayout layout = (LinearLayout) findViewById(R.id.graph1); layout.addView(graphView); */ } /* private void showFFT() { GraphViewData[] data = new GraphViewData[FFT_half_len]; for (int i = 0; i < FFT_half_len; i++) { data[i] = new GraphViewData(i,10 * Math.log10(mService.getFFT(i))); } LinearLayout layout = (LinearLayout) findViewById(R.id.llgraph); layout.removeAllViewsInLayout(); GraphView graphView = new LineGraphView( this , "GraphViewDemo" ); graphView.addSeries(new GraphViewSeries(data)); layout.addView(graphView); } */ /** Defines callbacks for service binding, passed to bindService() */ private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to LocalService, cast the IBinder and get LocalService instance LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; mService.rcv.enableFFT = true; if (mService.enableUploader && _menu != null) _menu.findItem(R.id.toggle_online).setChecked(true); setBaudButton(); updateListView(); refreshButtons(); } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; private void initAdapter() { adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, mService.listRxStr); } private class StringRxReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Dsp_service.TELEM_RX)) { //Do stuff System.out.println("GOT INTENT telem"); // list.add updateListView(); } } } private class CharRxReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Dsp_service.CHAR_RX)) { //Do stuff String ch = intent.getStringExtra(Dsp_service.CHARS); // System.out.println(ch); try { txtchars.append(ch); final int scrollAmount = txtchars.getLayout().getLineTop(txtchars.getLineCount()) -txtchars.getHeight(); int currentpos = txtchars.getLayout().getLineTop(Math.max(0,txtchars.getLineCount() - txtViewLines)); boolean enScroll = (txtchars.getScrollY() + 20 > currentpos); if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) < Configuration.SCREENLAYOUT_SIZE_LARGE) enScroll = true; // if there is no need to scroll, scrollAmount will be <=0 if(scrollAmount>0 && (lastScrollLength < txtchars.getLineCount()) && enScroll) txtchars.scrollTo(0, scrollAmount); // else // txtchars.scrollTo(0,0); lastScrollLength = txtchars.getLineCount(); } catch (Exception e) { } } } } private class FFTUpdateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Dsp_service.FFT_UPDATED)) { //TODO: HERE Bitmap img = wf.updateLine(mService.getFFT(),mService.get_f1_FFTbin(),mService.get_f2_FFTbin()); if (img != null){ wfview.setImageBitmap(img); wfview.invalidate(); } //tdata.setTe handler.post(new Runnable() { @Override public void run() { TextView tdata = (TextView) findViewById(R.id.txtDataBits); TextView tstops = (TextView) findViewById(R.id.txtStopBits); TextView tstat = (TextView) findViewById(R.id.txtStatus); if (mService.rcv.paramsValid()){ tdata.setText(Integer.toString(mService.rcv.current_data_bits)); tstops.setText(Integer.toString(mService.rcv.current_stop_bits)); }else{ tdata.setText("-"); tstops.setText("-"); } if (mService.getDecoderRunning()) tstat.setText(mService.rcv.statusToString()); else tstat.setText("Paused"); } }); } } } public void setBaud(View view) { int currentBaud = mService.getBaud(); if (currentBaud == 300) mService.setBaud(50); else if (currentBaud == 50) mService.setBaud(100); else if (currentBaud == 100) mService.setBaud(150); else //if (currentBaud == 150) mService.setBaud(300); setBaudButton(); } public void toggleEcho(View view) { if (mService.getEchoEnabled()) mService.disableEcho(); else mService.enableEcho(); refreshButtons(); //delete later //PredictionGrabber pg = new PredictionGrabber(this.getApplicationContext(),"http://users.ecs.soton.ac.uk/mfb2g09/get_predictions.php.htm"); //pg.getPredictions(); } public void toggleBell(View view) { if (mService.enableBell) mService.enableBell = false; else mService.enableBell = true; refreshButtons(); } public void toggleConnected(View view) { if (mService.enableUploader) mService.enableUploader = false; else mService.enableUploader = true; refreshButtons(); } public void toggleBinary(View view) { if (mService.rcv.current_mode == fsk_receiver.Mode.BINARY) mService.rcv.setMode(fsk_receiver.Mode.RTTY); else mService.rcv.setMode(fsk_receiver.Mode.BINARY); refreshButtons(); } public void toggleAfsk(View view) { // Get UsbManager from Android. UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); if (mService.rcv.current_modulation == fsk_receiver.Modulation.AFSK) mService.rcv.setModulation(fsk_receiver.Modulation.FSK); else{ mService.rcv.setModulation(fsk_receiver.Modulation.AFSK); mService.rcv.setFreq(500,750); } refreshButtons(); } public void toggleRunning(View view) { if (mService.getDecoderRunning()){ mService.disableDecoder(); TextView tstat = (TextView) findViewById(R.id.txtStatus); tstat.setText("Paused"); } else mService.enableDecoder(); refreshButtons(); } private void refreshButtons() { Button btnafsk = (Button) findViewById(R.id.btnAfsk); ImageButton btnecho = (ImageButton) findViewById(R.id.btnEcho); Button btnbin = (Button) findViewById(R.id.btnBinary); ImageButton btnplay = (ImageButton) findViewById(R.id.btnRunning); MenuItem chk = (MenuItem) findViewById(R.id.toggle_online); //if (mService.enableBell) // btnbell.setImageResource(R.drawable.ic_action_bell_on); //else // btnbell.setImageResource(R.drawable.ic_action_bell_off); if (mService.getEchoEnabled()) btnecho.setImageResource(R.drawable.ic_action_echo_on); else btnecho.setImageResource(R.drawable.ic_action_echo_off); //if (mService.enableUploader) // btnconn.setImageResource(R.drawable.ic_action_connected); //else // btnconn.setImageResource(R.drawable.ic_action_disconnected); if (mService.rcv.current_modulation == fsk_receiver.Modulation.AFSK) btnafsk.setText("FM"); else btnafsk.setText("SSB"); if (mService.rcv.current_mode == fsk_receiver.Mode.RTTY) btnbin.setText("RTTY"); else btnbin.setText("BIN"); if (mService.getDecoderRunning()) btnplay.setImageResource(R.drawable.ic_action_play); else btnplay.setImageResource(R.drawable.ic_action_pause); TextView tdata = (TextView) findViewById(R.id.txtDataBits); TextView tstops = (TextView) findViewById(R.id.txtStopBits); TextView tstat = (TextView) findViewById(R.id.txtStatus); if (mService.rcv.paramsValid()){ tdata.setText(Integer.toString(mService.rcv.current_data_bits)); tstops.setText(Integer.toString(mService.rcv.current_stop_bits)); }else{ tdata.setText("-"); tstops.setText("-"); } if (mService.getDecoderRunning()) tstat.setText(mService.rcv.statusToString()); else tstat.setText("Paused"); } private void setBaudButton() { Button btn = (Button) findViewById(R.id.btnBaud); btn.setText(Integer.toString(mService.getBaud())); //mService.StringRx("$$XABEN1,346,13:22:10,52.06253,-0.37046,14708*5B3F", true); } @Override public void onDialogPositiveClick(DialogFragment dialog, boolean enPos, boolean enChase) { mService.changeLocationSettings(enPos,enChase); } @Override public void onDialogPositiveClick(DialogFragment dialog, String callsign, int lookBehind) { // TODO Auto-generated method stub mService.addActivePayload(callsign,lookBehind); Balloon_data_fragment fragment = (Balloon_data_fragment) getFragmentManager().findFragmentById(R.id.balloon_data_holder); fragment.AddPayload(callsign,mService.getPayloadColour(callsign)); mService.updateActivePayloadsHabitat(); } }