implemented sync process

pull/5/head
Felix Prahl-Kamps 2018-06-16 17:38:59 +02:00
parent b49cc7a66f
commit 70dbbeb479
21 changed files with 698 additions and 141 deletions

View File

@ -22,7 +22,7 @@ android {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
@ -31,4 +31,5 @@ dependencies {
implementation 'com.android.volley:volley:1.1.0' implementation 'com.android.volley:volley:1.1.0'
implementation 'com.github.kenglxn.QRGen:android:2.4.0' implementation 'com.github.kenglxn.QRGen:android:2.4.0'
implementation 'com.google.android.gms:play-services-vision:15.0.2'
} }

View File

@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.overview.wg.its.mispauth"> package="de.overview.wg.its.mispauth">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<application <application
@ -26,6 +27,7 @@
android:parentActivityName=".activity.MainActivity"/> android:parentActivityName=".activity.MainActivity"/>
<activity <activity
android:screenOrientation="portrait"
android:name=".activity.SyncActivity" android:name=".activity.SyncActivity"
android:label="@string/title_activity_sync" android:label="@string/title_activity_sync"
android:parentActivityName=".activity.MainActivity"/> android:parentActivityName=".activity.MainActivity"/>

View File

@ -1,35 +1,38 @@
package de.overview.wg.its.mispauth.activity; package de.overview.wg.its.mispauth.activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter; import android.support.v7.app.AlertDialog;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.LinearLayout;
import com.android.volley.VolleyError;
import de.overview.wg.its.mispauth.R; import de.overview.wg.its.mispauth.R;
import de.overview.wg.its.mispauth.auxiliary.OrganisationDialog;
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager; import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
import de.overview.wg.its.mispauth.fragment.ScanQrFragment; import de.overview.wg.its.mispauth.fragment.ScanQrFragment;
import de.overview.wg.its.mispauth.fragment.ShowQrFragment; import de.overview.wg.its.mispauth.fragment.ShowQrFragment;
import de.overview.wg.its.mispauth.fragment.SyncStartFragment; import de.overview.wg.its.mispauth.fragment.SyncStartFragment;
import de.overview.wg.its.mispauth.fragment.UploadFragment; import de.overview.wg.its.mispauth.fragment.UploadFragment;
import de.overview.wg.its.mispauth.model.Organisation; import de.overview.wg.its.mispauth.model.Organisation;
import de.overview.wg.its.mispauth.network.MispRequest; import org.json.JSONException;
import de.overview.wg.its.mispauth.custom_viewpager.ExtendedViewPager; import org.json.JSONObject;
import org.json.JSONArray;
public class SyncActivity extends AppCompatActivity { public class SyncActivity extends AppCompatActivity {
private static final String TAG = "DEBUG";
private PreferenceManager preferenceManager; private PreferenceManager preferenceManager;
private static final int PAGE_COUNT = 3; private Button prevButton, nextButton;
private ExtendedViewPager viewPager; private int partnerChoice = -1;
private PagerAdapter pagerAdapter; private String scannedQrString = "";
private LinearLayout bottomLayout;
private int currentFragmentPosition = 0;
@Override @Override
@ -37,107 +40,131 @@ public class SyncActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync); setContentView(R.layout.activity_sync);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
preferenceManager = PreferenceManager.Instance(this); preferenceManager = PreferenceManager.Instance(this);
setupViewPager(); nextButton = findViewById(R.id.nextButton);
prevButton = findViewById(R.id.backButton);
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getFragment(currentFragmentPosition + 1, true);
}
});
prevButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getFragment(currentFragmentPosition - 1, true);
}
});
getFragment(0, false);
} }
private void setupViewPager() { private void getFragment(int position, boolean animate) {
bottomLayout = findViewById(R.id.linearLayout);
pagerAdapter = new SimplePagerAdapter(getSupportFragmentManager()); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
viewPager = findViewById(R.id.viewPager); if (animate) {
viewPager.setPagingEnabled(false); if (position > currentFragmentPosition) {
viewPager.setAdapter(pagerAdapter); transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
} else {
transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
}
}
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { currentFragmentPosition = position;
switch (position) {
case 0:
prevButton.setEnabled(false);
nextButton.setEnabled(false);
transaction.replace(R.id.fragmentContainer, new SyncStartFragment());
break;
case 1:
prevButton.setEnabled(true);
if (partnerChoice == 1) {
nextButton.setEnabled(false);
transaction.replace(R.id.fragmentContainer, new ScanQrFragment(), "FRAGMENT_SCAN");
@Override
public void onPageSelected(int position) {
if (position == 0) {
bottomLayout.setVisibility(View.GONE);
} else { } else {
bottomLayout.setVisibility(View.VISIBLE);
nextButton.setEnabled(true);
transaction.replace(R.id.fragmentContainer, new ShowQrFragment(), "FRAGMENT_SHOW");
} }
} break;
@Override case 2:
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (partnerChoice == 1) {
} prevButton.setEnabled(true);
nextButton.setEnabled(true);
transaction.replace(R.id.fragmentContainer, new ShowQrFragment(), "FRAGMENT_SHOW");
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING } else {
@Override
public void onPageScrollStateChanged(int state) {
} prevButton.setEnabled(true);
}); nextButton.setEnabled(false);
Button next = findViewById(R.id.nextButton); transaction.replace(R.id.fragmentContainer, new ScanQrFragment(), "FRAGMENT_SCAN");
Button back = findViewById(R.id.backButton); }
break;
next.setOnClickListener(new View.OnClickListener() { case 3:
@Override
public void onClick(View v) {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
}
});
back.setOnClickListener(new View.OnClickListener() { nextButton.setText("Finish");
@Override nextButton.setEnabled(false);
public void onClick(View v) {
viewPager.setCurrentItem(viewPager.getCurrentItem() - 1, true); transaction.replace(R.id.fragmentContainer, new UploadFragment());
}
}); break;
default:
break;
}
transaction.commit();
} }
private class SimplePagerAdapter extends FragmentStatePagerAdapter { public void setPartnerChoice(int choice) {
public SimplePagerAdapter(FragmentManager fm) { partnerChoice = choice;
super(fm);
}
@Override if (choice != -1) {
public Fragment getItem(int position) { nextButton.setEnabled(true);
} else {
switch (position) { nextButton.setEnabled(false);
case 0:
return new SyncStartFragment(); // start fragment
case 1:
return new ScanQrFragment(); // scan fragment
case 2:
return new ShowQrFragment(); // show QR fragment
case 3:
return new UploadFragment(); // show upload fragment
default:
return null; // This should not be happening
}
}
@Override
public int getCount() {
return PAGE_COUNT;
} }
} }
private void uploadOrganisation(Organisation org) { public void setScannedQr(String qr) {
MispRequest mispRequest = MispRequest.Instance(this);
mispRequest.getOrganisations(new MispRequest.OrganisationsCallback() { final FragmentManager manager = getSupportFragmentManager();
@Override final ScanQrFragment scanFragment = (ScanQrFragment) manager.findFragmentByTag("FRAGMENT_SCAN");
public void onResult(JSONArray organisations) {
} scanFragment.setReadQr(false);
try {
OrganisationDialog d = new OrganisationDialog(this);
Organisation o = new Organisation();
o.fromJSON(new JSONObject(qr));
d.createDialog(o);
@Override } catch (JSONException e) {
public void onError(VolleyError volleyError) { e.printStackTrace();
}
} }
});
public void uploadReady() {
nextButton.setEnabled(true);
} }
} }

