Android Open Source - security-cam Main Activity






From Project

Back to project page security-cam.

License

The source code is released under:

MIT License

If you think the Android project security-cam listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package berlin.reiche.securitas.activities;
//  w w w .  ja  v  a2  s . c o m
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import berlin.reiche.securitas.Client;
import berlin.reiche.securitas.R;
import berlin.reiche.securitas.controller.ClientController;
import berlin.reiche.securitas.controller.GCMIntentService;
import berlin.reiche.securitas.controller.states.DetectionState;
import berlin.reiche.securitas.model.ClientModel;
import berlin.reiche.securitas.model.ClientModel.State;
import berlin.reiche.securitas.util.NotificationDialog;

import com.google.android.gcm.GCMRegistrar;

/**
 * Activity used to remote control the server and display snapshots. This class
 * implements the {@link Callback} interface in order to handle requests sent
 * from the controller for updating the interface.
 * 
 * @author Konrad Reiche
 * 
 */
public class MainActivity extends Activity implements Callback {

  /**
   * Tag for logging.
   */
  private static String TAG = MainActivity.class.getSimpleName();

  /**
   * Specific client controller which is used to make requests.
   */
  ClientController controller;

  /**
   * This {@link ImageView} will display the latest snapshot or the snapshot
   * that triggered an motion detection.
   */
  public ImageView snapshot;

  /**
   * The same button is used for starting and stopping the motion detection on
   * the backend.
   */
  public Button detectionToggle;

  /**
   * The layout for this activity.
   */
  private RelativeLayout layout;

  /**
   * Separate layout for the layout.
   */
  public RelativeLayout snapshotArea;

  /**
   * Progress bar for displaying progress.
   */
  public ProgressBar progress;

  /**
   * Headline title.
   */
  public TextView headline;

  /**
   * Headline subtitle.
   */
  public TextView subtitle;

  /**
   * Whether all components are initialized and can be referenced.
   */
  private boolean initialized;

  /**
   * This is an activity state variable used for saving and restoring the
   * state without accessing the model.
   */
  private boolean detecting;

  /**
   * Called when the activity is created. Manages the initialization of the
   * application state, as well as restoring a previous state.
   * 
   * @param savedInstanceState
   *            if the activity is being re-initialized after previously being
   *            shut down then this Bundle contains the data it most recently
   *            supplied in onSaveInstanceState(Bundle). <b>Note: Otherwise it
   *            is null.</b>
   */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i(TAG, "onCreate");
    setContentView(R.layout.activity_main);

    Client.setModel(new ClientModel());
    Client.setController(new ClientController(Client.getModel()));

    controller = Client.getController();
    controller.addOutboxHandler(new Handler(this));

    initializeReferences();
    if (!ensureConfiguration()) {
      return;
    }

    // restore image due to orientation change
    if (getLastNonConfigurationInstance() != null) {
      Bitmap bitmap = (Bitmap) getLastNonConfigurationInstance();
      snapshot.setImageBitmap(bitmap);
    }

