de.tu.darmstadt.seemoo.ansian.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for de.tu.darmstadt.seemoo.ansian.MainActivity.java

Source

package de.tu.darmstadt.seemoo.ansian;

import java.io.File;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
import de.greenrobot.event.EventBus;
import de.greenrobot.event.Subscribe;
import de.tu.darmstadt.seemoo.ansian.control.DataHandler;
import de.tu.darmstadt.seemoo.ansian.control.SourceControl;
import de.tu.darmstadt.seemoo.ansian.control.StateHandler;
import de.tu.darmstadt.seemoo.ansian.control.events.DemodulationEvent;
import de.tu.darmstadt.seemoo.ansian.control.events.tx.image.sstv.ImagePickIntentResultEvent;
import de.tu.darmstadt.seemoo.ansian.gui.misc.AnsianNotification;
import de.tu.darmstadt.seemoo.ansian.gui.misc.MyToast;
import de.tu.darmstadt.seemoo.ansian.gui.tabs.MainActivityPagerAdapter;
import de.tu.darmstadt.seemoo.ansian.gui.tabs.MyViewPager;
import de.tu.darmstadt.seemoo.ansian.gui.tabs.SlidingTabLayout;
import de.tu.darmstadt.seemoo.ansian.gui.views.SSTVView;
import de.tu.darmstadt.seemoo.ansian.model.Logger;
import de.tu.darmstadt.seemoo.ansian.model.demodulation.Demodulation.DemoType;
import de.tu.darmstadt.seemoo.ansian.model.preferences.Preferences;
import de.tu.darmstadt.seemoo.ansian.model.sources.RtlsdrSource;
import de.tu.darmstadt.seemoo.ansian.model.sources.SDRplaySource;
import de.tu.darmstadt.seemoo.ansian.model.transmission.TransmissionChain;

/**
 * <h1>AnSiAn - Main Activity</h1>
 *
 * Module: MainActivity.java Description: Main Activity of AnSiAn
 *
 * @author Dennis Mantz
 * @author Markus Grau
 * @author Steffen Kreis
 *
 *         Copyright (C) 2014 Dennis Mantz License:
 *         http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
 *
 *         This library 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 2 of the License, or (at
 *         your option) any later version.
 *
 *         This library 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.
 *
 *         You should have received a copy of the GNU General Public License
 *         along with this library; if not, write to the Free Software
 *         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 *         02110-1301 USA
 */
public class MainActivity extends AppCompatActivity {

    public static MainActivity instance;
    public Process logcat = null;

    private StateHandler stateHandler;
    public static AnsianNotification notification;
    private MyViewPager viewPager;
    private SlidingTabLayout slidingTabLayout;
    public static final String LOGTAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        EventBus.getDefault().register(this);
        super.onCreate(savedInstanceState);
        instance = this;

        // init all prefs
        new Preferences(this);

        // enable logging of demodulated text
        new Logger();

        // TODO: move somewhere more sensible
        new TransmissionChain();

        // Set view for this activity
        setContentView(R.layout.activity_main);

        // ViewPager and its adapters use support library
        // fragments, so use getSupportFragmentManager.
        // Get the ViewPager and set it's PagerAdapter so that it can display
        // items
        viewPager = (MyViewPager) findViewById(R.id.viewpager);
        MainActivityPagerAdapter pagerAdapter = new MainActivityPagerAdapter(getSupportFragmentManager(), viewPager,
                this);
        viewPager.setAdapter(pagerAdapter);
        viewPager.setCurrentItem(1);

        // Make sure the DataHandler instance is created in order for it to catch the new-source-event
        DataHandler.getInstance();

        // Give the SlidingTabLayout the ViewPager
        slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
        // Center the tabs in the layout
        slidingTabLayout.setDistributeEvenly(true);
        slidingTabLayout.setViewPager(viewPager);
        stateHandler = StateHandler.getInstance();
        stateHandler.start(Preferences.MISC_PREFERENCE.isAutostart());

