mirror of
https://github.com/SimpleMobileTools/Simple-Flashlight.git
synced 2025-04-16 11:17:18 +02:00
initial implementation of rewriting the app in kotlin
This commit is contained in:
parent
a856156f76
commit
18b5c9de46
@ -16,10 +16,10 @@
|
|||||||
android:label="@string/app_launcher_name"
|
android:label="@string/app_launcher_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.MainActivity"
|
android:name=".activities.SplashActivity"
|
||||||
android:screenOrientation="portrait"
|
android:theme="@style/SplashTheme">
|
||||||
android:theme="@style/BlackSplashScreen.Dark">
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
@ -27,6 +27,11 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".activities.MainActivity"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/BlackSplashScreen.Dark"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.WidgetConfigureActivity"
|
android:name=".activities.WidgetConfigureActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
@ -36,16 +41,6 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".activities.AboutActivity"
|
|
||||||
android:label="@string/about"
|
|
||||||
android:parentActivityName=".activities.MainActivity"/>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".activities.LicenseActivity"
|
|
||||||
android:label="@string/third_party_licences"
|
|
||||||
android:parentActivityName=".activities.AboutActivity"/>
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.BrightDisplayActivity"
|
android:name=".activities.BrightDisplayActivity"
|
||||||
android:screenOrientation="portrait"/>
|
android:screenOrientation="portrait"/>
|
||||||
@ -55,6 +50,21 @@
|
|||||||
android:label="@string/settings"
|
android:label="@string/settings"
|
||||||
android:parentActivityName=".activities.MainActivity"/>
|
android:parentActivityName=".activities.MainActivity"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.simplemobiletools.commons.activities.AboutActivity"
|
||||||
|
android:label="@string/about"
|
||||||
|
android:parentActivityName=".activities.MainActivity"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.simplemobiletools.commons.activities.LicenseActivity"
|
||||||
|
android:label="@string/third_party_licences"
|
||||||
|
android:parentActivityName="com.simplemobiletools.commons.activities.AboutActivity"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.simplemobiletools.commons.activities.CustomizationActivity"
|
||||||
|
android:label="@string/customize_colors"
|
||||||
|
android:parentActivityName=".activities.SettingsActivity"/>
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".helpers.MyWidgetProvider"
|
android:name=".helpers.MyWidgetProvider"
|
||||||
android:icon="@drawable/circles_small">
|
android:icon="@drawable/circles_small">
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.activities;
|
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.Html;
|
|
||||||
import android.text.method.LinkMovementMethod;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.BuildConfig;
|
|
||||||
import com.simplemobiletools.flashlight.helpers.Config;
|
|
||||||
import com.simplemobiletools.flashlight.R;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import butterknife.OnClick;
|
|
||||||
|
|
||||||
public class AboutActivity extends SimpleActivity {
|
|
||||||
@BindView(R.id.about_copyright) TextView mCopyright;
|
|
||||||
@BindView(R.id.about_email) TextView mEmailTV;
|
|
||||||
@BindView(R.id.about_rate_us) View mRateUs;
|
|
||||||
|
|
||||||
private static Resources mRes;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_about);
|
|
||||||
ButterKnife.bind(this);
|
|
||||||
mRes = getResources();
|
|
||||||
|
|
||||||
setupEmail();
|
|
||||||
setupCopyright();
|
|
||||||
setupRateUs();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupEmail() {
|
|
||||||
final String email = mRes.getString(R.string.email);
|
|
||||||
final String appName = mRes.getString(R.string.app_name);
|
|
||||||
final String href = "<a href=\"mailto:" + email + "?subject=" + appName + "\">" + email + "</a>";
|
|
||||||
mEmailTV.setText(Html.fromHtml(href));
|
|
||||||
mEmailTV.setMovementMethod(LinkMovementMethod.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupCopyright() {
|
|
||||||
final String versionName = BuildConfig.VERSION_NAME;
|
|
||||||
final int year = Calendar.getInstance().get(Calendar.YEAR);
|
|
||||||
final String copyrightText = String.format(mRes.getString(R.string.copyright), versionName, year);
|
|
||||||
mCopyright.setText(copyrightText);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupRateUs() {
|
|
||||||
if (Config.newInstance(getApplicationContext()).getIsFirstRun()) {
|
|
||||||
mRateUs.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.about_invite)
|
|
||||||
public void inviteFriend() {
|
|
||||||
final Intent intent = new Intent();
|
|
||||||
final String text = String.format(getString(R.string.share_text), getString(R.string.app_name), getStoreUrl());
|
|
||||||
intent.setAction(Intent.ACTION_SEND);
|
|
||||||
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name));
|
|
||||||
intent.putExtra(Intent.EXTRA_TEXT, text);
|
|
||||||
intent.setType("text/plain");
|
|
||||||
startActivity(Intent.createChooser(intent, getString(R.string.invite_via)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.about_rate_us)
|
|
||||||
public void rateUsClicked() {
|
|
||||||
final Uri uri = Uri.parse("market://details?id=" + getPackageName());
|
|
||||||
try {
|
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW, uri));
|
|
||||||
} catch (ActivityNotFoundException ignored) {
|
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getStoreUrl())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.about_license)
|
|
||||||
public void licenseClicked() {
|
|
||||||
final Intent intent = new Intent(getApplicationContext(), LicenseActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.about_facebook)
|
|
||||||
public void facebookClicked() {
|
|
||||||
String link = "https://www.facebook.com/simplemobiletools";
|
|
||||||
try {
|
|
||||||
getPackageManager().getPackageInfo("com.facebook.katana", 0);
|
|
||||||
link = "fb://page/150270895341774";
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(link)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.about_gplus)
|
|
||||||
public void googlePlusClicked() {
|
|
||||||
final String link = "https://plus.google.com/communities/104880861558693868382";
|
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(link)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getStoreUrl() {
|
|
||||||
return "https://play.google.com/store/apps/details?id=" + getPackageName();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.activities;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.R;
|
|
||||||
|
|
||||||
public class BrightDisplayActivity extends SimpleActivity {
|
|
||||||
@Override
|
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_bright_display);
|
|
||||||
|
|
||||||
if (getSupportActionBar() != null)
|
|
||||||
getSupportActionBar().hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
toggleBrightness(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
toggleBrightness(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toggleBrightness(boolean increase) {
|
|
||||||
final WindowManager.LayoutParams layout = getWindow().getAttributes();
|
|
||||||
layout.screenBrightness = (increase ? 1 : 0);
|
|
||||||
getWindow().setAttributes(layout);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.activities;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.R;
|
|
||||||
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import butterknife.OnClick;
|
|
||||||
|
|
||||||
public class LicenseActivity extends SimpleActivity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_license);
|
|
||||||
ButterKnife.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.license_butterknife_title)
|
|
||||||
public void butterKnifeClicked() {
|
|
||||||
openUrl(R.string.butterknife_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.license_ambilwarna_title)
|
|
||||||
public void ambilwarnaClicked() {
|
|
||||||
openUrl(R.string.ambilwarna_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.license_otto_title)
|
|
||||||
public void ottoClicked() {
|
|
||||||
openUrl(R.string.otto_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openUrl(int id) {
|
|
||||||
final String url = getResources().getString(id);
|
|
||||||
final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
|
||||||
startActivity(browserIntent);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,227 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.activities;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.graphics.PorterDuff;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.app.ActivityCompat;
|
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.SeekBar;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.helpers.BusProvider;
|
|
||||||
import com.simplemobiletools.flashlight.helpers.Config;
|
|
||||||
import com.simplemobiletools.flashlight.models.Events;
|
|
||||||
import com.simplemobiletools.flashlight.helpers.MyCameraImpl;
|
|
||||||
import com.simplemobiletools.flashlight.R;
|
|
||||||
import com.simplemobiletools.flashlight.helpers.Utils;
|
|
||||||
import com.squareup.otto.Bus;
|
|
||||||
import com.squareup.otto.Subscribe;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import butterknife.OnClick;
|
|
||||||
|
|
||||||
public class MainActivity extends SimpleActivity {
|
|
||||||
private static final int CAMERA_PERMISSION = 1;
|
|
||||||
private static final int MAX_STROBO_DELAY = 2000;
|
|
||||||
private static final int MIN_STROBO_DELAY = 30;
|
|
||||||
|
|
||||||
@BindView(R.id.toggle_btn) ImageView mToggleBtn;
|
|
||||||
@BindView(R.id.bright_display_btn) ImageView mBrightDisplayBtn;
|
|
||||||
@BindView(R.id.stroboscope_btn) ImageView mStroboscopeBtn;
|
|
||||||
@BindView(R.id.stroboscope_bar) SeekBar mStroboscopeBar;
|
|
||||||
|
|
||||||
private static Bus mBus;
|
|
||||||
private MyCameraImpl mCameraImpl;
|
|
||||||
private boolean mJustGrantedPermission;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_main);
|
|
||||||
ButterKnife.bind(this);
|
|
||||||
|
|
||||||
mBus = BusProvider.getInstance();
|
|
||||||
changeIconColor(R.color.translucent_white, mBrightDisplayBtn);
|
|
||||||
changeIconColor(R.color.translucent_white, mStroboscopeBtn);
|
|
||||||
mStroboscopeBar.setMax(MAX_STROBO_DELAY - MIN_STROBO_DELAY);
|
|
||||||
mStroboscopeBar.setProgress(mStroboscopeBar.getMax() / 2);
|
|
||||||
|
|
||||||
mStroboscopeBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
|
|
||||||
final int frequency = mStroboscopeBar.getMax() - progress + MIN_STROBO_DELAY;
|
|
||||||
if (mCameraImpl != null)
|
|
||||||
mCameraImpl.setStroboFrequency(frequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.menu, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.settings:
|
|
||||||
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
|
|
||||||
return true;
|
|
||||||
case R.id.about:
|
|
||||||
startActivity(new Intent(getApplicationContext(), AboutActivity.class));
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupCameraImpl() {
|
|
||||||
mCameraImpl = new MyCameraImpl(this);
|
|
||||||
mCameraImpl.enableFlashlight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.toggle_btn)
|
|
||||||
public void toggleFlashlight() {
|
|
||||||
mCameraImpl.toggleFlashlight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.bright_display_btn)
|
|
||||||
public void launchBrightDisplay() {
|
|
||||||
startActivity(new Intent(getApplicationContext(), BrightDisplayActivity.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.stroboscope_btn)
|
|
||||||
public void tryToggleStroboscope() {
|
|
||||||
toggleStroboscope();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toggleStroboscope() {
|
|
||||||
// use the old Camera API for stroboscope, the new Camera Manager is way too slow
|
|
||||||
if (isCameraPermissionGranted() || Utils.isNougat()) {
|
|
||||||
if (mCameraImpl.toggleStroboscope()) {
|
|
||||||
mStroboscopeBar.setVisibility(mStroboscopeBar.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE);
|
|
||||||
changeIconColor(mStroboscopeBar.getVisibility() == View.VISIBLE ? R.color.colorPrimary : R.color.translucent_white, mStroboscopeBtn);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final String[] permissions = {Manifest.permission.CAMERA};
|
|
||||||
ActivityCompat.requestPermissions(this, permissions, CAMERA_PERMISSION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
||||||
|
|
||||||
if (requestCode == CAMERA_PERMISSION) {
|
|
||||||
mJustGrantedPermission = true;
|
|
||||||
if (isCameraPermissionGranted()) {
|
|
||||||
toggleStroboscope();
|
|
||||||
} else {
|
|
||||||
Utils.showToast(getApplicationContext(), R.string.camera_permission);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
mBus.register(this);
|
|
||||||
|
|
||||||
if (mCameraImpl == null) {
|
|
||||||
setupCameraImpl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
if (mJustGrantedPermission) {
|
|
||||||
mJustGrantedPermission = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mCameraImpl.handleCameraSetup();
|
|
||||||
mCameraImpl.checkFlashlight();
|
|
||||||
|
|
||||||
mBrightDisplayBtn.setVisibility(mConfig.getBrightDisplay() ? View.VISIBLE : View.GONE);
|
|
||||||
mStroboscopeBtn.setVisibility(mConfig.getStroboscope() ? View.VISIBLE : View.GONE);
|
|
||||||
if (!mConfig.getStroboscope()) {
|
|
||||||
mCameraImpl.stopStroboscope();
|
|
||||||
mStroboscopeBar.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
mBus.unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
Config.newInstance(getApplicationContext()).setIsFirstRun(false);
|
|
||||||
releaseCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void releaseCamera() {
|
|
||||||
if (mCameraImpl != null) {
|
|
||||||
mCameraImpl.releaseCamera();
|
|
||||||
mCameraImpl = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isCameraPermissionGranted() {
|
|
||||||
return ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void stateChangedEvent(Events.StateChanged event) {
|
|
||||||
if (event.getIsEnabled()) {
|
|
||||||
enableFlashlight();
|
|
||||||
} else {
|
|
||||||
disableFlashlight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableFlashlight() {
|
|
||||||
changeIconColor(R.color.colorPrimary, mToggleBtn);
|
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
|
|
||||||
changeIconColor(R.color.translucent_white, mStroboscopeBtn);
|
|
||||||
mStroboscopeBar.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disableFlashlight() {
|
|
||||||
changeIconColor(R.color.translucent_white, mToggleBtn);
|
|
||||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void changeIconColor(int colorId, ImageView imageView) {
|
|
||||||
final int appColor = getResources().getColor(colorId);
|
|
||||||
imageView.getBackground().mutate().setColorFilter(appColor, PorterDuff.Mode.SRC_IN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void cameraUnavailable(Events.CameraUnavailable event) {
|
|
||||||
Utils.showToast(this, R.string.camera_error);
|
|
||||||
disableFlashlight();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.activities;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.app.TaskStackBuilder;
|
|
||||||
import android.support.v7.widget.SwitchCompat;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.helpers.Config;
|
|
||||||
import com.simplemobiletools.flashlight.R;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import butterknife.OnClick;
|
|
||||||
|
|
||||||
public class SettingsActivity extends SimpleActivity {
|
|
||||||
@BindView(R.id.settings_dark_theme) SwitchCompat mDarkThemeSwitch;
|
|
||||||
@BindView(R.id.settings_bright_display) SwitchCompat mBrightDisplaySwitch;
|
|
||||||
@BindView(R.id.settings_stroboscope) SwitchCompat mStroboscopeSwitch;
|
|
||||||
|
|
||||||
private static Config mConfig;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_settings);
|
|
||||||
mConfig = Config.newInstance(getApplicationContext());
|
|
||||||
ButterKnife.bind(this);
|
|
||||||
|
|
||||||
setupDarkTheme();
|
|
||||||
setupBrightDisplay();
|
|
||||||
setupStroboscope();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupDarkTheme() {
|
|
||||||
mDarkThemeSwitch.setChecked(mConfig.getIsDarkTheme());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupBrightDisplay() {
|
|
||||||
mBrightDisplaySwitch.setChecked(mConfig.getBrightDisplay());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupStroboscope() {
|
|
||||||
mStroboscopeSwitch.setChecked(mConfig.getStroboscope());
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.settings_dark_theme_holder)
|
|
||||||
public void handleDarkTheme() {
|
|
||||||
mDarkThemeSwitch.setChecked(!mDarkThemeSwitch.isChecked());
|
|
||||||
mConfig.setIsDarkTheme(mDarkThemeSwitch.isChecked());
|
|
||||||
restartActivity();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.settings_bright_display_holder)
|
|
||||||
public void handleBrightDisplay() {
|
|
||||||
mBrightDisplaySwitch.setChecked(!mBrightDisplaySwitch.isChecked());
|
|
||||||
mConfig.setBrightDisplay(mBrightDisplaySwitch.isChecked());
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.settings_stroboscope_holder)
|
|
||||||
public void handleStroboscope() {
|
|
||||||
mStroboscopeSwitch.setChecked(!mStroboscopeSwitch.isChecked());
|
|
||||||
mConfig.setStroboscope(mStroboscopeSwitch.isChecked());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void restartActivity() {
|
|
||||||
TaskStackBuilder.create(getApplicationContext()).addNextIntentWithParentStack(getIntent()).startActivities();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.activities;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.helpers.Config;
|
|
||||||
import com.simplemobiletools.flashlight.R;
|
|
||||||
|
|
||||||
public class SimpleActivity extends AppCompatActivity {
|
|
||||||
protected Config mConfig;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
mConfig = Config.newInstance(getApplicationContext());
|
|
||||||
int theme = mConfig.getIsDarkTheme() ? R.style.AppTheme_Dark : R.style.AppTheme;
|
|
||||||
if (this instanceof MainActivity) {
|
|
||||||
theme = R.style.BlackSplashScreen_Dark;
|
|
||||||
}
|
|
||||||
setTheme(theme);
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case android.R.id.home:
|
|
||||||
finish();
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,142 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.activities;
|
|
||||||
|
|
||||||
import android.appwidget.AppWidgetManager;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.PorterDuff;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.RemoteViews;
|
|
||||||
import android.widget.SeekBar;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.helpers.Constants;
|
|
||||||
import com.simplemobiletools.flashlight.helpers.MyWidgetProvider;
|
|
||||||
import com.simplemobiletools.flashlight.R;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import butterknife.OnClick;
|
|
||||||
import yuku.ambilwarna.AmbilWarnaDialog;
|
|
||||||
|
|
||||||
public class WidgetConfigureActivity extends AppCompatActivity {
|
|
||||||
@BindView(R.id.config_widget_seekbar) SeekBar mWidgetSeekBar;
|
|
||||||
@BindView(R.id.config_widget_color) View mWidgetColorPicker;
|
|
||||||
@BindView(R.id.config_image) ImageView mImage;
|
|
||||||
|
|
||||||
private static float mWidgetAlpha;
|
|
||||||
private static int mWidgetId;
|
|
||||||
private static int mWidgetColor;
|
|
||||||
private static int mWidgetColorWithoutTransparency;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setResult(RESULT_CANCELED);
|
|
||||||
setContentView(R.layout.widget_config);
|
|
||||||
ButterKnife.bind(this);
|
|
||||||
initVariables();
|
|
||||||
|
|
||||||
final Intent intent = getIntent();
|
|
||||||
final Bundle extras = intent.getExtras();
|
|
||||||
if (extras != null)
|
|
||||||
mWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
|
|
||||||
|
|
||||||
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID)
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initVariables() {
|
|
||||||
final SharedPreferences prefs = getSharedPreferences(Constants.PREFS_KEY, Context.MODE_PRIVATE);
|
|
||||||
mWidgetColor = prefs.getInt(Constants.WIDGET_COLOR, 1);
|
|
||||||
if (mWidgetColor == 1) {
|
|
||||||
mWidgetColor = getResources().getColor(R.color.colorPrimary);
|
|
||||||
mWidgetAlpha = 1.f;
|
|
||||||
} else {
|
|
||||||
mWidgetAlpha = Color.alpha(mWidgetColor) / (float) 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
mWidgetColorWithoutTransparency = Color.rgb(Color.red(mWidgetColor), Color.green(mWidgetColor), Color.blue(mWidgetColor));
|
|
||||||
mWidgetSeekBar.setOnSeekBarChangeListener(seekbarChangeListener);
|
|
||||||
mWidgetSeekBar.setProgress((int) (mWidgetAlpha * 100));
|
|
||||||
updateColors();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.config_save)
|
|
||||||
public void saveConfig() {
|
|
||||||
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
|
|
||||||
final RemoteViews views = new RemoteViews(getPackageName(), R.layout.widget);
|
|
||||||
appWidgetManager.updateAppWidget(mWidgetId, views);
|
|
||||||
|
|
||||||
storeWidgetColors();
|
|
||||||
requestWidgetUpdate();
|
|
||||||
|
|
||||||
final Intent resultValue = new Intent();
|
|
||||||
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId);
|
|
||||||
setResult(RESULT_OK, resultValue);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.config_widget_color)
|
|
||||||
public void pickBackgroundColor() {
|
|
||||||
AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, mWidgetColorWithoutTransparency, new AmbilWarnaDialog.OnAmbilWarnaListener() {
|
|
||||||
@Override
|
|
||||||
public void onCancel(AmbilWarnaDialog dialog) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onOk(AmbilWarnaDialog dialog, int color) {
|
|
||||||
mWidgetColorWithoutTransparency = color;
|
|
||||||
updateColors();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void storeWidgetColors() {
|
|
||||||
final SharedPreferences prefs = getSharedPreferences(Constants.PREFS_KEY, Context.MODE_PRIVATE);
|
|
||||||
prefs.edit().putInt(Constants.WIDGET_COLOR, mWidgetColor).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void requestWidgetUpdate() {
|
|
||||||
final Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetProvider.class);
|
|
||||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[]{mWidgetId});
|
|
||||||
sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateColors() {
|
|
||||||
mWidgetColor = adjustAlpha(mWidgetColorWithoutTransparency, mWidgetAlpha);
|
|
||||||
mWidgetColorPicker.setBackgroundColor(mWidgetColor);
|
|
||||||
mImage.getBackground().mutate().setColorFilter(mWidgetColor, PorterDuff.Mode.SRC_IN);
|
|
||||||
}
|
|
||||||
|
|
||||||
private SeekBar.OnSeekBarChangeListener seekbarChangeListener = new SeekBar.OnSeekBarChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
|
||||||
mWidgetAlpha = (float) progress / (float) 100;
|
|
||||||
updateColors();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private int adjustAlpha(int color, float factor) {
|
|
||||||
final int alpha = Math.round(Color.alpha(color) * factor);
|
|
||||||
final int red = Color.red(color);
|
|
||||||
final int green = Color.green(color);
|
|
||||||
final int blue = Color.blue(color);
|
|
||||||
return Color.argb(alpha, red, green, blue);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.helpers;
|
|
||||||
|
|
||||||
import com.squareup.otto.Bus;
|
|
||||||
|
|
||||||
public class BusProvider {
|
|
||||||
private static final Bus BUS = new Bus();
|
|
||||||
|
|
||||||
public static Bus getInstance() {
|
|
||||||
return BUS;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.helpers;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
|
|
||||||
public class Config {
|
|
||||||
private SharedPreferences mPrefs;
|
|
||||||
|
|
||||||
public static Config newInstance(Context context) {
|
|
||||||
return new Config(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Config(Context context) {
|
|
||||||
mPrefs = context.getSharedPreferences(Constants.PREFS_KEY, Context.MODE_PRIVATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getIsFirstRun() {
|
|
||||||
return mPrefs.getBoolean(Constants.IS_FIRST_RUN, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsFirstRun(boolean firstRun) {
|
|
||||||
mPrefs.edit().putBoolean(Constants.IS_FIRST_RUN, firstRun).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getIsDarkTheme() {
|
|
||||||
return mPrefs.getBoolean(Constants.IS_DARK_THEME, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsDarkTheme(boolean isDarkTheme) {
|
|
||||||
mPrefs.edit().putBoolean(Constants.IS_DARK_THEME, isDarkTheme).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getBrightDisplay() {
|
|
||||||
return mPrefs.getBoolean(Constants.BRIGHT_DISPLAY, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrightDisplay(boolean brightDisplay) {
|
|
||||||
mPrefs.edit().putBoolean(Constants.BRIGHT_DISPLAY, brightDisplay).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getStroboscope() {
|
|
||||||
return mPrefs.getBoolean(Constants.STROBOSCOPE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStroboscope(boolean stroboscope) {
|
|
||||||
mPrefs.edit().putBoolean(Constants.STROBOSCOPE, stroboscope).apply();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.helpers;
|
|
||||||
|
|
||||||
public class Constants {
|
|
||||||
// shared preferences
|
|
||||||
public static final String PREFS_KEY = "Flashlight";
|
|
||||||
public static final String IS_FIRST_RUN = "is_first_run";
|
|
||||||
public static final String IS_DARK_THEME = "is_dark_theme";
|
|
||||||
public static final String BRIGHT_DISPLAY = "bright_display";
|
|
||||||
public static final String STROBOSCOPE = "stroboscope";
|
|
||||||
public static final String WIDGET_COLOR = "widget_color";
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.helpers;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.hardware.camera2.CameraAccessException;
|
|
||||||
import android.hardware.camera2.CameraManager;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.models.Events;
|
|
||||||
import com.squareup.otto.Bus;
|
|
||||||
|
|
||||||
class MarshmallowCamera {
|
|
||||||
private static final String TAG = MyCameraImpl.class.getSimpleName();
|
|
||||||
|
|
||||||
private CameraManager manager;
|
|
||||||
private String cameraId;
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.M)
|
|
||||||
MarshmallowCamera(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
|
|
||||||
try {
|
|
||||||
final String[] list = manager.getCameraIdList();
|
|
||||||
cameraId = list[0];
|
|
||||||
} catch (CameraAccessException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.M)
|
|
||||||
void toggleMarshmallowFlashlight(final Bus bus, boolean enable) {
|
|
||||||
try {
|
|
||||||
manager.setTorchMode(cameraId, enable);
|
|
||||||
} catch (CameraAccessException e) {
|
|
||||||
Log.e(TAG, "toggle marshmallow flashlight " + e.getMessage());
|
|
||||||
|
|
||||||
Runnable mainRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
bus.post(new Events.CameraUnavailable());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
new Handler(mContext.getMainLooper()).post(mainRunnable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,275 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.helpers;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.SurfaceTexture;
|
|
||||||
import android.hardware.Camera;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.R;
|
|
||||||
import com.simplemobiletools.flashlight.models.Events;
|
|
||||||
import com.squareup.otto.Bus;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class MyCameraImpl {
|
|
||||||
private static final String TAG = MyCameraImpl.class.getSimpleName();
|
|
||||||
|
|
||||||
private static Camera mCamera;
|
|
||||||
private static Camera.Parameters mParams;
|
|
||||||
private static Bus mBus;
|
|
||||||
private Context mContext;
|
|
||||||
private MarshmallowCamera mMarshmallowCamera;
|
|
||||||
private volatile boolean mShouldStroboscopeStop;
|
|
||||||
private volatile boolean mIsStroboscopeRunning;
|
|
||||||
|
|
||||||
private static boolean mIsFlashlightOn;
|
|
||||||
private static boolean mIsMarshmallow;
|
|
||||||
private static boolean mShouldEnableFlashlight;
|
|
||||||
private static int mStroboFrequency;
|
|
||||||
|
|
||||||
public MyCameraImpl(Context cxt) {
|
|
||||||
mContext = cxt;
|
|
||||||
mIsMarshmallow = isMarshmallow();
|
|
||||||
mStroboFrequency = 1000;
|
|
||||||
|
|
||||||
if (mBus == null) {
|
|
||||||
mBus = BusProvider.getInstance();
|
|
||||||
mBus.register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCameraSetup();
|
|
||||||
checkFlashlight();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void toggleFlashlight() {
|
|
||||||
mIsFlashlightOn = !mIsFlashlightOn;
|
|
||||||
handleCameraSetup();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStroboFrequency(int frequency) {
|
|
||||||
mStroboFrequency = frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean toggleStroboscope() {
|
|
||||||
if (!mIsStroboscopeRunning)
|
|
||||||
disableFlashlight();
|
|
||||||
|
|
||||||
if (!Utils.isNougat()) {
|
|
||||||
if (mCamera == null) {
|
|
||||||
initCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCamera == null) {
|
|
||||||
Utils.showToast(mContext, R.string.camera_error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIsStroboscopeRunning) {
|
|
||||||
stopStroboscope();
|
|
||||||
} else {
|
|
||||||
new Thread(stroboscope).start();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopStroboscope() {
|
|
||||||
mShouldStroboscopeStop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleCameraSetup() {
|
|
||||||
if (mIsMarshmallow) {
|
|
||||||
setupMarshmallowCamera();
|
|
||||||
} else {
|
|
||||||
setupCamera();
|
|
||||||
}
|
|
||||||
checkFlashlight();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupMarshmallowCamera() {
|
|
||||||
if (mMarshmallowCamera == null) {
|
|
||||||
mMarshmallowCamera = new MarshmallowCamera(mContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupCamera() {
|
|
||||||
if (mIsMarshmallow)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mCamera == null) {
|
|
||||||
initCamera();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initCamera() {
|
|
||||||
try {
|
|
||||||
mCamera = Camera.open();
|
|
||||||
mParams = mCamera.getParameters();
|
|
||||||
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
|
|
||||||
mCamera.setParameters(mParams);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "setup mCamera " + e.getMessage());
|
|
||||||
mBus.post(new Events.CameraUnavailable());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkFlashlight() {
|
|
||||||
if (mIsFlashlightOn) {
|
|
||||||
enableFlashlight();
|
|
||||||
} else {
|
|
||||||
disableFlashlight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableFlashlight() {
|
|
||||||
mShouldStroboscopeStop = true;
|
|
||||||
if (mIsStroboscopeRunning) {
|
|
||||||
mShouldEnableFlashlight = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIsFlashlightOn = true;
|
|
||||||
if (mIsMarshmallow) {
|
|
||||||
toggleMarshmallowFlashlight(true);
|
|
||||||
} else {
|
|
||||||
if (mCamera == null || mParams == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
|
|
||||||
mCamera.setParameters(mParams);
|
|
||||||
mCamera.startPreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
Runnable mainRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mBus.post(new Events.StateChanged(true));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
new Handler(mContext.getMainLooper()).post(mainRunnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableFlashlight() {
|
|
||||||
if (mIsStroboscopeRunning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIsFlashlightOn = false;
|
|
||||||
if (mIsMarshmallow) {
|
|
||||||
toggleMarshmallowFlashlight(false);
|
|
||||||
} else {
|
|
||||||
if (mCamera == null || mParams == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
|
|
||||||
mCamera.setParameters(mParams);
|
|
||||||
}
|
|
||||||
mBus.post(new Events.StateChanged(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toggleMarshmallowFlashlight(boolean enable) {
|
|
||||||
mMarshmallowCamera.toggleMarshmallowFlashlight(mBus, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void releaseCamera() {
|
|
||||||
if (mIsFlashlightOn) {
|
|
||||||
disableFlashlight();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCamera != null) {
|
|
||||||
mCamera.release();
|
|
||||||
mCamera = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mBus != null) {
|
|
||||||
mBus.unregister(this);
|
|
||||||
}
|
|
||||||
mIsFlashlightOn = false;
|
|
||||||
mShouldStroboscopeStop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isMarshmallow() {
|
|
||||||
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Runnable stroboscope = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (mIsStroboscopeRunning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mShouldStroboscopeStop = false;
|
|
||||||
mIsStroboscopeRunning = true;
|
|
||||||
|
|
||||||
if (Utils.isNougat()) {
|
|
||||||
while (!mShouldStroboscopeStop) {
|
|
||||||
try {
|
|
||||||
mMarshmallowCamera.toggleMarshmallowFlashlight(mBus, true);
|
|
||||||
Thread.sleep(mStroboFrequency);
|
|
||||||
mMarshmallowCamera.toggleMarshmallowFlashlight(mBus, false);
|
|
||||||
Thread.sleep(mStroboFrequency);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
mShouldStroboscopeStop = true;
|
|
||||||
} catch (RuntimeException ignored) {
|
|
||||||
mShouldStroboscopeStop = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (mCamera == null) {
|
|
||||||
initCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
Camera.Parameters torchOn = mCamera.getParameters();
|
|
||||||
Camera.Parameters torchOff = mCamera.getParameters();
|
|
||||||
torchOn.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
|
|
||||||
torchOff.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
|
|
||||||
|
|
||||||
SurfaceTexture dummy = new SurfaceTexture(1);
|
|
||||||
try {
|
|
||||||
mCamera.setPreviewTexture(dummy);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "setup stroboscope1 " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
mCamera.startPreview();
|
|
||||||
|
|
||||||
while (!mShouldStroboscopeStop) {
|
|
||||||
try {
|
|
||||||
mCamera.setParameters(torchOn);
|
|
||||||
Thread.sleep(mStroboFrequency);
|
|
||||||
mCamera.setParameters(torchOff);
|
|
||||||
Thread.sleep(mStroboFrequency);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
mShouldStroboscopeStop = true;
|
|
||||||
} catch (RuntimeException ignored) {
|
|
||||||
mShouldStroboscopeStop = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (mCamera != null) {
|
|
||||||
mCamera.setParameters(torchOff);
|
|
||||||
if (!mShouldEnableFlashlight || mIsMarshmallow) {
|
|
||||||
mCamera.release();
|
|
||||||
mCamera = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
Log.e(TAG, "setup stroboscope2 " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mIsStroboscopeRunning = false;
|
|
||||||
mShouldStroboscopeStop = false;
|
|
||||||
|
|
||||||
if (mShouldEnableFlashlight) {
|
|
||||||
enableFlashlight();
|
|
||||||
mShouldEnableFlashlight = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.helpers;
|
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.appwidget.AppWidgetManager;
|
|
||||||
import android.appwidget.AppWidgetProvider;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.PorterDuff;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.widget.RemoteViews;
|
|
||||||
|
|
||||||
import com.simplemobiletools.flashlight.R;
|
|
||||||
import com.simplemobiletools.flashlight.models.Events;
|
|
||||||
import com.squareup.otto.Bus;
|
|
||||||
import com.squareup.otto.Subscribe;
|
|
||||||
|
|
||||||
public class MyWidgetProvider extends AppWidgetProvider {
|
|
||||||
private static final String TOGGLE = "toggle";
|
|
||||||
private static MyCameraImpl mCameraImpl;
|
|
||||||
private static RemoteViews mRemoteViews;
|
|
||||||
private static AppWidgetManager mWidgetManager;
|
|
||||||
private static Bitmap mColoredBmp;
|
|
||||||
private static Bitmap mWhiteBmp;
|
|
||||||
private static Bus mBus;
|
|
||||||
private static Context mContext;
|
|
||||||
|
|
||||||
private static int[] mWidgetIds;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
|
||||||
initVariables(context);
|
|
||||||
appWidgetManager.updateAppWidget(appWidgetIds, mRemoteViews);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initVariables(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
final ComponentName component = new ComponentName(context, MyWidgetProvider.class);
|
|
||||||
mWidgetManager = AppWidgetManager.getInstance(context);
|
|
||||||
mWidgetIds = mWidgetManager.getAppWidgetIds(component);
|
|
||||||
|
|
||||||
final Intent intent = new Intent(context, MyWidgetProvider.class);
|
|
||||||
intent.setAction(TOGGLE);
|
|
||||||
|
|
||||||
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
|
||||||
mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
|
|
||||||
mRemoteViews.setOnClickPendingIntent(R.id.toggle_btn, pendingIntent);
|
|
||||||
mCameraImpl = new MyCameraImpl(context);
|
|
||||||
|
|
||||||
final SharedPreferences prefs = initPrefs(context);
|
|
||||||
final Resources res = context.getResources();
|
|
||||||
final int defaultColor = res.getColor(R.color.colorPrimary);
|
|
||||||
final int selectedColor = prefs.getInt(Constants.WIDGET_COLOR, defaultColor);
|
|
||||||
final int alpha = Color.alpha(selectedColor);
|
|
||||||
|
|
||||||
mColoredBmp = getColoredCircles(selectedColor, alpha);
|
|
||||||
mWhiteBmp = getColoredCircles(Color.WHITE, alpha);
|
|
||||||
mRemoteViews.setImageViewBitmap(R.id.toggle_btn, mWhiteBmp);
|
|
||||||
|
|
||||||
if (mBus == null) {
|
|
||||||
mBus = BusProvider.getInstance();
|
|
||||||
}
|
|
||||||
registerBus();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
final String action = intent.getAction();
|
|
||||||
if (action.equals(TOGGLE)) {
|
|
||||||
if (mCameraImpl == null || mBus == null) {
|
|
||||||
initVariables(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
mCameraImpl.toggleFlashlight();
|
|
||||||
} else
|
|
||||||
super.onReceive(context, intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bitmap getColoredCircles(int color, int alpha) {
|
|
||||||
final Drawable drawable = mContext.getResources().getDrawable(R.drawable.circles_small);
|
|
||||||
drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
|
||||||
drawable.mutate().setAlpha(alpha);
|
|
||||||
return Utils.drawableToBitmap(drawable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableFlashlight() {
|
|
||||||
mRemoteViews.setImageViewBitmap(R.id.toggle_btn, mColoredBmp);
|
|
||||||
for (int widgetId : mWidgetIds) {
|
|
||||||
mWidgetManager.updateAppWidget(widgetId, mRemoteViews);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disableFlashlight() {
|
|
||||||
mRemoteViews.setImageViewBitmap(R.id.toggle_btn, mWhiteBmp);
|
|
||||||
for (int widgetId : mWidgetIds) {
|
|
||||||
mWidgetManager.updateAppWidget(widgetId, mRemoteViews);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private SharedPreferences initPrefs(Context context) {
|
|
||||||
return context.getSharedPreferences(Constants.PREFS_KEY, Context.MODE_PRIVATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void cameraUnavailable(Events.CameraUnavailable event) {
|
|
||||||
if (mContext != null) {
|
|
||||||
Utils.showToast(mContext, R.string.camera_error);
|
|
||||||
disableFlashlight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void stateChangedEvent(Events.StateChanged event) {
|
|
||||||
if (event.getIsEnabled()) {
|
|
||||||
enableFlashlight();
|
|
||||||
} else {
|
|
||||||
disableFlashlight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDeleted(Context context, int[] appWidgetIds) {
|
|
||||||
super.onDeleted(context, appWidgetIds);
|
|
||||||
unregisterBus();
|
|
||||||
releaseCamera(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void releaseCamera(Context context) {
|
|
||||||
if (mCameraImpl == null)
|
|
||||||
initVariables(context);
|
|
||||||
|
|
||||||
mCameraImpl.releaseCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerBus() {
|
|
||||||
try {
|
|
||||||
mBus.register(this);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unregisterBus() {
|
|
||||||
try {
|
|
||||||
mBus.unregister(this);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.helpers;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
public class Utils {
|
|
||||||
public static Bitmap drawableToBitmap(Drawable drawable) {
|
|
||||||
final int width = drawable.getIntrinsicWidth();
|
|
||||||
final int height = drawable.getIntrinsicHeight();
|
|
||||||
final Bitmap mutableBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
final Canvas canvas = new Canvas(mutableBitmap);
|
|
||||||
drawable.setBounds(0, 0, width, height);
|
|
||||||
drawable.draw(canvas);
|
|
||||||
return mutableBitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showToast(Context context, int resId) {
|
|
||||||
Toast.makeText(context, context.getResources().getString(resId), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isNougat() {
|
|
||||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.models;
|
|
||||||
|
|
||||||
public class Events {
|
|
||||||
public static class StateChanged {
|
|
||||||
private static boolean mIsEnabled;
|
|
||||||
|
|
||||||
public StateChanged(boolean isEnabled) {
|
|
||||||
mIsEnabled = isEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getIsEnabled() {
|
|
||||||
return mIsEnabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CameraUnavailable {
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.simplemobiletools.flashlight.activities
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.WindowManager
|
||||||
|
|
||||||
|
import com.simplemobiletools.flashlight.R
|
||||||
|
|
||||||
|
class BrightDisplayActivity : SimpleActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_bright_display)
|
||||||
|
supportActionBar?.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
toggleBrightness(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
toggleBrightness(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toggleBrightness(increase: Boolean) {
|
||||||
|
val layout = window.attributes
|
||||||
|
layout.screenBrightness = (if (increase) 1 else 0).toFloat()
|
||||||
|
window.attributes = layout
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,224 @@
|
|||||||
|
package com.simplemobiletools.flashlight.activities
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.PorterDuff
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v4.app.ActivityCompat
|
||||||
|
import android.support.v4.content.ContextCompat
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.SeekBar
|
||||||
|
import butterknife.ButterKnife
|
||||||
|
import butterknife.OnClick
|
||||||
|
import com.simplemobiletools.commons.activities.AboutActivity
|
||||||
|
import com.simplemobiletools.commons.extensions.beInvisible
|
||||||
|
import com.simplemobiletools.commons.helpers.LICENSE_KOTLIN
|
||||||
|
import com.simplemobiletools.commons.helpers.LICENSE_OTTO
|
||||||
|
import com.simplemobiletools.flashlight.BuildConfig
|
||||||
|
import com.simplemobiletools.flashlight.R
|
||||||
|
import com.simplemobiletools.flashlight.extensions.config
|
||||||
|
import com.simplemobiletools.flashlight.helpers.BusProvider
|
||||||
|
import com.simplemobiletools.flashlight.helpers.MyCameraImpl
|
||||||
|
import com.simplemobiletools.flashlight.helpers.Utils
|
||||||
|
import com.simplemobiletools.flashlight.models.Events
|
||||||
|
import com.squareup.otto.Bus
|
||||||
|
import com.squareup.otto.Subscribe
|
||||||
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
|
|
||||||
|
class MainActivity : SimpleActivity() {
|
||||||
|
companion object {
|
||||||
|
private val CAMERA_PERMISSION = 1
|
||||||
|
private val MAX_STROBO_DELAY = 2000
|
||||||
|
private val MIN_STROBO_DELAY = 30
|
||||||
|
|
||||||
|
private var mBus: Bus? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private var mCameraImpl: MyCameraImpl? = null
|
||||||
|
private var mJustGrantedPermission: Boolean = false
|
||||||
|
|
||||||
|
private val isCameraPermissionGranted: Boolean
|
||||||
|
get() = ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
ButterKnife.bind(this)
|
||||||
|
|
||||||
|
mBus = BusProvider.instance
|
||||||
|
changeIconColor(R.color.translucent_white, bright_display_btn)
|
||||||
|
changeIconColor(R.color.translucent_white, stroboscope_btn)
|
||||||
|
stroboscope_bar.max = MAX_STROBO_DELAY - MIN_STROBO_DELAY
|
||||||
|
stroboscope_bar.progress = stroboscope_bar.max / 2
|
||||||
|
|
||||||
|
stroboscope_bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||||
|
override fun onProgressChanged(seekBar: SeekBar, progress: Int, b: Boolean) {
|
||||||
|
val frequency = stroboscope_bar.max - progress + MIN_STROBO_DELAY
|
||||||
|
if (mCameraImpl != null)
|
||||||
|
mCameraImpl!!.setStroboFrequency(frequency)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartTrackingTouch(seekBar: SeekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
menuInflater.inflate(R.menu.menu, menu)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.settings -> {
|
||||||
|
startActivity(Intent(applicationContext, SettingsActivity::class.java))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.about -> {
|
||||||
|
startActivity(Intent(applicationContext, AboutActivity::class.java))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else -> return super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchSettings() {
|
||||||
|
startActivity(Intent(applicationContext, SettingsActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchAbout() {
|
||||||
|
startAboutActivity(R.string.app_name, LICENSE_KOTLIN or LICENSE_OTTO, BuildConfig.VERSION_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupCameraImpl() {
|
||||||
|
mCameraImpl = MyCameraImpl(this)
|
||||||
|
mCameraImpl!!.enableFlashlight()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.toggle_btn)
|
||||||
|
fun toggleFlashlight() {
|
||||||
|
mCameraImpl!!.toggleFlashlight()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.bright_display_btn)
|
||||||
|
fun launchBrightDisplay() {
|
||||||
|
startActivity(Intent(applicationContext, BrightDisplayActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.stroboscope_btn)
|
||||||
|
fun tryToggleStroboscope() {
|
||||||
|
toggleStroboscope()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toggleStroboscope() {
|
||||||
|
// use the old Camera API for stroboscope, the new Camera Manager is way too slow
|
||||||
|
if (isCameraPermissionGranted || Utils.isNougat) {
|
||||||
|
if (mCameraImpl!!.toggleStroboscope()) {
|
||||||
|
stroboscope_bar.visibility = if (stroboscope_bar.visibility == View.VISIBLE) View.INVISIBLE else View.VISIBLE
|
||||||
|
changeIconColor(if (stroboscope_bar.visibility == View.VISIBLE) R.color.colorPrimary else R.color.translucent_white, stroboscope_btn)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val permissions = arrayOf(Manifest.permission.CAMERA)
|
||||||
|
ActivityCompat.requestPermissions(this, permissions, CAMERA_PERMISSION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
|
||||||
|
if (requestCode == CAMERA_PERMISSION) {
|
||||||
|
mJustGrantedPermission = true
|
||||||
|
if (isCameraPermissionGranted) {
|
||||||
|
toggleStroboscope()
|
||||||
|
} else {
|
||||||
|
Utils.showToast(applicationContext, R.string.camera_permission)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
mBus!!.register(this)
|
||||||
|
|
||||||
|
if (mCameraImpl == null) {
|
||||||
|
setupCameraImpl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
if (mJustGrantedPermission) {
|
||||||
|
mJustGrantedPermission = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mCameraImpl!!.handleCameraSetup()
|
||||||
|
mCameraImpl!!.checkFlashlight()
|
||||||
|
|
||||||
|
bright_display_btn!!.visibility = if (config.brightDisplay) View.VISIBLE else View.GONE
|
||||||
|
stroboscope_btn!!.visibility = if (config.stroboscope) View.VISIBLE else View.GONE
|
||||||
|
if (!config.stroboscope) {
|
||||||
|
mCameraImpl!!.stopStroboscope()
|
||||||
|
stroboscope_bar.visibility = View.INVISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
mBus!!.unregister(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
releaseCamera()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun releaseCamera() {
|
||||||
|
if (mCameraImpl != null) {
|
||||||
|
mCameraImpl!!.releaseCamera()
|
||||||
|
mCameraImpl = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
fun stateChangedEvent(event: Events.StateChanged) {
|
||||||
|
if (event.isEnabled) {
|
||||||
|
enableFlashlight()
|
||||||
|
} else {
|
||||||
|
disableFlashlight()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enableFlashlight() {
|
||||||
|
changeIconColor(R.color.colorPrimary, toggle_btn)
|
||||||
|
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
|
||||||
|
changeIconColor(R.color.translucent_white, stroboscope_btn)
|
||||||
|
stroboscope_bar.beInvisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun disableFlashlight() {
|
||||||
|
changeIconColor(R.color.translucent_white, toggle_btn)
|
||||||
|
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun changeIconColor(colorId: Int, imageView: ImageView?) {
|
||||||
|
val appColor = resources.getColor(colorId)
|
||||||
|
imageView!!.background.mutate().setColorFilter(appColor, PorterDuff.Mode.SRC_IN)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
fun cameraUnavailable(event: Events.CameraUnavailable) {
|
||||||
|
Utils.showToast(this, R.string.camera_error)
|
||||||
|
disableFlashlight()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.simplemobiletools.flashlight.activities
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v4.app.TaskStackBuilder
|
||||||
|
import android.support.v7.widget.SwitchCompat
|
||||||
|
import butterknife.BindView
|
||||||
|
import butterknife.ButterKnife
|
||||||
|
import butterknife.OnClick
|
||||||
|
import com.simplemobiletools.flashlight.R
|
||||||
|
import com.simplemobiletools.flashlight.helpers.Config
|
||||||
|
|
||||||
|
class SettingsActivity : SimpleActivity() {
|
||||||
|
@BindView(R.id.settings_bright_display) internal var mBrightDisplaySwitch: SwitchCompat? = null
|
||||||
|
@BindView(R.id.settings_stroboscope) internal var mStroboscopeSwitch: SwitchCompat? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_settings)
|
||||||
|
mConfig = Config.newInstance(applicationContext)
|
||||||
|
ButterKnife.bind(this)
|
||||||
|
|
||||||
|
setupBrightDisplay()
|
||||||
|
setupStroboscope()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupBrightDisplay() {
|
||||||
|
mBrightDisplaySwitch!!.isChecked = mConfig!!.brightDisplay
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupStroboscope() {
|
||||||
|
mStroboscopeSwitch!!.isChecked = mConfig!!.stroboscope
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.settings_bright_display_holder)
|
||||||
|
fun handleBrightDisplay() {
|
||||||
|
mBrightDisplaySwitch!!.isChecked = !mBrightDisplaySwitch!!.isChecked
|
||||||
|
mConfig!!.brightDisplay = mBrightDisplaySwitch!!.isChecked
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.settings_stroboscope_holder)
|
||||||
|
fun handleStroboscope() {
|
||||||
|
mStroboscopeSwitch!!.isChecked = !mStroboscopeSwitch!!.isChecked
|
||||||
|
mConfig!!.stroboscope = mStroboscopeSwitch!!.isChecked
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun restartActivity() {
|
||||||
|
TaskStackBuilder.create(applicationContext).addNextIntentWithParentStack(intent).startActivities()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private var mConfig: Config? = null
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.simplemobiletools.flashlight.activities
|
||||||
|
|
||||||
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
|
|
||||||
|
open class SimpleActivity : BaseSimpleActivity()
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.simplemobiletools.flashlight.activities
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v7.app.AppCompatActivity
|
||||||
|
|
||||||
|
class SplashActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
startActivity(Intent(this, MainActivity::class.java))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,137 @@
|
|||||||
|
package com.simplemobiletools.flashlight.activities
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.PorterDuff
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v7.app.AppCompatActivity
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.RemoteViews
|
||||||
|
import android.widget.SeekBar
|
||||||
|
import butterknife.BindView
|
||||||
|
import butterknife.ButterKnife
|
||||||
|
import butterknife.OnClick
|
||||||
|
import com.simplemobiletools.commons.helpers.PREFS_KEY
|
||||||
|
import com.simplemobiletools.flashlight.R
|
||||||
|
import com.simplemobiletools.flashlight.helpers.MyWidgetProvider
|
||||||
|
import com.simplemobiletools.flashlight.helpers.WIDGET_COLOR
|
||||||
|
import yuku.ambilwarna.AmbilWarnaDialog
|
||||||
|
|
||||||
|
class WidgetConfigureActivity : AppCompatActivity() {
|
||||||
|
@BindView(R.id.config_widget_seekbar) internal var mWidgetSeekBar: SeekBar? = null
|
||||||
|
@BindView(R.id.config_widget_color) internal var mWidgetColorPicker: View? = null
|
||||||
|
@BindView(R.id.config_image) internal var mImage: ImageView? = null
|
||||||
|
|
||||||
|
private val seekbarChangeListener = object : SeekBar.OnSeekBarChangeListener {
|
||||||
|
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||||
|
mWidgetAlpha = progress.toFloat() / 100.toFloat()
|
||||||
|
updateColors()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartTrackingTouch(seekBar: SeekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setResult(Activity.RESULT_CANCELED)
|
||||||
|
setContentView(R.layout.widget_config)
|
||||||
|
ButterKnife.bind(this)
|
||||||
|
initVariables()
|
||||||
|
|
||||||
|
val intent = intent
|
||||||
|
val extras = intent.extras
|
||||||
|
if (extras != null)
|
||||||
|
mWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
|
||||||
|
|
||||||
|
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initVariables() {
|
||||||
|
val prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
|
||||||
|
mWidgetColor = prefs.getInt(WIDGET_COLOR, 1)
|
||||||
|
if (mWidgetColor == 1) {
|
||||||
|
mWidgetColor = resources.getColor(R.color.colorPrimary)
|
||||||
|
mWidgetAlpha = 1f
|
||||||
|
} else {
|
||||||
|
mWidgetAlpha = Color.alpha(mWidgetColor) / 255.toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
mWidgetColorWithoutTransparency = Color.rgb(Color.red(mWidgetColor), Color.green(mWidgetColor), Color.blue(mWidgetColor))
|
||||||
|
mWidgetSeekBar!!.setOnSeekBarChangeListener(seekbarChangeListener)
|
||||||
|
mWidgetSeekBar!!.progress = (mWidgetAlpha * 100).toInt()
|
||||||
|
updateColors()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.config_save)
|
||||||
|
fun saveConfig() {
|
||||||
|
val appWidgetManager = AppWidgetManager.getInstance(this)
|
||||||
|
val views = RemoteViews(packageName, R.layout.widget)
|
||||||
|
appWidgetManager.updateAppWidget(mWidgetId, views)
|
||||||
|
|
||||||
|
storeWidgetColors()
|
||||||
|
requestWidgetUpdate()
|
||||||
|
|
||||||
|
val resultValue = Intent()
|
||||||
|
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
|
||||||
|
setResult(Activity.RESULT_OK, resultValue)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.config_widget_color)
|
||||||
|
fun pickBackgroundColor() {
|
||||||
|
val dialog = AmbilWarnaDialog(this, mWidgetColorWithoutTransparency, object : AmbilWarnaDialog.OnAmbilWarnaListener {
|
||||||
|
override fun onCancel(dialog: AmbilWarnaDialog) {}
|
||||||
|
|
||||||
|
override fun onOk(dialog: AmbilWarnaDialog, color: Int) {
|
||||||
|
mWidgetColorWithoutTransparency = color
|
||||||
|
updateColors()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun storeWidgetColors() {
|
||||||
|
val prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
|
||||||
|
prefs.edit().putInt(WIDGET_COLOR, mWidgetColor).apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestWidgetUpdate() {
|
||||||
|
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetProvider::class.java)
|
||||||
|
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(mWidgetId))
|
||||||
|
sendBroadcast(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateColors() {
|
||||||
|
mWidgetColor = adjustAlpha(mWidgetColorWithoutTransparency, mWidgetAlpha)
|
||||||
|
mWidgetColorPicker!!.setBackgroundColor(mWidgetColor)
|
||||||
|
mImage!!.background.mutate().setColorFilter(mWidgetColor, PorterDuff.Mode.SRC_IN)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun adjustAlpha(color: Int, factor: Float): Int {
|
||||||
|
val alpha = Math.round(Color.alpha(color) * factor)
|
||||||
|
val red = Color.red(color)
|
||||||
|
val green = Color.green(color)
|
||||||
|
val blue = Color.blue(color)
|
||||||
|
return Color.argb(alpha, red, green, blue)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private var mWidgetAlpha: Float = 0.toFloat()
|
||||||
|
private var mWidgetId: Int = 0
|
||||||
|
private var mWidgetColor: Int = 0
|
||||||
|
private var mWidgetColorWithoutTransparency: Int = 0
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.simplemobiletools.flashlight.extensions
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.simplemobiletools.flashlight.helpers.Config
|
||||||
|
|
||||||
|
val Context.config: Config get() = Config.newInstance(this)
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
import com.squareup.otto.Bus
|
||||||
|
|
||||||
|
object BusProvider {
|
||||||
|
val instance = Bus()
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.simplemobiletools.commons.helpers.BaseConfig
|
||||||
|
|
||||||
|
class Config(context: Context) : BaseConfig(context) {
|
||||||
|
companion object {
|
||||||
|
fun newInstance(context: Context) = Config(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
var brightDisplay: Boolean
|
||||||
|
get() = prefs.getBoolean(BRIGHT_DISPLAY, true)
|
||||||
|
set(brightDisplay) = prefs.edit().putBoolean(BRIGHT_DISPLAY, brightDisplay).apply()
|
||||||
|
|
||||||
|
var stroboscope: Boolean
|
||||||
|
get() = prefs.getBoolean(STROBOSCOPE, true)
|
||||||
|
set(stroboscope) = prefs.edit().putBoolean(STROBOSCOPE, stroboscope).apply()
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
val BRIGHT_DISPLAY = "bright_display"
|
||||||
|
val STROBOSCOPE = "stroboscope"
|
||||||
|
val WIDGET_COLOR = "widget_color"
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.content.Context
|
||||||
|
import android.hardware.camera2.CameraAccessException
|
||||||
|
import android.hardware.camera2.CameraManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Handler
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
|
import com.simplemobiletools.flashlight.models.Events
|
||||||
|
import com.squareup.otto.Bus
|
||||||
|
|
||||||
|
internal class MarshmallowCamera @TargetApi(Build.VERSION_CODES.M)
|
||||||
|
constructor(private val mContext: Context) {
|
||||||
|
|
||||||
|
private val manager: CameraManager
|
||||||
|
private var cameraId: String? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
manager = mContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||||
|
try {
|
||||||
|
val list = manager.cameraIdList
|
||||||
|
cameraId = list[0]
|
||||||
|
} catch (ignored: CameraAccessException) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.M)
|
||||||
|
fun toggleMarshmallowFlashlight(bus: Bus, enable: Boolean) {
|
||||||
|
try {
|
||||||
|
manager.setTorchMode(cameraId!!, enable)
|
||||||
|
} catch (e: CameraAccessException) {
|
||||||
|
Log.e(TAG, "toggle marshmallow flashlight " + e.message)
|
||||||
|
|
||||||
|
val mainRunnable = Runnable { bus.post(Events.CameraUnavailable()) }
|
||||||
|
Handler(mContext.mainLooper).post(mainRunnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = MyCameraImpl::class.java.simpleName
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,271 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.SurfaceTexture
|
||||||
|
import android.hardware.Camera
|
||||||
|
import android.os.Handler
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
|
import com.simplemobiletools.flashlight.R
|
||||||
|
import com.simplemobiletools.flashlight.models.Events
|
||||||
|
import com.squareup.otto.Bus
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
class MyCameraImpl(private val mContext: Context) {
|
||||||
|
companion object {
|
||||||
|
private val TAG = MyCameraImpl::class.java.simpleName
|
||||||
|
|
||||||
|
private var mCamera: Camera? = null
|
||||||
|
private var mParams: Camera.Parameters? = null
|
||||||
|
private var mBus: Bus? = null
|
||||||
|
|
||||||
|
private var mIsFlashlightOn: Boolean = false
|
||||||
|
private var mIsMarshmallow: Boolean = false
|
||||||
|
private var mShouldEnableFlashlight: Boolean = false
|
||||||
|
private var mStroboFrequency: Int = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private var mMarshmallowCamera: MarshmallowCamera? = null
|
||||||
|
@Volatile private var mShouldStroboscopeStop: Boolean = false
|
||||||
|
@Volatile private var mIsStroboscopeRunning: Boolean = false
|
||||||
|
|
||||||
|
private val isMarshmallow: Boolean
|
||||||
|
get() = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M
|
||||||
|
|
||||||
|
private val stroboscope = Runnable {
|
||||||
|
if (mIsStroboscopeRunning) {
|
||||||
|
return@Runnable
|
||||||
|
}
|
||||||
|
|
||||||
|
mShouldStroboscopeStop = false
|
||||||
|
mIsStroboscopeRunning = true
|
||||||
|
|
||||||
|
if (Utils.isNougat) {
|
||||||
|
while (!mShouldStroboscopeStop) {
|
||||||
|
try {
|
||||||
|
mMarshmallowCamera!!.toggleMarshmallowFlashlight(mBus!!, true)
|
||||||
|
Thread.sleep(mStroboFrequency.toLong())
|
||||||
|
mMarshmallowCamera!!.toggleMarshmallowFlashlight(mBus!!, false)
|
||||||
|
Thread.sleep(mStroboFrequency.toLong())
|
||||||
|
} catch (ignored: InterruptedException) {
|
||||||
|
mShouldStroboscopeStop = true
|
||||||
|
} catch (ignored: RuntimeException) {
|
||||||
|
mShouldStroboscopeStop = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mCamera == null) {
|
||||||
|
initCamera()
|
||||||
|
}
|
||||||
|
|
||||||
|
val torchOn = mCamera!!.parameters
|
||||||
|
val torchOff = mCamera!!.parameters
|
||||||
|
torchOn.flashMode = Camera.Parameters.FLASH_MODE_TORCH
|
||||||
|
torchOff.flashMode = Camera.Parameters.FLASH_MODE_OFF
|
||||||
|
|
||||||
|
val dummy = SurfaceTexture(1)
|
||||||
|
try {
|
||||||
|
mCamera!!.setPreviewTexture(dummy)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Log.e(TAG, "setup stroboscope1 " + e.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
mCamera!!.startPreview()
|
||||||
|
|
||||||
|
while (!mShouldStroboscopeStop) {
|
||||||
|
try {
|
||||||
|
mCamera!!.parameters = torchOn
|
||||||
|
Thread.sleep(mStroboFrequency.toLong())
|
||||||
|
mCamera!!.parameters = torchOff
|
||||||
|
Thread.sleep(mStroboFrequency.toLong())
|
||||||
|
} catch (ignored: InterruptedException) {
|
||||||
|
mShouldStroboscopeStop = true
|
||||||
|
} catch (ignored: RuntimeException) {
|
||||||
|
mShouldStroboscopeStop = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (mCamera != null) {
|
||||||
|
mCamera!!.parameters = torchOff
|
||||||
|
if (!mShouldEnableFlashlight || mIsMarshmallow) {
|
||||||
|
mCamera!!.release()
|
||||||
|
mCamera = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: RuntimeException) {
|
||||||
|
Log.e(TAG, "setup stroboscope2 " + e.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mIsStroboscopeRunning = false
|
||||||
|
mShouldStroboscopeStop = false
|
||||||
|
|
||||||
|
if (mShouldEnableFlashlight) {
|
||||||
|
enableFlashlight()
|
||||||
|
mShouldEnableFlashlight = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
mIsMarshmallow = isMarshmallow
|
||||||
|
mStroboFrequency = 1000
|
||||||
|
|
||||||
|
if (mBus == null) {
|
||||||
|
mBus = BusProvider.instance
|
||||||
|
mBus!!.register(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCameraSetup()
|
||||||
|
checkFlashlight()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toggleFlashlight() {
|
||||||
|
mIsFlashlightOn = !mIsFlashlightOn
|
||||||
|
handleCameraSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setStroboFrequency(frequency: Int) {
|
||||||
|
mStroboFrequency = frequency
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toggleStroboscope(): Boolean {
|
||||||
|
if (!mIsStroboscopeRunning)
|
||||||
|
disableFlashlight()
|
||||||
|
|
||||||
|
if (!Utils.isNougat) {
|
||||||
|
if (mCamera == null) {
|
||||||
|
initCamera()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCamera == null) {
|
||||||
|
Utils.showToast(mContext, R.string.camera_error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIsStroboscopeRunning) {
|
||||||
|
stopStroboscope()
|
||||||
|
} else {
|
||||||
|
Thread(stroboscope).start()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopStroboscope() {
|
||||||
|
mShouldStroboscopeStop = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleCameraSetup() {
|
||||||
|
if (mIsMarshmallow) {
|
||||||
|
setupMarshmallowCamera()
|
||||||
|
} else {
|
||||||
|
setupCamera()
|
||||||
|
}
|
||||||
|
checkFlashlight()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupMarshmallowCamera() {
|
||||||
|
if (mMarshmallowCamera == null) {
|
||||||
|
mMarshmallowCamera = MarshmallowCamera(mContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupCamera() {
|
||||||
|
if (mIsMarshmallow)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (mCamera == null) {
|
||||||
|
initCamera()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initCamera() {
|
||||||
|
try {
|
||||||
|
mCamera = Camera.open()
|
||||||
|
mParams = mCamera!!.parameters
|
||||||
|
mParams!!.flashMode = Camera.Parameters.FLASH_MODE_OFF
|
||||||
|
mCamera!!.parameters = mParams
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "setup mCamera " + e.message)
|
||||||
|
mBus!!.post(Events.CameraUnavailable())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkFlashlight() {
|
||||||
|
if (mIsFlashlightOn) {
|
||||||
|
enableFlashlight()
|
||||||
|
} else {
|
||||||
|
disableFlashlight()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enableFlashlight() {
|
||||||
|
mShouldStroboscopeStop = true
|
||||||
|
if (mIsStroboscopeRunning) {
|
||||||
|
mShouldEnableFlashlight = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mIsFlashlightOn = true
|
||||||
|
if (mIsMarshmallow) {
|
||||||
|
toggleMarshmallowFlashlight(true)
|
||||||
|
} else {
|
||||||
|
if (mCamera == null || mParams == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mParams!!.flashMode = Camera.Parameters.FLASH_MODE_TORCH
|
||||||
|
mCamera!!.parameters = mParams
|
||||||
|
mCamera!!.startPreview()
|
||||||
|
}
|
||||||
|
|
||||||
|
val mainRunnable = Runnable { mBus!!.post(Events.StateChanged(true)) }
|
||||||
|
Handler(mContext.mainLooper).post(mainRunnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun disableFlashlight() {
|
||||||
|
if (mIsStroboscopeRunning) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mIsFlashlightOn = false
|
||||||
|
if (mIsMarshmallow) {
|
||||||
|
toggleMarshmallowFlashlight(false)
|
||||||
|
} else {
|
||||||
|
if (mCamera == null || mParams == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mParams!!.flashMode = Camera.Parameters.FLASH_MODE_OFF
|
||||||
|
mCamera!!.parameters = mParams
|
||||||
|
}
|
||||||
|
mBus!!.post(Events.StateChanged(false))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toggleMarshmallowFlashlight(enable: Boolean) {
|
||||||
|
mMarshmallowCamera!!.toggleMarshmallowFlashlight(mBus!!, enable)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun releaseCamera() {
|
||||||
|
if (mIsFlashlightOn) {
|
||||||
|
disableFlashlight()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCamera != null) {
|
||||||
|
mCamera!!.release()
|
||||||
|
mCamera = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBus != null) {
|
||||||
|
mBus!!.unregister(this)
|
||||||
|
}
|
||||||
|
mIsFlashlightOn = false
|
||||||
|
mShouldStroboscopeStop = true
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,152 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.appwidget.AppWidgetProvider
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.PorterDuff
|
||||||
|
import android.widget.RemoteViews
|
||||||
|
import com.simplemobiletools.commons.helpers.PREFS_KEY
|
||||||
|
import com.simplemobiletools.flashlight.R
|
||||||
|
import com.simplemobiletools.flashlight.models.Events
|
||||||
|
import com.squareup.otto.Bus
|
||||||
|
import com.squareup.otto.Subscribe
|
||||||
|
|
||||||
|
class MyWidgetProvider : AppWidgetProvider() {
|
||||||
|
|
||||||
|
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||||
|
initVariables(context)
|
||||||
|
appWidgetManager.updateAppWidget(appWidgetIds, mRemoteViews)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initVariables(context: Context) {
|
||||||
|
mContext = context
|
||||||
|
val component = ComponentName(context, MyWidgetProvider::class.java)
|
||||||
|
mWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
|
mWidgetIds = mWidgetManager!!.getAppWidgetIds(component)
|
||||||
|
|
||||||
|
val intent = Intent(context, MyWidgetProvider::class.java)
|
||||||
|
intent.action = TOGGLE
|
||||||
|
|
||||||
|
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0)
|
||||||
|
mRemoteViews = RemoteViews(context.packageName, R.layout.widget)
|
||||||
|
mRemoteViews!!.setOnClickPendingIntent(R.id.toggle_btn, pendingIntent)
|
||||||
|
mCameraImpl = MyCameraImpl(context)
|
||||||
|
|
||||||
|
val prefs = initPrefs(context)
|
||||||
|
val res = context.resources
|
||||||
|
val defaultColor = res.getColor(R.color.colorPrimary)
|
||||||
|
val selectedColor = prefs.getInt(WIDGET_COLOR, defaultColor)
|
||||||
|
val alpha = Color.alpha(selectedColor)
|
||||||
|
|
||||||
|
mColoredBmp = getColoredCircles(selectedColor, alpha)
|
||||||
|
mWhiteBmp = getColoredCircles(Color.WHITE, alpha)
|
||||||
|
mRemoteViews!!.setImageViewBitmap(R.id.toggle_btn, mWhiteBmp)
|
||||||
|
|
||||||
|
if (mBus == null) {
|
||||||
|
mBus = BusProvider.instance
|
||||||
|
}
|
||||||
|
registerBus()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
val action = intent.action
|
||||||
|
if (action == TOGGLE) {
|
||||||
|
if (mCameraImpl == null || mBus == null) {
|
||||||
|
initVariables(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
mCameraImpl!!.toggleFlashlight()
|
||||||
|
} else
|
||||||
|
super.onReceive(context, intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getColoredCircles(color: Int, alpha: Int): Bitmap {
|
||||||
|
val drawable = mContext!!.resources.getDrawable(R.drawable.circles_small)
|
||||||
|
drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
|
||||||
|
drawable.mutate().alpha = alpha
|
||||||
|
return Utils.drawableToBitmap(drawable)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enableFlashlight() {
|
||||||
|
mRemoteViews!!.setImageViewBitmap(R.id.toggle_btn, mColoredBmp)
|
||||||
|
for (widgetId in mWidgetIds!!) {
|
||||||
|
mWidgetManager!!.updateAppWidget(widgetId, mRemoteViews)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun disableFlashlight() {
|
||||||
|
mRemoteViews!!.setImageViewBitmap(R.id.toggle_btn, mWhiteBmp)
|
||||||
|
for (widgetId in mWidgetIds!!) {
|
||||||
|
mWidgetManager!!.updateAppWidget(widgetId, mRemoteViews)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initPrefs(context: Context): SharedPreferences {
|
||||||
|
return context.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
fun cameraUnavailable(event: Events.CameraUnavailable) {
|
||||||
|
if (mContext != null) {
|
||||||
|
Utils.showToast(mContext!!, R.string.camera_error)
|
||||||
|
disableFlashlight()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
fun stateChangedEvent(event: Events.StateChanged) {
|
||||||
|
if (event.isEnabled) {
|
||||||
|
enableFlashlight()
|
||||||
|
} else {
|
||||||
|
disableFlashlight()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
|
||||||
|
super.onDeleted(context, appWidgetIds)
|
||||||
|
unregisterBus()
|
||||||
|
releaseCamera(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun releaseCamera(context: Context) {
|
||||||
|
if (mCameraImpl == null)
|
||||||
|
initVariables(context)
|
||||||
|
|
||||||
|
mCameraImpl!!.releaseCamera()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerBus() {
|
||||||
|
try {
|
||||||
|
mBus!!.register(this)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unregisterBus() {
|
||||||
|
try {
|
||||||
|
mBus!!.unregister(this)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TOGGLE = "toggle"
|
||||||
|
private var mCameraImpl: MyCameraImpl? = null
|
||||||
|
private var mRemoteViews: RemoteViews? = null
|
||||||
|
private var mWidgetManager: AppWidgetManager? = null
|
||||||
|
private var mColoredBmp: Bitmap? = null
|
||||||
|
private var mWhiteBmp: Bitmap? = null
|
||||||
|
private var mBus: Bus? = null
|
||||||
|
private var mContext: Context? = null
|
||||||
|
|
||||||
|
private var mWidgetIds: IntArray? = null
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.os.Build
|
||||||
|
import android.widget.Toast
|
||||||
|
|
||||||
|
object Utils {
|
||||||
|
|
||||||
|
val isNougat: Boolean
|
||||||
|
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||||
|
|
||||||
|
fun drawableToBitmap(drawable: Drawable): Bitmap {
|
||||||
|
val width = drawable.intrinsicWidth
|
||||||
|
val height = drawable.intrinsicHeight
|
||||||
|
val mutableBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||||
|
val canvas = Canvas(mutableBitmap)
|
||||||
|
drawable.setBounds(0, 0, width, height)
|
||||||
|
drawable.draw(canvas)
|
||||||
|
return mutableBitmap
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showToast(context: Context, resId: Int) {
|
||||||
|
Toast.makeText(context, context.resources.getString(resId), Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.simplemobiletools.flashlight.models
|
||||||
|
|
||||||
|
class Events {
|
||||||
|
class StateChanged(isEnabled: Boolean) {
|
||||||
|
|
||||||
|
val isEnabled: Boolean
|
||||||
|
get() = mIsEnabled
|
||||||
|
|
||||||
|
init {
|
||||||
|
mIsEnabled = isEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var mIsEnabled: Boolean = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CameraUnavailable
|
||||||
|
}
|
@ -1,105 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ScrollView
|
|
||||||
android:id="@+id/about_scrollview"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:fillViewport="true">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/about_holder"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingBottom="@dimen/activity_margin"
|
|
||||||
android:paddingLeft="@dimen/activity_margin"
|
|
||||||
android:paddingTop="@dimen/activity_margin">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/about_website"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:autoLink="web"
|
|
||||||
android:text="@string/website"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/about_email_label"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@+id/about_website"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin"
|
|
||||||
android:text="@string/email_label"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/about_email"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@+id/about_email_label"
|
|
||||||
android:paddingBottom="@dimen/activity_margin"
|
|
||||||
android:text="@string/email"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/about_invite"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@+id/about_email"
|
|
||||||
android:paddingBottom="@dimen/activity_margin"
|
|
||||||
android:paddingTop="@dimen/activity_margin"
|
|
||||||
android:text="@string/invite_friends_underlined"
|
|
||||||
android:textColor="@color/colorPrimary"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/about_rate_us"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@+id/about_invite"
|
|
||||||
android:paddingBottom="@dimen/activity_margin"
|
|
||||||
android:paddingTop="@dimen/activity_margin"
|
|
||||||
android:text="@string/rate_us_underlined"
|
|
||||||
android:textColor="@color/colorPrimary"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/about_license"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@+id/about_rate_us"
|
|
||||||
android:paddingBottom="@dimen/activity_margin"
|
|
||||||
android:paddingTop="@dimen/activity_margin"
|
|
||||||
android:text="@string/third_party_licences_underlined"
|
|
||||||
android:textColor="@color/colorPrimary"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/about_follow_us"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@+id/about_license"
|
|
||||||
android:paddingBottom="@dimen/social_padding"
|
|
||||||
android:paddingTop="@dimen/activity_margin"
|
|
||||||
android:text="@string/follow_us"/>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/about_facebook"
|
|
||||||
android:layout_width="@dimen/social_logo"
|
|
||||||
android:layout_height="@dimen/social_logo"
|
|
||||||
android:layout_below="@+id/about_follow_us"
|
|
||||||
android:src="@mipmap/facebook"/>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/about_gplus"
|
|
||||||
android:layout_width="@dimen/social_logo"
|
|
||||||
android:layout_height="@dimen/social_logo"
|
|
||||||
android:layout_below="@+id/about_follow_us"
|
|
||||||
android:layout_marginLeft="@dimen/social_padding"
|
|
||||||
android:layout_toRightOf="@+id/about_facebook"
|
|
||||||
android:src="@mipmap/gplus"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/about_copyright"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_below="@+id/about_gplus"
|
|
||||||
android:gravity="center_horizontal|bottom"
|
|
||||||
android:paddingTop="@dimen/activity_margin"
|
|
||||||
android:text="v1.0\nCopyright © Simple Mobile Tools 2016"/>
|
|
||||||
</RelativeLayout>
|
|
||||||
</ScrollView>
|
|
@ -1,63 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ScrollView
|
|
||||||
android:id="@+id/license_holder"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/license"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="@dimen/activity_margin">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/notice"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/license_butterknife_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingTop="@dimen/activity_margin"
|
|
||||||
android:text="@string/butterknife_title"
|
|
||||||
android:textColor="@color/colorPrimary"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/license_butterknife_text"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/butterknife_text"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/license_ambilwarna_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingTop="@dimen/activity_margin"
|
|
||||||
android:text="@string/ambilwarna_title"
|
|
||||||
android:textColor="@color/colorPrimary"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/license_ambilwarna_text"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/ambilwarna_text"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/license_otto_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingTop="@dimen/activity_margin"
|
|
||||||
android:text="@string/otto_title"
|
|
||||||
android:textColor="@color/colorPrimary"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/license_otto_text"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/otto_text"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
@ -11,32 +11,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/settings_dark_theme_holder"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/settings_padding"
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:padding="@dimen/activity_margin">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/settings_dark_theme_label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:paddingLeft="@dimen/settings_padding"
|
|
||||||
android:text="@string/dark_theme"/>
|
|
||||||
|
|
||||||
<android.support.v7.widget.SwitchCompat
|
|
||||||
android:id="@+id/settings_dark_theme"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:background="@null"
|
|
||||||
android:clickable="false"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/settings_bright_display_holder"
|
android:id="@+id/settings_bright_display_holder"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user