Skip to content

Commit

Permalink
feat: EmergencySignal with blinking background and a sound
Browse files Browse the repository at this point in the history
fix: delete deprecated
refactor: minor changes throughout the code
update: gradle with instant start
design: colors change
  • Loading branch information
dmytroKarataiev committed Apr 25, 2016
1 parent eee3c80 commit bfb3fe4
Show file tree
Hide file tree
Showing 21 changed files with 353 additions and 194 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
# Flashlight with Morse Code
Simple Flashlight with no Ads which works as a Service (flashlight works when the app is in background). </br>
App has been published on [Google Play](https://play.google.com/store/apps/details?id=com.adkdevelopment.simpleflashlightadfree).
<a href="https://play.google.com/store/apps/details?id=com.adkdevelopment.simpleflashlightadfree"><img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/apps/en-play-badge.png" width="185" height="60"/></a><br>

![Screenshot](materials/flashlight_screenshots.png)

Flashlight with Morse Code and no Ads which works as a Service (it works when the app is in background). </br>

## Functionality
* Switch On/Off.
* Morse Code (alpha) added with [(03acde1)](https://github.com/dmytroKarataiev/SimpleFlashlight/commit/03acde1851b01802823e2d7e044bdaf1f1a31297) commit.
* Morse Code [(03acde1) commit.](https://github.com/dmytroKarataiev/SimpleFlashlight/commit/03acde1851b01802823e2d7e044bdaf1f1a31297)
* Full Marshmallow support (Camera2 API, CameraManager).
* Emergency state with a SEWS signal and a flashing background.

## Future development
* Emergency state.
* Morse Code speed.
* Sending an SMS of a location to most important people.

## Used technologies
* Service, Intents.
Expand All @@ -18,3 +23,4 @@ App has been published on [Google Play](https://play.google.com/store/apps/detai
## Content from the Internet
* App Icon - http://graphiccave.com/project/flashlight-icon-vector-and-png-free-download/
* Power Buttons - http://www.freestockphotos.biz/stockphoto/15104
* Emergency Signal - http://www.disaster.qld.gov.au/Warnings_and_Alerts/About_SEWS.html
15 changes: 11 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
buildToolsVersion "23.0.3"

defaultConfig {
applicationId "com.adkdevelopment.simpleflashlightadfree"
minSdkVersion 16
targetSdkVersion 22
versionCode 6
versionName "1.4"
versionCode 7
versionName "1.5"
}
buildTypes {
release {
Expand All @@ -19,8 +19,15 @@ android {
}
}

ext {
supportVersion = '23.3.0'
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile "com.android.support:appcompat-v7:$supportVersion"

// life simplifiers
compile 'com.jakewharton:butterknife:7.0.1'
}

This file was deleted.

2 changes: 0 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.flash"/>



<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
Expand Down
Binary file added app/src/main/assets/sews.mp3
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package com.adkdevelopment.simpleflashlightadfree;

import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Color;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
* Created by karataev on 2/22/16.
*/
public class EmergencyFragment extends android.support.v4.app.Fragment {

private static final String TAG = EmergencyFragment.class.getSimpleName();

private int status;
MediaPlayer mMediaPlayer;

@Bind(R.id.button_image) ImageView mButtonImage;
@Bind(R.id.flashlight_mode) TextView mStatusText;
@Bind(R.id.layout) LinearLayout mLinearLayout;

public EmergencyFragment() {}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (savedInstanceState != null) {
status = savedInstanceState.getInt(FlashlightService.STATUS);

if (status != FlashlightService.STATUS_OFF) {
Intent intent = new Intent(getActivity().getApplication(), FlashlightService.class);
intent.putExtra(FlashlightService.STATUS, status);
getActivity().getApplication().startService(intent);
}
} else {
status = FlashlightService.STATUS_OFF;
}

}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.fragment_main, container, false);

ButterKnife.bind(this, rootView);

// check status and use correct image
Utility.setSwitchColor(mStatusText, mButtonImage, status);

mButtonImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Start service on click
if (status == FlashlightService.STATUS_OFF) {
status = FlashlightService.STATUS_BLINK;
} else {
status = FlashlightService.STATUS_OFF;
}

emergencySignal();

Intent intent = new Intent(getActivity().getApplication(), FlashlightService.class);

// Set button drawable
Utility.setSwitchColor(mStatusText, mButtonImage, status);

intent.putExtra(FlashlightService.STATUS, status);
getActivity().getApplication().startService(intent);
}
});

return rootView;
}

@Override
public void onDestroy() {
super.onDestroy();


}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);

// Save status on rotate, possibly will remove rotation in the future
outState.putInt(FlashlightService.STATUS, status);
}