        // Set the hardware volume keys to work on the music audio stream:
        setVolumeControlStream(AudioManager.STREAM_MUSIC);

        // Start logging if enabled:
        if (Preferences.MISC_PREFERENCE.isLogging()) {
            try {
                File logfile = Preferences.MISC_PREFERENCE.getLogFile();
                logfile.getParentFile().mkdir(); // Create folder
                logcat = Runtime.getRuntime().exec("logcat -f " + logfile);
                Log.i("MainActivity", "onCreate: started logcat (" + logcat.toString() + ") to " + logfile);
            } catch (Exception e) {
                Log.e("MainActivity", "onCreate: Failed to start logging!");
            }
        }

        // Notification
        notification = new AnsianNotification(this);
        // TODO: move that to a better location. only execute when mic is needed
        Log.d(LOGTAG,
                "permission_on_micro=" + ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO));
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[] { Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE },
                    0);
        }

        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
        }

    }

    @Override
    protected void onDestroy() {
        Preferences.saveAll();
        // stop logging:
        if (logcat != null) {
            try {
                logcat.destroy();
                logcat.waitFor();
                Log.i(LOGTAG, "onDestroy: logcat exit value: " + logcat.exitValue());
            } catch (Exception e) {
                Log.e(LOGTAG, "onDestroy: couldn't stop logcat: " + e.getMessage());
            }
        }
        notification.destroy();
        super.onDestroy();
    }

    @Override
    protected void onStart() {
        // show/hide tabs if desired
        if (Preferences.GUI_PREFERENCE.isTabsHide())
            slidingTabLayout.setVisibility(View.GONE);
        else
            slidingTabLayout.setVisibility(View.VISIBLE);
        // show/hide demodulation info text, depending on current demod type
        if (StateHandler.getActiveDemodulationMode() == DemoType.MORSE
                || (StateHandler.getActiveDemodulationMode() == DemoType.WFM
                        && Preferences.DEMOD_PREFERENCE.isFmRDS())
                || (StateHandler.getActiveDemodulationMode() == DemoType.USB
                        && Preferences.DEMOD_PREFERENCE.isUsbPSK31())) {
            findViewById(R.id.demodulationInfoView).setVisibility(View.VISIBLE);
        } else {
            findViewById(R.id.demodulationInfoView).setVisibility(View.GONE);
        }

        super.onStart();
    }

    @Override
    public void onBackPressed() {
        if (StateHandler.isStopped())
            super.onBackPressed();
        else
            moveTaskToBack(true);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        Intent intentShowSettings = new Intent(MainActivity.instance.getApplicationContext(),
                SettingsActivity.class);
        MainActivity.instance.startActivity(intentShowSettings);
        return false;
    }

    @Override
    protected void onPause() {
        if (!StateHandler.isStopped())
            MyToast.makeText("AnSiAn service will continue running in background!", Toast.LENGTH_SHORT);
        super.onPause();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(LOGTAG, "onActivityResult");
        // err_info from RTL2832U:
        String[] rtlsdrErrInfo = { "permission_denied", "root_required", "no_devices_found", "unknown_error",
                "replug", "already_running" };

        switch (requestCode) {
        case SourceControl.RTL2832U_RESULT_CODE:
            // This happens if the RTL2832U driver was started.
            // We check for errors and print them:
            if (resultCode == RESULT_OK)
                Log.i(LOGTAG, "onActivityResult: RTL2832U driver was successfully started.");
            else {
                int errorId = -1;
                int exceptionCode = 0;
                String detailedDescription = null;
                if (data != null) {
                    errorId = data.getIntExtra("marto.rtl_tcp_andro.RtlTcpExceptionId", -1);
                    exceptionCode = data.getIntExtra("detailed_exception_code", 0);
                    detailedDescription = data.getStringExtra("detailed_exception_message");
                }
                String errorMsg = "ERROR NOT SPECIFIED";
                if (errorId >= 0 && errorId < rtlsdrErrInfo.length)
                    errorMsg = rtlsdrErrInfo[errorId];

                Log.e(LOGTAG,
                        "onActivityResult: RTL2832U driver returned with error: " + errorMsg + " (" + errorId + ")"
                                + (detailedDescription != null
                                        ? ": " + detailedDescription + " (" + exceptionCode + ")"
                                        : ""));

                SourceControl.getInstance();
                SourceControl.getInstance();
                if (SourceControl.getSource() != null && SourceControl.getSource() instanceof RtlsdrSource) {
                    SourceControl.getInstance();
                    Toast.makeText(MainActivity.this,
                            "Error with Source [" + SourceControl.getSource().getName() + "]: " + errorMsg + " ("
                                    + errorId + ")"
                                    + (detailedDescription != null
                                            ? ": " + detailedDescription + " (" + exceptionCode + ")"
                                            : ""),
                            Toast.LENGTH_LONG).show();
                    SourceControl.getInstance();
                    SourceControl.getSource().close();
                }
            }
            break;
        case SourceControl.SDRPLAY_RESULT_CODE:
            // This happens if the SDRplay driver was started.
            // We check for errors and print them:
            if (resultCode == -1) // SDRplay driver returns -1 on success (not standard conform)
                Log.i(LOGTAG, "onActivityResult: SDRplay driver was successfully started.");
            else {
                int errorId = -1;
                int exceptionCode = 0;
                String detailedDescription = null;
                if (data != null) {
                    errorId = data.getIntExtra("marto.rtl_tcp_andro.RtlTcpExceptionId", -1);
                    exceptionCode = data.getIntExtra("detailed_exception_code", 0);
                    detailedDescription = data.getStringExtra("detailed_exception_message");
                }
                String errorMsg = "ERROR NOT SPECIFIED";
                if (errorId >= 0 && errorId < rtlsdrErrInfo.length)
                    errorMsg = rtlsdrErrInfo[errorId];

                Log.e(LOGTAG,
                        "onActivityResult: SDRplay driver returned with error: " + errorMsg + " (" + errorId + ")"
                                + (detailedDescription != null
                                        ? ": " + detailedDescription + " (" + exceptionCode + ")"
                                        : ""));

                SourceControl.getInstance();
                SourceControl.getInstance();
                if (SourceControl.getSource() != null && SourceControl.getSource() instanceof SDRplaySource) {
                    SourceControl.getInstance();
                    Toast.makeText(MainActivity.this,
                            "Error with Source [" + SourceControl.getSource().getName() + "]: " + errorMsg + " ("
                                    + errorId + ")"
                                    + (detailedDescription != null
                                            ? ": " + detailedDescription + " (" + exceptionCode + ")"
                                            : ""),
                            Toast.LENGTH_LONG).show();
                    SourceControl.getInstance();
                    SourceControl.getSource().close();
                }
            }
            break;

        case SSTVView.IMAGE_PICKER_INTENT_RESULT_CODE:
            if (resultCode == RESULT_OK) {
                Uri imageUri = data.getData();
                EventBus.getDefault().post(new ImagePickIntentResultEvent(imageUri));
            }

        }
    }

    /**
     * Set visibility for demodulation info text
     */
    @Subscribe
    public void onEvent(final DemodulationEvent event) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (event.getDemodulation() == DemoType.MORSE
                        || (event.getDemodulation() == DemoType.WFM && Preferences.DEMOD_PREFERENCE.isFmRDS())
                        || (event.getDemodulation() == DemoType.USB && Preferences.DEMOD_PREFERENCE.isUsbPSK31())) {
                    findViewById(R.id.demodulationInfoView).setVisibility(View.VISIBLE);
                } else {
                    findViewById(R.id.demodulationInfoView).setVisibility(View.GONE);
                }
            }
        });
    }

    public MyViewPager getViewPager() {
        return viewPager;
    }

}