/* * Artcodes recognises a different marker scheme that allows the * creation of aesthetically pleasing, even beautiful, codes. * Copyright (C) 2013-2016 The University of Nottingham * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package uk.ac.horizon.artcodes.activity; import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.support.customtabs.CustomTabsIntent; import android.support.v4.app.NavUtils; import android.support.v4.app.TaskStackBuilder; import android.support.v4.content.ContextCompat; import android.util.Log; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; import com.google.gson.Gson; import java.util.List; import uk.ac.horizon.artcodes.Artcodes; import uk.ac.horizon.artcodes.Feature; import uk.ac.horizon.artcodes.GoogleAnalytics; import uk.ac.horizon.artcodes.R; import uk.ac.horizon.artcodes.animator.VisibilityAnimator; import uk.ac.horizon.artcodes.databinding.ScannerActionBinding; import uk.ac.horizon.artcodes.detect.ArtcodeDetector; import uk.ac.horizon.artcodes.detect.handler.ActionDetectionHandler; import uk.ac.horizon.artcodes.detect.handler.MarkerActionDetectionHandler; import uk.ac.horizon.artcodes.detect.handler.MultipleMarkerActionDetectionHandler; import uk.ac.horizon.artcodes.drawer.MarkerThumbnailDrawer; import uk.ac.horizon.artcodes.model.Action; import uk.ac.horizon.artcodes.model.Experience; import uk.ac.horizon.artcodes.model.MarkerImage; import uk.ac.horizon.artcodes.scanner.ScannerActivity; import uk.ac.horizon.artcodes.server.ArtcodeServer; import uk.ac.horizon.artcodes.server.LoadCallback; import uk.ac.horizon.artcodes.ui.MarkerHistoryViewController; public class ArtcodeActivity extends ScannerActivity implements LoadCallback<Experience> { private ScannerActionBinding actionBinding; private VisibilityAnimator actionAnimator; public static void start(Context context, Experience experience) { final String experienceJSON = new Gson().toJson(experience); TaskStackBuilder.create(context) .addNextIntent(new Intent(context, NavigationActivity.class)) .addNextIntent(new Intent(context, ExperienceActivity.class) .putExtra("experience", experienceJSON)) .addNextIntent(new Intent(context, ArtcodeActivity.class) .putExtra("experience", experienceJSON)) .startActivities(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewGroup bottomView = (ViewGroup) findViewById(R.id.bottomView); if (bottomView != null) { actionBinding = ScannerActionBinding.inflate(getLayoutInflater(), bottomView, false); bottomView.addView(actionBinding.getRoot()); actionAnimator = new VisibilityAnimator(actionBinding.getRoot()); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { progressBar.setIndeterminateTintList(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.apptheme_accent))); } if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); } } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { final Experience experience = getExperience(); NavUtils.navigateUpTo(this, ExperienceActivity.intent(this, experience)); return true; } return super.onOptionsItemSelected(item); } @Override public void loaded(final Experience experience) { super.loaded(experience); if (experience != null) { GoogleAnalytics.trackScreen("Scan", getExperience().getId()); getServer().loadRecent(new LoadCallback<List<String>>() { @Override public void loaded(List<String> item) { item.remove(experience.getId()); item.add(0, experience.getId()); getServer().saveRecent(item); } @Override public void error(Throwable e) { GoogleAnalytics.trackException(e); } }); } } @Override public void error(Throwable e) { GoogleAnalytics.trackException(e); } @Override protected void loadExperience(Bundle savedInstanceState) { if (savedInstanceState != null && savedInstanceState.containsKey("experience")) { loaded(new Gson().fromJson(savedInstanceState.getString("experience"), Experience.class)); } else { Intent intent = getIntent(); if (intent.hasExtra("experience")) { loaded(new Gson().fromJson(intent.getStringExtra("experience"), Experience.class)); } else { final Uri data = intent.getData(); if (data != null) { getServer().loadExperience(data.toString(), this); } } } } private Artcodes getArtcodes() { return (Artcodes) getApplication(); } private ArtcodeServer getServer() { return getArtcodes().getServer(); } private void onActionChanged(final Action action) { Log.i("action", "" + action); if (action != null) { final Experience experience = getExperience(); getServer().logScan(experience.getId(), action); GoogleAnalytics.trackEvent("Action", "Scanned", experience.getId(), action.getName()); actionBinding.setAction(action); actionBinding.getRoot().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (action.getUrl() != null) { GoogleAnalytics.trackEvent("Action", "Opened", experience.getId(), action.getName()); CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); // TODO Warmup urls //builder.setSession(session); builder.setToolbarColor(ContextCompat.getColor(ArtcodeActivity.this, R.color.apptheme_primary)); CustomTabsIntent customTabsIntent = builder.build(); customTabsIntent.launchUrl(ArtcodeActivity.this, Uri.parse(action.getUrl())); } } }); runOnUiThread(new Runnable() { @Override public void run() { actionAnimator.showView(); progressBar.setVisibility(View.INVISIBLE); } }); } else { runOnUiThread(new Runnable() { @Override public void run() { actionAnimator.hideView(); progressBar.setVisibility(View.VISIBLE); } }); } } @Override protected ArtcodeDetector getNewDetector(Experience experience) { if (Feature.get(getApplicationContext(), R.bool.feature_combined_markers).isEnabled()) { return new ArtcodeDetector(this, experience, new MultipleMarkerActionDetectionHandler(new ActionDetectionHandler() { private final MarkerHistoryViewController markerHistoryViewController = new MarkerHistoryViewController(ArtcodeActivity.this, (RelativeLayout) findViewById(R.id.thumbnailImageLayout), new Handler(Looper.getMainLooper())); @Override public void onMarkerActionDetected(Action detectedAction, Action futureAction, List<MarkerImage> detectedMarkers) { markerHistoryViewController.update(detectedMarkers, futureAction); onActionChanged(detectedAction); } }, experience, new MarkerThumbnailDrawer())); } else { return new ArtcodeDetector(this, experience, new MarkerActionDetectionHandler(new ActionDetectionHandler() { @Override public void onMarkerActionDetected(Action detectedAction, Action possibleFutureAction, List<MarkerImage> imagesForFutureAction) { onActionChanged(detectedAction); } }, experience, null)); } } }