View File

@ -27,6 +27,9 @@ public class OrganisationDialog {
TextView title = dialogContent.findViewById(R.id.organisation_title); TextView title = dialogContent.findViewById(R.id.organisation_title);
title.setText(org.getName()); title.setText(org.getName());
TextView uuid = dialogContent.findViewById(R.id.organisation_uuid);
uuid.setText(org.getUuid());
TextView description = dialogContent.findViewById(R.id.organisation_description); TextView description = dialogContent.findViewById(R.id.organisation_description);
description.setText(org.getDescription()); description.setText(org.getDescription());
@ -39,7 +42,9 @@ public class OrganisationDialog {
TextView userCount = dialogContent.findViewById(R.id.organisation_user_count); TextView userCount = dialogContent.findViewById(R.id.organisation_user_count);
userCount.setText("" + org.getUserCount()); userCount.setText("" + org.getUserCount());
// dialogBuilder.setPositiveButton("OK", null); dialogBuilder.setCancelable(false);
dialogBuilder.setNegativeButton("REJECT", null);
dialogBuilder.setPositiveButton("ACCEPT", null);
dialogBuilder.show(); dialogBuilder.show();
} }
} }

View File

@ -1,17 +1,361 @@
package de.overview.wg.its.mispauth.fragment; package de.overview.wg.its.mispauth.fragment;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.*;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.renderscript.*;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.view.LayoutInflater; import android.support.v4.content.ContextCompat;
import android.view.View; import android.util.Size;
import android.view.ViewGroup; import android.util.SparseArray;
import android.view.*;
import android.widget.Toast;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import de.overview.wg.its.mispauth.R; import de.overview.wg.its.mispauth.R;
import de.overview.wg.its.mispauth.activity.SyncActivity;
import java.util.Arrays;
import java.util.List;
public class ScanQrFragment extends Fragment { public class ScanQrFragment extends Fragment {
private static final int CAMERA_REQUEST_CODE = 0;
private HandlerThread backgroundThread;
private Handler backgroundHandler;
private CameraManager cameraManager;
private CameraDevice cameraDevice;
private String cameraID;
private CameraCaptureSession cameraCaptureSession;
private SurfaceTexture previewSurfaceTexture;
private Surface previewSurface, yuvSurface;
private Size[] yuvSizes;
private BarcodeDetector barcodeDetector;
private TextureView previewView;
private boolean readQr = true;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_sync_scan, null); View v = inflater.inflate(R.layout.fragment_sync_scan, null);
previewView = v.findViewById(R.id.texture_scan_preview);
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA)) {
} else {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
}
} else {
setUpBarcodeDetector();
setUpPreviewTexture();
}
return v; return v;
} }
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case CAMERA_REQUEST_CODE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setUpBarcodeDetector();
setUpPreviewTexture();
} else {
Toast.makeText(getActivity(), "Camera permission needed!", Toast.LENGTH_SHORT).show();
}
}
}
}
@Override
public void onResume() {
super.onResume();
openBackgroundThread();
}
@Override
public void onStop() {
super.onStop();
closeCamera();
closeBackgroundThread();
}
private void returnResult(String qrData) {
((SyncActivity) getActivity()).setScannedQr(qrData);
}
private void setUpPreviewTexture() {
previewView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
surface.setDefaultBufferSize(width, height);
previewSurfaceTexture = surface;
setUpCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
}
private void setUpCamera() {
cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
Integer facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
if (facing == CameraCharacteristics.LENS_FACING_BACK) {
cameraID = cameraId;
StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
yuvSizes = streamConfigurationMap.getOutputSizes(ImageFormat.YUV_420_888);
setUpImageReader();
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void setUpImageReader() {
Size yuvSize = yuvSizes[yuvSizes.length - 6];
ImageReader yuvImageReader = ImageReader.newInstance(yuvSize.getWidth(), yuvSize.getHeight(), ImageFormat.YUV_420_888, 5);
ImageReader.OnImageAvailableListener yuvImageListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
if (!readQr) {
return;
}
Image lastImage = reader.acquireLatestImage();
Bitmap bitmap = YUV2Bitmap(lastImage);
if (bitmap != null) {
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
SparseArray<Barcode> barcodes = barcodeDetector.detect(frame);
if (barcodes.size() > 0) {
returnResult(barcodes.valueAt(0).rawValue);
}
}
if (lastImage != null) {
lastImage.close();
}
}
};
yuvImageReader.setOnImageAvailableListener(yuvImageListener, backgroundHandler);
previewSurface = new Surface(previewSurfaceTexture);
yuvSurface = yuvImageReader.getSurface();
openCamera();
}
public void openCamera() {
CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
cameraDevice = camera;
createCaptureSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
}
};
try {
if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
cameraManager.openCamera(cameraID, stateCallback, backgroundHandler);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCaptureSession() {
List<Surface> surfaces = Arrays.asList(previewSurface, yuvSurface);
CameraCaptureSession.StateCallback captureStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
cameraCaptureSession = session;
createCaptureRequest();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
};
try {
cameraDevice.createCaptureSession(surfaces, captureStateCallback, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCaptureRequest() {
try {
CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
requestBuilder.addTarget(previewSurface);
requestBuilder.addTarget(yuvSurface);
CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
}
};
cameraCaptureSession.setRepeatingRequest(requestBuilder.build(), captureCallback, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openBackgroundThread() {
backgroundThread = new HandlerThread("raw_image_available_listener_thread");
backgroundThread.start();
backgroundHandler = new Handler(backgroundThread.getLooper());
}
private void closeBackgroundThread() {
backgroundThread.quitSafely();
try {
backgroundThread.join();
backgroundThread = null;
backgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void closeCamera() {
if (cameraCaptureSession != null) {
cameraCaptureSession.close();
cameraCaptureSession = null;
}
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
}
private void setUpBarcodeDetector() {
barcodeDetector = new BarcodeDetector.Builder(getActivity())
.setBarcodeFormats(Barcode.QR_CODE)
.build();
if (!barcodeDetector.isOperational()) {
Toast.makeText(getActivity(), "Could not setup QR-Code scanner!", Toast.LENGTH_SHORT).show();
}
}
private Bitmap YUV2Bitmap(Image image) {
if (image == null) return null;
int W = image.getWidth();
int H = image.getHeight();
Image.Plane Y = image.getPlanes()[0];
Image.Plane U = image.getPlanes()[1];
Image.Plane V = image.getPlanes()[2];
int Yb = Y.getBuffer().remaining();
int Ub = U.getBuffer().remaining();
int Vb = V.getBuffer().remaining();
byte[] data = new byte[Yb + Ub + Vb];
Y.getBuffer().get(data, 0, Yb);
V.getBuffer().get(data, Yb, Vb);
U.getBuffer().get(data, Yb + Vb, Ub);
RenderScript rs = RenderScript.create(getActivity().getApplicationContext());
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
in.copyFromUnchecked(data);
yuvToRgbIntrinsic.setInput(in);
yuvToRgbIntrinsic.forEach(out);
out.copyTo(bmpout);
image.close();
return bmpout;
}
public void setReadQr(boolean enabled) {
readQr = enabled;
}
} }

View File

@ -1,27 +1,52 @@
package de.overview.wg.its.mispauth.fragment; package de.overview.wg.its.mispauth.fragment;
import android.graphics.Point;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import de.overview.wg.its.mispauth.R; import de.overview.wg.its.mispauth.R;
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
import net.glxn.qrgen.android.QRCode; import net.glxn.qrgen.android.QRCode;
public class ShowQrFragment extends Fragment { public class ShowQrFragment extends Fragment {
private ImageView qrImageView; private ImageView qrImageView;
private int screenWidth, screenHeight;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_sync_show, null); View v = inflater.inflate(R.layout.fragment_sync_show, null);
// DisplayMetrics metrics = new DisplayMetrics();
// getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
//
// screenWidth = (int)(metrics.widthPixels * metrics.density);
// screenHeight = (int)(metrics.heightPixels * metrics.density);
// Display display = getActivity().getWindowManager().getDefaultDisplay();
// Point size = new Point();
// display.getSize(size);
// screenWidth = size.x;
// screenHeight = size.y;
screenHeight = getResources().getDisplayMetrics().heightPixels;
screenWidth = getResources().getDisplayMetrics().widthPixels;
qrImageView = v.findViewById(R.id.image_view_qr); qrImageView = v.findViewById(R.id.image_view_qr);
setQr("Hallo hier steht leide nur scheiße, aber ansonsten hat alles geklappt! (Y)");
PreferenceManager preferenceManager = PreferenceManager.Instance(getActivity());
setQr(preferenceManager.getMyOrganisation().toJSON().toString());
return v; return v;
} }
public void setQr(String msg) { private void setQr(String msg) {
qrImageView.setImageBitmap(QRCode.from(msg).bitmap()); qrImageView.setImageBitmap(QRCode.from(msg)
.withSize(screenHeight, screenHeight)
.bitmap());
} }
} }

View File

@ -1,17 +1,33 @@
package de.overview.wg.its.mispauth.fragment; package de.overview.wg.its.mispauth.fragment;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.RadioGroup;
import de.overview.wg.its.mispauth.R; import de.overview.wg.its.mispauth.R;
import de.overview.wg.its.mispauth.activity.SyncActivity;
public class SyncStartFragment extends Fragment { public class SyncStartFragment extends Fragment {
private static final String TAG = "DEBUG";
private RadioGroup radioGroup;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_sync_start, null); View v = inflater.inflate(R.layout.fragment_sync_start, null);
radioGroup = v.findViewById(R.id.radioGroup);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
((SyncActivity)getActivity()).setPartnerChoice(checkedId % 2);
}
});
return v; return v;
} }
} }