    if (savedInstanceState != null) {
      // activity was put to the background, restore
      Log.i(TAG, "Restore saved instance state");
      Bitmap bitmap = savedInstanceState.getParcelable("snapshot");
      detecting = savedInstanceState.getBoolean("detectionActive");
      snapshot.setImageBitmap(bitmap);
    } else if (getIntent().getExtras() == null) {
      // activity was destroyed, restore state based on the server state
      lockInterface();
      controller.restoreClientState();
    } else {
      // activity was destroyed, activity started through notification
      lockInterface();
      String filename = getIntent().getExtras().getString("filename");
      controller.restoreClientState(filename);
    }
  }

  /**
   * If the screen orientation changes this method has to make sure, that the
   * appropriate controller state is set and that this state is displayed in
   * the interface.
   * 
   * Also this method performs the interface changes when the orientation is
   * changed, for instance removing the background image. If the application
   * was not closed and a motion notification is selected this method also
   * makes sure, that the motion snapshot is requested.
   */
  @Override
  public void onResume() {
    super.onResume();
    Log.i(TAG, "onResume");

    if (detecting) {
      controller.setState(new DetectionState(controller));
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
      detectionToggle.setText(R.string.button_stop_detection);
    }
    int orientation = getResources().getConfiguration().orientation;
    if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
      getWindow().setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN);
      LayoutParams params = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
      layout.setBackgroundDrawable(null);
      snapshotArea.setLayoutParams(params);
    }
    boolean notification = getIntent().getExtras() != null;
    if (notification) {
      lockInterface();
      String filename = getIntent().getExtras().getString("filename");
      controller.downloadMotionSnapshot(filename);
      GCMIntentService.resetMotionsDetected(this);
    }
  }

  /**
   * Disposes the controller so the handler looper is shut down. Makes sure
   * that that this method does not fail and delegates to the super method.
   * 
   * @see android.app.Activity#onDestroy()
   */
  @Override
  public void onDestroy() {
    try {
      controller.dispose();
    } catch (Throwable t) {
      Log.e(TAG, "Failed to destroy the controller", t);
    } finally {
      super.onDestroy();
    }
  }

  /**
   * Initializes the application menu, used to make the
   * {@link SettingsActivity} accessible.
   */
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu, menu);
    return true;
  }

  /**
   * Initializes actions for the application menu, used to make the
   * {@link SettingsActivity} accessible.
   */
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.settings:
      startSettingsActivity(false);
      break;
    }
    return true;
  }

  /**
   * Saves all necessary information to restore the activity state.
   * 
   * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
   */
  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putBoolean("detectionActive", detecting);

    if (snapshot.getDrawable() != null) {
      BitmapDrawable drawable = ((BitmapDrawable) snapshot.getDrawable());
      Bitmap bitmap = drawable.getBitmap();
      savedInstanceState.putParcelable("snapshot", bitmap);
    }
  }

  /**
   * Called when the screen orientation changes and stores the image so it
   * does not need to be retrieved once more.
   * 
   * @see android.app.Activity#onRetainNonConfigurationInstance()
   */
  @Override
  public Object onRetainNonConfigurationInstance() {
    super.onRetainNonConfigurationInstance();
    return ((BitmapDrawable) snapshot.getDrawable()).getBitmap();
  }

  /**
   * For a faster access of the components this method initializes all the
   * references by finding their view instance elements through their
   * respective identifiers.
   */
  public void initializeReferences() {
    if (!initialized) {
      layout = (RelativeLayout) findViewById(R.id.layout);
      snapshot = (ImageView) findViewById(R.id.snapshot);
      detectionToggle = (Button) findViewById(R.id.detection_toggle);
      progress = (ProgressBar) findViewById(R.id.progress_bar);
      snapshotArea = (RelativeLayout) findViewById(R.id.snapshot_area);
      headline = (TextView) findViewById(R.id.headline);
      subtitle = (TextView) findViewById(R.id.subtitle);
      initialized = true;
    }
  }

  /**
   * This method is used at the beginning of the main activity to make sure,
   * that the client's configuration is completed.
   * 
   * @return whether the endpoint configuration is complete.
   */
  private boolean ensureConfiguration() {
    boolean configured = Client.isConfigured(this);
    if (!configured) {
      startSettingsActivity(true);
    }
    return configured;
  }

  /**
   * Starts the settings activity. This method is used when accessing the
   * {@link SettingsActivity} via the menu and when it is required due to
   * incomplete endpoint configuration.
   * 
   * @param force
   *            whether instruction should be displayed which tell the user
   *            that he/she needs to complete the endpoint configuration.
   */
  private void startSettingsActivity(boolean force) {
    Intent intent = new Intent(this, SettingsActivity.class);
    intent.putExtra(SettingsActivity.DISPLAY_INSTRUCTION, force);
    startActivity(intent);
  }

  /**
   * Toggles the motion detection based on the current state. This method must
   * only be invoked when the state is {@link State#IDLE} or
   * {@link State#DETECTING}.
   * 
   * @param view
   *            the view that was clicked.
   */
  public void toggleMotionDetection(View view) {
    lockInterface();
    if (detecting) {
      controller.stopDetection();
    } else {
      controller.startDetection();
    }
  }

  /**
   * Locks the interface so the user cannot interact anymore until the current
   * actions have finished.
   */
  public void lockInterface() {
    detectionToggle.setEnabled(false);
    snapshot.setEnabled(false);
    progress.setVisibility(View.VISIBLE);
    snapshot.setVisibility(View.INVISIBLE);
  }

  /**
   * Unlocks the interface because a request was carried out, independent
   * whether it was successful or not.
   * 
   * Only make {@link ImageView} for snapshot visible again, if the motion
   * detection is currently active.
   */
  public void unlockInterface(boolean detecting) {
    detectionToggle.setEnabled(true);
    snapshot.setEnabled(true);
    progress.setVisibility(View.INVISIBLE);
    if (detecting) {
      snapshot.setVisibility(View.VISIBLE);
    }
  }

  /**
   * Issues a request to download the latest snapshot.
   * 
   * @param view
   *            not required.
   */
  public void refreshSnapshot(View view) {
    lockInterface();
    controller.downloadLatestSnapshot();
  }

  /**
   * Callback handler which is used to react on messages sent from the
   * controller. This method is called if there are new changes which need to
   * be displayed on the interface.
   */
  @Override
  public boolean handleMessage(Message message) {

    Action action = Action.valueOf(message.what);
    switch (action) {
    case LOCK_INTERFACE:
      lockInterface();
      break;
    case UNLOCK_INTERFACE:
      unlockInterface((Boolean) message.obj);
      break;
    case SET_DETECTION_MODE:
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
      detectionToggle.setText(R.string.button_stop_detection);
      detectionToggle.setEnabled(true);
      detecting = true;
      break;
    case SET_IDLE_MODE:
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
      detectionToggle.setText(R.string.button_start_detection);
      detecting = false;
      snapshot.setVisibility(ImageView.INVISIBLE);
      unlockInterface(false);
      break;
    case SET_REGISTERED_ON_SERVER:
      GCMRegistrar.setRegisteredOnServer(this, (Boolean) message.obj);
      break;
    case SET_SNAPSHOT:
      snapshot.setImageBitmap((Bitmap) message.obj);
      unlockInterface(detecting);
      break;
    case REPORT_ERROR:
      NotificationDialog.create(this, message.obj.toString()).show();
      unlockInterface(detecting);
      break;
    case ISSUE_DEVICE_REGISTRATION:
      Log.d(TAG, "Received device registration issue.");
      GCMRegistrar.setRegisteredOnServer(this, false);
      GCMIntentService.manageDeviceRegistration(this);
      break;
    default:
      Log.e(TAG, "Retrieved illegal action: " + action);
      throw new IllegalStateException();
    }
    return true;
  }

}




