Java tutorial
/* * Copyright 2016 Simon Zigelli * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ze.client.projecto.activity; import android.Manifest; import android.animation.ValueAnimator; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.os.Bundle; import android.support.annotation.ColorInt; import android.support.annotation.ColorRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.constraint.ConstraintLayout; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v4.app.LoaderManager; import android.support.v4.content.ContextCompat; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.content.res.ResourcesCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.SwitchCompat; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; import android.widget.TextView; import com.ze.client.projecto.Projecto; import com.ze.client.projecto.R; import com.ze.client.projecto.database.ProjectoContract; import com.ze.client.projecto.database.Projector; import com.ze.client.projecto.database.ProjectorDbHelper; import com.ze.client.projecto.fragment.SettingsFragment; import com.ze.client.projecto.projectorstrategy.NECProjectorStrategy; import com.ze.client.projecto.projectorstrategy.ProjectorException; import com.ze.client.projecto.projectorstrategy.ProjectorStrategy; import com.ze.client.projecto.projectorstrategy.ProjectorStrategyContext; import com.ze.client.projecto.utils.ColorUtils; import com.ze.client.projecto.utils.ProjectoPreferences; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import static com.ze.client.projecto.database.Projector.ProjectorStatus.F_OFF; import static com.ze.client.projecto.database.Projector.ProjectorStatus.F_ON; public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener, ProjectorStrategy.ProjectorCallback, LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemSelectedListener { private static final int LOADER = 3; private static final int PERMISSIONS_REQUEST_INTERNET = 17; public static final String TAG = "MainActivity"; public static final String ARG_SENDER = "sender"; private ProjectorStrategyContext mProjectorStrategyContext; private boolean mPermission = false; private CoordinatorLayout mCoordinatorLayout; private TextView mTextViewStatus; private ConstraintLayout mInfoLayout; private SwitchCompat mPowerSwitch; private Button mButtonPictureMute; private Spinner mProjectorsSpinner; private TextView mProjectorsSpinnerCaption; private Toolbar mToolbar; private List<Projector> mList = new ArrayList<>(); @Inject public ProjectoPreferences mPreferences; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Projecto.from(this).getComponent().inject(this); if (mPreferences.isKeepScreenOn()) getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); mToolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(mToolbar); if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); mList = new ArrayList<>(); Loader<Object> loader = getSupportLoaderManager().getLoader(LOADER); if (loader != null && !loader.isReset()) { restartLoader(LOADER, null, this); } else { initLoader(LOADER, null, this); } mPreferences.registerOnSharedPreferenceChangeListener(this); mCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinator_layout); mTextViewStatus = (TextView) findViewById(R.id.text_view_status); mInfoLayout = (ConstraintLayout) findViewById(R.id.info_layout); mPowerSwitch = (SwitchCompat) findViewById(R.id.projector_power); mButtonPictureMute = (Button) findViewById(R.id.button_picture_mute); mProjectorsSpinner = (Spinner) findViewById(R.id.spinner_projectors); mProjectorsSpinnerCaption = (TextView) findViewById(R.id.text_view_projector_spinner_caption); if (mProjectorsSpinner != null) mProjectorsSpinner.setOnItemSelectedListener(this); if (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.INTERNET)) { Snackbar.make(mCoordinatorLayout, R.string.message_network_permission, Snackbar.LENGTH_LONG).show(); } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.INTERNET }, PERMISSIONS_REQUEST_INTERNET); } } else { mPermission = true; } mProjectorStrategyContext = new ProjectorStrategyContext(); refresh(); refreshGui(mProjectorStrategyContext.getStrategy().getPowerStatus(), mProjectorStrategyContext.getStrategy().getPictureMuteStatus()); refreshState(); setPowerChangeListener(); if (mButtonPictureMute != null) { mButtonPictureMute.setOnClickListener(view -> { if (mPermission) mProjectorStrategyContext.togglePictureMute(); }); } } private void animateToolbarColorResource(@ColorRes int fromColorRes, @ColorRes final int toColorRes) { @ColorInt int fromColor = ResourcesCompat.getColor(getResources(), fromColorRes, getTheme()); @ColorInt int toColor = ResourcesCompat.getColor(getResources(), toColorRes, getTheme()); if (((ColorDrawable) mToolbar.getBackground()).getColor() == toColor) { return; } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { ValueAnimator anim = ValueAnimator.ofArgb(fromColor, toColor); anim.addUpdateListener( valueAnimator -> mToolbar.setBackgroundColor((Integer) valueAnimator.getAnimatedValue())); anim.addUpdateListener( valueAnimator -> mInfoLayout.setBackgroundColor((Integer) valueAnimator.getAnimatedValue())); @ColorInt int fromStatusColor = getWindow().getStatusBarColor(); @ColorInt int toStatusColor = ColorUtils.scrimify(toColor, true, 0.2f); ValueAnimator anim2 = ValueAnimator.ofArgb(fromStatusColor, toStatusColor); anim2.addUpdateListener( valueAnimator -> getWindow().setStatusBarColor(((Integer) valueAnimator.getAnimatedValue()))); anim.setDuration(300); anim2.setDuration(300); anim.start(); anim2.start(); } else { mToolbar.setBackgroundColor(toColor); mInfoLayout.setBackgroundColor(toColor); } } @Override public void onDestroy() { super.onDestroy(); mProjectorStrategyContext.cleanUp(); mPreferences.unregisterOnSharedPreferenceChangeListener(this); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement switch (id) { case R.id.action_settings: showSettings(); return true; case R.id.action_projectors: showProjectors(); case R.id.action_refresh: refreshState(); return true; } return super.onOptionsItemSelected(item); } private void showProjectors() { Intent intent = new Intent(this, ProjectorsActivity.class); intent.putExtra(ARG_SENDER, TAG); startActivity(intent); } private void showSettings() { Intent intent = new Intent(this, SettingsActivity.class); intent.putExtra(ARG_SENDER, TAG); startActivityForResult(intent, SettingsFragment.SETTINGS_RESULT); } private void setProjectorStrategy(@Nullable Projector projector) { mProjectorStrategyContext.cleanUp(); if (projector != null) { switch ((int) projector.getProjectorType().getId()) { case 0: mProjectorStrategyContext.setStrategy(new NECProjectorStrategy(projector, this)); break; // case 1: default: //mProjectorStrategyContext.setStrategy(new DummyProjectorStrategy(projector, this)); //mProjectorStrategyContext.setProjectorCallback(this); break; } } mProjectorStrategyContext.setProjectorCallback(this); } protected <T> void initLoader(final int loaderId, final Bundle args, final LoaderManager.LoaderCallbacks<T> callbacks) { getSupportLoaderManager().initLoader(loaderId, args, callbacks); } protected <T> void restartLoader(final int loaderId, final Bundle args, final LoaderManager.LoaderCallbacks<T> callbacks) { getSupportLoaderManager().restartLoader(loaderId, args, callbacks); } private void setPowerChangeListener() { if (mPowerSwitch != null) { mPowerSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { if (mPermission) { if (!isChecked) mProjectorStrategyContext.setPower(F_OFF); else mProjectorStrategyContext.setPower(F_ON); } else { mProjectorStrategyContext.setPower(F_OFF); } }); } } private void refresh() { long id = mPreferences.getProjectorId(); Projector projector = null; if (id != -1) { projector = ProjectorDbHelper.getProjector(this, id); } setProjectorStrategy(projector); if (projector == null) mPreferences.setProjectorId(Projector.NO_ID); } private void refreshState() { if (mPermission) { mProjectorStrategyContext.refresh(); } } private void refreshGui(@Projector.ProjectorStatus.FlagState int power, @Projector.ProjectorStatus.FlagState int pictureMute) { StringBuilder sb = new StringBuilder(); if (mPowerSwitch != null) { mPowerSwitch.setOnCheckedChangeListener(null); if (mPermission) { mPowerSwitch.setEnabled(true); if (power == F_OFF) { mButtonPictureMute.setVisibility(View.GONE); animateToolbarColorResource(R.color.colorProjectorPictureMuteOn, R.color.colorPrimary); mPowerSwitch.setChecked(false); setProjectorName(""); } else { sb.append(getResources().getString(R.string.caption_status)).append(": "); mButtonPictureMute.setVisibility(View.VISIBLE); mPowerSwitch.setChecked(true); sb.append(getResources().getString(R.string.mode_pic_mute)).append(" "); if (pictureMute == F_OFF) { animateToolbarColorResource(R.color.colorProjectorPictureMuteOn, R.color.colorPrimary); sb.append(getResources().getString(R.string.pic_mute_off)); mButtonPictureMute.setText(R.string.action_projector_picture_mute_on); } else { animateToolbarColorResource(R.color.colorPrimary, R.color.colorProjectorPictureMuteOn); sb.append(getResources().getString(R.string.pic_mute_on)); mButtonPictureMute.setText(R.string.action_projector_picture_mute_off); } } } else { mPowerSwitch.setChecked(false); mPowerSwitch.setEnabled(false); mButtonPictureMute.setVisibility(View.GONE); } setPowerChangeListener(); mTextViewStatus.setText(sb.toString()); } } private void setProjectorName(String name) { if (getSupportActionBar() != null) { // if (!Strings.isNullOrEmpty(name)) getSupportActionBar().setSubtitle(name); } } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals(ProjectoPreferences.KEY_PROJECTOR_ID)) { refresh(); refreshGui(mProjectorStrategyContext.getStrategy().getPowerStatus(), mProjectorStrategyContext.getStrategy().getPictureMuteStatus()); } } @Override public void callback(ProjectorStrategy projectorStrategy) { setProjectorName(projectorStrategy.getProjectorDisplayName()); refreshGui(projectorStrategy.getPowerStatus(), projectorStrategy.getPictureMuteStatus()); } @Override public void log(String message) { } @Override public void error(ProjectorStrategy projectorStrategy, ProjectorException e) { Snackbar.make(mCoordinatorLayout, e.getStringId(), Snackbar.LENGTH_LONG).show(); refreshGui(projectorStrategy.getPowerStatus(), projectorStrategy.getPictureMuteStatus()); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { String sortOrder = ProjectoContract.Projector.NAME + " ASC"; Uri contentUri = ProjectoContract.Projector.CONTENT_URI; return new CursorLoader(this, contentUri, null, null, null, sortOrder); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { final int size = data.getCount(); boolean wasEmpty = mList.isEmpty(); mList.clear(); for (int i = 0; i < size; i++) { data.moveToNext(); mList.add(ProjectorDbHelper.createProjectorFromCursor(this, data)); } if (mList.size() > 0) { ArrayAdapter<Projector> adapter = new ArrayAdapter<>(this, R.layout.dropdown_projector, mList); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); if (mProjectorsSpinner != null) { mProjectorsSpinner.setAdapter(adapter); mProjectorsSpinner.setVisibility(View.VISIBLE); mProjectorsSpinnerCaption.setVisibility(View.VISIBLE); } if (!wasEmpty) refreshGui(F_OFF, F_OFF); } else { mProjectorsSpinner.setVisibility(View.GONE); mProjectorsSpinnerCaption.setVisibility(View.GONE); } } @Override public void onLoaderReset(Loader<Cursor> loader) { } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { mPreferences.setProjectorId(mList.get(position).getId()); } @Override public void onNothingSelected(AdapterView<?> parent) { } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { switch (requestCode) { case PERMISSIONS_REQUEST_INTERNET: { mPermission = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); } }