View File

@ -0,0 +1,5 @@
package de.overview.wg.its.mispauth.interfaces;
public interface IProcessable {
boolean isDone();
}

View File

@ -0,0 +1,6 @@
package de.overview.wg.its.mispauth.interfaces;
public interface ISyncCommunication {
void setPartnerChoice(int choice);
void setScannedQr(String qr);
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300" />
</set>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="150"/>
</set>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="150" />
</set>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quad"
android:valueFrom="0"
android:valueTo="1"
android:propertyName="alpha"
android:duration="@android:integer/config_mediumAnimTime"/>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="2dp"
android:useLevel="false">
<solid android:color="@android:color/darker_gray"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thickness="4dp"
android:useLevel="false" >
<solid android:color="@color/colorAccent"/>
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/tab_indicator_selected"
android:state_selected="true"/>
<item android:drawable="@drawable/tab_indicator_default"/>
</selector>

View File

@ -12,6 +12,7 @@
android:background="@color/colorPrimary"> android:background="@color/colorPrimary">
<android.support.design.widget.AppBarLayout <android.support.design.widget.AppBarLayout
app:elevation="0dp"
android:id="@+id/sync.appbar" android:id="@+id/sync.appbar"
android:background="@color/colorPrimaryDark" android:background="@color/colorPrimaryDark"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -35,19 +36,24 @@
android:padding="0dp" android:padding="0dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<de.overview.wg.its.mispauth.custom_viewpager.ExtendedViewPager
android:id="@+id/viewPager" <FrameLayout
android:layout_width="match_parent" android:id="@+id/fragmentContainer"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toTopOf="@+id/linearLayout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/linearLayout"/> app:layout_constraintTop_toTopOf="parent"
android:layout_width="0dp"
android:layout_height="0dp">
</FrameLayout>
<LinearLayout <LinearLayout
android:id="@+id/linearLayout" android:id="@+id/linearLayout"
android:background="@color/colorPrimary" android:background="@color/colorPrimary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="horizontal" android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -57,18 +63,26 @@
android:id="@+id/backButton" android:id="@+id/backButton"
android:text="Back" android:text="Back"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"/> android:layout_height="match_parent"
android:enabled="false"/>
<TextView <android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_weight="1" android:layout_weight="1"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content"/> android:layout_height="match_parent"
app:tabBackground="@drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp">
</android.support.design.widget.TabLayout>
<Button style="@style/Widget.AppCompat.Button.Borderless.Colored" <Button style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:id="@+id/nextButton" android:id="@+id/nextButton"
android:text="Next" android:text="Next"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"/> android:layout_height="match_parent"
android:enabled="false"/>
</LinearLayout> </LinearLayout>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View File

@ -1,17 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <TextureView
android:layout_width="wrap_content" android:id="@+id/texture_scan_preview"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Scan QR" android:layout_height="wrap_content"/>
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="8dp"
app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="8dp"/>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View File

@ -1,12 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ImageView <ImageView
android:id="@+id/image_view_qr" android:id="@+id/image_view_qr"
android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_width="wrap_content"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View File

@ -5,32 +5,69 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ImageView <RadioGroup
android:id="@+id/sync_image" android:id="@+id/radioGroup"
android:src="@drawable/ic_sync_alpha" android:padding="16dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="128dp"/> android:layout_height="wrap_content" android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp" android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<TextView <TextView
android:gravity="center" android:layout_width="match_parent"
android:id="@+id/help_text_sync" android:layout_height="wrap_content"
android:text="I am partner" android:layout_marginBottom="8dp"
android:layout_width="match_parent" android:textSize="20sp"
android:layout_height="wrap_content" android:textStyle="bold"
app:layout_constraintTop_toBottomOf="@+id/sync_image"/> android:text="How would you like to start?"/>
<Button style="@style/CustomButton" <TextView
android:id="@+id/button_scan" android:layout_width="match_parent"
android:text="Scan" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_marginBottom="16dp"
android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:textSize="17sp"
app:layout_constraintBottom_toTopOf="@+id/button_share"/> android:text="Make sure your partner will choose the opposite option."/>
<Button style="@style/CustomButton" <RadioButton
android:id="@+id/button_share" android:layout_width="match_parent"
android:text="Share" android:layout_height="56dp"
android:layout_width="match_parent" android:text="Scan QR-Code first"/>
android:layout_height="wrap_content" android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"/> <RadioButton
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="Share QR-Code first"/>
</RadioGroup>
<!--<ImageView-->
<!--android:id="@+id/sync_image"-->
<!--android:src="@drawable/ic_sync_alpha"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="128dp"/>-->
<!--<TextView-->
<!--android:gravity="center"-->
<!--android:id="@+id/help_text_sync"-->
<!--android:text="I am partner"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--app:layout_constraintTop_toBottomOf="@+id/sync_image"/>-->
<!--<Button style="@style/CustomButton"-->
<!--android:id="@+id/button_scan"-->
<!--android:text="Scan"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content" android:layout_marginBottom="8dp"-->
<!--app:layout_constraintBottom_toTopOf="@+id/button_share"/>-->
<!--<Button style="@style/CustomButton"-->
<!--android:id="@+id/button_share"-->
<!--android:text="Share"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content" android:layout_marginBottom="8dp"-->
<!--app:layout_constraintBottom_toBottomOf="parent"/>-->
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>