Java Source Code List

berlin.reiche.securitas.Client.java
berlin.reiche.securitas.Settings.java
berlin.reiche.securitas.activities.Action.java
berlin.reiche.securitas.activities.LauncherActivity.java
berlin.reiche.securitas.activities.MainActivity.java
berlin.reiche.securitas.activities.SettingsActivity.java
berlin.reiche.securitas.activities.package-info.java
berlin.reiche.securitas.controller.ClientController.java
berlin.reiche.securitas.controller.Controller.java
berlin.reiche.securitas.controller.GCMIntentService.java
berlin.reiche.securitas.controller.GCMReceiver.java
berlin.reiche.securitas.controller.InboxHandler.java
berlin.reiche.securitas.controller.states.ControllerState.java
berlin.reiche.securitas.controller.states.DetectionState.java
berlin.reiche.securitas.controller.states.IdleState.java
berlin.reiche.securitas.controller.states.package-info.java
berlin.reiche.securitas.controller.tasks.BitmapDownloadTask.java
berlin.reiche.securitas.controller.tasks.DetectionRequest.java
berlin.reiche.securitas.controller.tasks.DeviceRegistration.java
berlin.reiche.securitas.controller.tasks.StatusTask.java
berlin.reiche.securitas.controller.tasks.package-info.java
berlin.reiche.securitas.controller.package-info.java
berlin.reiche.securitas.model.ClientModel.java
berlin.reiche.securitas.model.Model.java
berlin.reiche.securitas.model.Protocol.java
berlin.reiche.securitas.model.package-info.java
berlin.reiche.securitas.util.FlushedInputStream.java
berlin.reiche.securitas.util.HttpUtilities.java
berlin.reiche.securitas.util.NotificationDialog.java
berlin.reiche.securitas.util.package-info.java
berlin.reiche.securitas.package-info.java