/**
* Starts emergency sound from assets
*/
public void emergencySignal() {

try {
if (mMediaPlayer != null && mMediaPlayer.isPlaying() && status == FlashlightService.STATUS_OFF) {
mMediaPlayer.stop();
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;

mLinearLayout.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorBackground));
} else if (status == FlashlightService.STATUS_BLINK) {

final AnimationDrawable drawable = new AnimationDrawable();
final Handler handler = new Handler();

drawable.addFrame(new ColorDrawable(Color.RED), 400);
drawable.addFrame(new ColorDrawable(Color.BLUE), 400);
drawable.setOneShot(false);

mLinearLayout.setBackground(drawable);
handler.postDelayed(new Runnable() {
@Override
public void run() {
drawable.start();
}
}, 100);

mMediaPlayer = new MediaPlayer();
AssetFileDescriptor descriptor = getActivity().getAssets().openFd("sews.mp3");
mMediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();

mMediaPlayer.prepare();
mMediaPlayer.setVolume(1f, 1f);
mMediaPlayer.setLooping(true);
mMediaPlayer.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ public class FlashlightService extends Service {

private final String LOG_TAG = FlashlightService.class.getSimpleName();

public static final String STATUS = "status";
public static final String MORSE = "morse";

public static final int STATUS_OFF = 0;
public static final int STATUS_TORCH = 1;
public static final int STATUS_BLINK = 2;
public static final int STATUS_MORSE = 3;

private int status = -1;
private String morseCode = "";

Expand All @@ -41,6 +49,7 @@ public class FlashlightService extends Service {
CameraManager manager;
String flashCameraId;

@TargetApi(Build.VERSION_CODES.M)
@Override
public void onDestroy() {
super.onDestroy();
Expand Down Expand Up @@ -77,7 +86,7 @@ public IBinder onBind(Intent intent) {
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);

status = intent.getIntExtra("status", 1);
status = intent.getIntExtra(STATUS, 1);

//get morse code from intent
morseCode = intent.getStringExtra("morse");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


if (savedInstanceState == null) {
pagerFragment = new PagerFragment();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@
import android.widget.ImageView;
import android.widget.TextView;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
* Created by karataev on 2/22/16.
*/
public class MainFragment extends android.support.v4.app.Fragment {

private final String LOG_TAG = MainFragment.class.getSimpleName();

private int status;
private boolean torch;

public static final String ARG_OBJECT = "object";

@Bind(R.id.button_image) ImageView mButtonImage;
@Bind(R.id.flashlight_mode) TextView mStatusText;

public MainFragment() {}

Expand All @@ -29,15 +29,15 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (savedInstanceState != null) {
status = savedInstanceState.getInt("status");
status = savedInstanceState.getInt(FlashlightService.STATUS);

if (status != 0) {
if (status != FlashlightService.STATUS_OFF) {
Intent intent = new Intent(getActivity().getApplication(), FlashlightService.class);
intent.putExtra("status", status);
intent.putExtra(FlashlightService.STATUS, status);
getActivity().getApplication().startService(intent);
}
} else {
status = 0;
status = FlashlightService.STATUS_OFF;
}

}
Expand All @@ -48,13 +48,12 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa

View rootView = inflater.inflate(R.layout.fragment_main, container, false);

final ImageView button = (ImageView) rootView.findViewById(R.id.button_image);
final TextView statusText = (TextView) rootView.findViewById(R.id.flashlight_mode);
ButterKnife.bind(this, rootView);

// check status and use correct image
setSwitchColor(statusText, button, status);
Utility.setSwitchColor(mStatusText, mButtonImage, status);

button.setOnClickListener(new View.OnClickListener() {
mButtonImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Start service on click
Expand All @@ -63,9 +62,9 @@ public void onClick(View v) {
Intent intent = new Intent(getActivity().getApplication(), FlashlightService.class);

// Set button drawable
setSwitchColor(statusText, button, status);
Utility.setSwitchColor(mStatusText, mButtonImage, status);

intent.putExtra("status", status);
intent.putExtra(FlashlightService.STATUS, status);
getActivity().getApplication().startService(intent);
}
});
Expand All @@ -85,30 +84,6 @@ public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);

// Save status on rotate, possibly will remove rotation in the future
outState.putInt("status", status);
outState.putInt(FlashlightService.STATUS, status);
}

/**
* Method to set flashlight button drawable
*
* @param button to switch flashlight
* @param status flashlight mode
*/
private void setSwitchColor(TextView mode, ImageView button, int status) {
switch (status) {
case 0:
button.setImageResource(R.drawable.switch_on);
mode.setText(R.string.flashlight_status_on);
break;
case 1:
button.setImageResource(R.drawable.switch_blink);
mode.setText(R.string.flashlight_status_blink);
break;
case 2:
button.setImageResource(R.drawable.switch_off);
mode.setText(R.string.flashlight_status_off);
break;
}
}

}
Loading

0 comments on commit bfb3fe4

Please sign in to comment.