android:versionCode="1"
android:versionName="1.0" >
-<uses-sdk
+ <uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
+ <android:uses-permission
+ android:name="android.permission.WRITE_EXTERNAL_STORAGE"
+ android:maxSdkVersion="18" />
+ <android:uses-permission android:name="android.permission.READ_PHONE_STATE" />
+ <android:uses-permission
+ android:name="android.permission.READ_EXTERNAL_STORAGE"
+ android:maxSdkVersion="18" />
+
<application
android:allowBackup="true"
android:icon="@drawable/ic_glass_logo"
android:label="@string/app_name" >
<activity
- android:name="cz.cvut.fel.dce.qrscanner.MainActivity"
+ android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
<action android:name="android.intent.action.MAIN" />
+
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
android:name=".PreviewActivity"
android:label="@string/title_activity_preview" >
</activity>
+ <activity
+ android:name=".pdfviewer.PdfViewActivity"
+ android:label="@string/title_activity_pdf_view" >
+ </activity>
</application>
</manifest>
import java.io.File;
import cz.cvut.fel.dce.qrscanner.mupdf.MuPDFCore;
+import cz.cvut.fel.dce.qrscanner.pdfviewer.PdfViewActivity;
public class PreviewActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview);
mPreviewImg = (ImageView) findViewById(R.id.imgComponent);
- mPreviewImg.setMaxWidth(640);
- mPreviewImg.setMaxHeight(360);
- mPreviewImg.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
if (mPreviewImg != null) {
+ mPreviewImg.setMaxWidth(640);
+ mPreviewImg.setMaxHeight(360);
+ mPreviewImg.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
mPreviewImgObserver = mPreviewImg.getViewTreeObserver();
Log.i(TAG, "Registering mPreviewImgObserver OnGlobalLayoutListener.");
mPreviewImgObserver.addOnGlobalLayoutListener(this);
Log.d(TAG, "page size: " + pageW + ", " + pageH);
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap previewBitmap = Bitmap.createBitmap(pageW, pageH, conf);
- core.drawPage(previewBitmap, 0, pageW, pageH,0 , 0, pageW, pageH, cookie);
+ core.drawPage(previewBitmap, 0, pageW, pageH, 0, 0, pageW, pageH, cookie);
mPreviewImg.setImageBitmap(previewBitmap);
mPreviewImg.invalidate();
} catch (Exception e) {
}
private void showPDF(String filePath) {
- Uri uri = Uri.parse(filePath);
- Intent pdfIntent = new Intent("com.artifex.mupdfdemo.VIEW");
- //pdfIntent.setAction(Intent.ACTION_VIEW);
- pdfIntent.setData(uri);
- startActivity(pdfIntent);
+ Intent preview = new Intent(this, PdfViewActivity.class);
+ preview.putExtra("FILE_PATH", filePath);
+ startActivity(preview);
}
@Override
--- /dev/null
+package cz.cvut.fel.dce.qrscanner.pdfviewer;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.view.View;
+
+/**
+ * Created by michal on 16.2.15.
+ */
+public class PdfPageView extends SceneView {
+ private Bitmap mPdfBitmap;
+ private Paint mBitmapPaint;
+
+ public PdfPageView(Context context, Bitmap pdfBitmap, float defZoom, float minZoom, float maxZoom, float defXCenter, float minX, float maxX, float defYCenter, float minY, float maxY) throws Exception {
+ super(context, defZoom, minZoom, maxZoom, defXCenter, minX, maxX, defYCenter, minY, maxY);
+ mPdfBitmap = Bitmap.createBitmap(pdfBitmap);
+ mBitmapPaint = new Paint();
+ }
+
+ @Override
+ protected void computeSceneDimmensions() {
+ mSceneWidth = mPdfBitmap.getWidth();
+ mSceneHeight = mPdfBitmap.getHeight();
+ }
+
+ @Override
+ public void draw(Canvas c) {
+ c.translate(c.getWidth()/2, c.getHeight()/2);
+ c.scale(mZoom.getValue(), mZoom.getValue());
+ c.translate(-mXPosition.getValue(), -mYPosition.getValue());
+ c.drawBitmap(mPdfBitmap, 0, 0, mBitmapPaint);
+ }
+}
--- /dev/null
+package cz.cvut.fel.dce.qrscanner.pdfviewer;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.Toast;
+
+import java.io.File;
+
+import cz.cvut.fel.dce.qrscanner.R;
+import cz.cvut.fel.dce.qrscanner.mupdf.MuPDFCore;
+
+public class PdfViewActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener, SceneView.SceneChange, SensorEventListener {
+ public static final String TAG = "PdfViewActivity";
+
+ private FrameLayout mPdfImageContainer;
+ private ViewTreeObserver mPreviewImgObserver;
+ private String mFilePath;
+ private PdfPageView mPdfView;
+ private Boolean mPdfLoaded = false;
+ private SensorManager mSensorManager;
+
+ /**
+ * Start position of the gesture on touchpad
+ */
+ private float startX;
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+ setContentView(R.layout.activity_pdf_view);
+ mPdfImageContainer = (FrameLayout) findViewById(R.id.pdf_view_container);
+ if (mPdfImageContainer != null) {
+ mPreviewImgObserver = mPdfImageContainer.getViewTreeObserver();
+ Log.i(TAG, "Registering mPreviewImgObserver OnGlobalLayoutListener.");
+ mPreviewImgObserver.addOnGlobalLayoutListener(this);
+ }
+ else {
+ Log.e(TAG, "ImageView for preview image could not be found in the resources.");
+ mPreviewImgObserver = null;
+ }
+
+ Intent intent = getIntent();
+ mFilePath = intent.getStringExtra("FILE_PATH");
+
+ if (mFilePath != null) {
+ Log.i(TAG, "File path: " + mFilePath);
+ File rootPath = new File(mFilePath);
+ if (!rootPath.exists()) {
+ Toast toast = Toast.makeText(getApplicationContext(), "Document not found", Toast.LENGTH_LONG);
+ toast.show();
+ finish();
+ }
+ }
+ else {
+ Log.i(TAG, "No file path received");
+ finish();
+ }
+ }
+
+ public void onResume() {
+ mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mSensorManager.unregisterListener(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mPreviewImgObserver != null && mPreviewImgObserver.isAlive()) {
+ mPreviewImgObserver.removeOnGlobalLayoutListener(this);
+ }
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+
+
+
+ @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_pdf_view, menu);
+ return true;
+ }
+
+ @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
+ if (id == R.id.action_settings) {
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onGlobalLayout() {
+ if (mPdfLoaded) {
+ Log.d(TAG, "PDF file already loaded.");
+ return;
+ }
+ try {
+ String picturePath = mFilePath;
+ Log.i(TAG, "Path to component files: " + picturePath);
+
+ MuPDFCore core = new MuPDFCore(getApplicationContext(), picturePath);
+ Log.d(TAG, "numpages: "+ core.countPages());
+ MuPDFCore.Cookie cookie = core.new Cookie();
+ int pageW = (int)core.getPageSize(0).x;
+ int pageH = (int)core.getPageSize(0).y;
+ Log.d(TAG, "page size: " + pageW + ", " + pageH);
+ Bitmap.Config mPdfBitmapConf = Bitmap.Config.ARGB_8888;
+ Bitmap mPdfBitmap = Bitmap.createBitmap(pageW, pageH, mPdfBitmapConf);
+ core.drawPage(mPdfBitmap, 0, pageW, pageH,0 , 0, pageW, pageH, cookie);
+ mPdfView = new PdfPageView(getApplicationContext(), mPdfBitmap, 0, 0, 100, (float) mPdfBitmap.getWidth()/2, 0, (float) mPdfBitmap.getWidth(), (float) mPdfBitmap.getHeight()/2, 0, (float) mPdfBitmap.getHeight());
+ mPdfView.setListener(this);
+ mPdfView.setDefaultValues(0, 0, 0);
+ if (mPdfImageContainer != null) {
+ mPdfImageContainer.addView(mPdfView);
+ mPdfImageContainer.invalidate();
+ mPdfLoaded = true;
+ }
+ else {
+ Log.e(TAG, "Could not find container for PdfPageView.");
+ finish();
+ }
+ } catch (Exception e) {
+ Toast toast = Toast.makeText(getApplicationContext(), "Component preview could not be loaded.", Toast.LENGTH_LONG);
+ toast.show();
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ /*
+ Zoom ratio gained during one gesture on touchpad
+ */
+ float dzoom;
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ startX = event.getRawX();
+ return false;
+ }
+ if (event.getAction() == MotionEvent.ACTION_MOVE) {
+ dzoom = event.getRawX() - startX;
+ Log.d(TAG,"move_action, dzoom: " + dzoom);
+ mPdfView.zoom(dzoom /1000f);
+ startX = event.getRawX();
+ return false;
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
+ @Override
+ public void onSceneChanged(SceneView source) {
+ if (mPdfView != null) {
+ mPdfView.invalidate();
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
+ float dx = event.values[1]*12;
+ float dy = event.values[0]*12;
+ if (mPdfView != null) {
+ mPdfView.move(-dx, -dy);
+ }
+ }
+ }
+}
--- /dev/null
+package cz.cvut.fel.dce.qrscanner.pdfviewer;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.view.View;
+
+/**
+ * Parent class for all views for drawing some graphic on canvas.
+ * The scenes can be zoomed and moved by an application.
+ * @author Michal Horn
+ *
+ */
+public abstract class SceneView extends View {
+ /**
+ * Value with some allowed minimum and maximum.
+ * @author Michal Horn
+ *
+ * @param <T> some comparable numeric data type
+ */
+ class IntervalValue<T extends Number & Comparable<? super T>> {
+ /**
+ * Stored value
+ */
+ private T mValue;
+ /**
+ * The lowest allowed value. All values stored in the object are
+ * higher or equal this minimum.
+ */
+ private T mMinimum;
+ /**
+ * The highest allowed value. All values stored in the object are
+ * lower or equal this maximum.
+ */
+ private T mMaximum;
+
+ /**
+ * Class constructor.
+ * Creates object that represents a value in range <minimum; maximum>.
+ *
+ * @param defValue Value to be stored in the object. Must be in the allowed range specified by other two parameters.
+ * @param minimum The lowes allowed value to be stored in the object.
+ * @param maximum The highest allowed value to be stored in the object.
+ * @throws Exception Throwed when minimal, maximal or inserted value were rejected.
+ */
+ public IntervalValue(T defValue, T minimum, T maximum) throws Exception {
+ setMinimum(minimum);
+ setMaximum(maximum);
+ if (!setValue(defValue)) {
+ throw new Exception("Provided value is not in the range.");
+ }
+ }
+
+ /**
+ * Store value in the object. The value must lie between the minimum and maximum
+ * defined for the object.
+ * @param value value to be stored in the object
+ * @return true - vale was stored successfully,<br>false - value could not be inserted because it was out of range.
+ */
+ public boolean setValue(T value) {
+ if (value.compareTo(mMinimum) >= 0 && value.compareTo(mMaximum) <= 0) {
+ mValue = value;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Set minimum for values in the object.
+ * Last inserted value is not changed even if it is lower then the new minimum.
+ * @param min new allowed minimum for the values stored to the object.
+ * @throws Exception throwed when new minimum is higher than old maximum.
+ */
+ public void setMinimum(T min) throws Exception {
+ if (mMaximum != null && mMinimum != null && mMinimum.compareTo(mMaximum) > 0) {
+ throw new Exception("Minimum is higher then maximum.");
+ }
+ mMinimum = min;
+ }
+
+ /**
+ * Set maximum for values in the object.
+ * Last inserted value is not changed even if it is higher then the new maximum.
+ * @param max new allowed maximum for the values stored to the object.
+ * @throws Exception throwed when new maximum is lower than old minimum.
+ */
+ public void setMaximum(T max) throws Exception {
+ if (mMinimum != null && mMaximum != null && mMaximum.compareTo(mMinimum) < 0) {
+ throw new Exception("Maximum is lower then minimum.");
+ }
+ mMaximum = max;
+ }
+
+ /**
+ * Get value stored in the object
+ * @return value stored in the object.
+ */
+ public T getValue() {
+ return mValue;
+ }
+
+ /**
+ * Get the lowest allowed value that can be stored in the object.
+ * @return minimal value
+ */
+ public T getMinimum() {
+ return mMinimum;
+ }
+
+ /**
+ * Get the highest allowed value that can be stored in the object.
+ * @return maximal value
+ */
+ public T getMaximum() {
+ return mMaximum;
+ }
+ }
+
+ /**
+ * Interface for events generated by the view
+ * @author Michal Horn
+ *
+ */
+ public interface SceneChange {
+ /**
+ * Invoked every time when the scene should be redrawed.
+ * @param source
+ */
+ public void onSceneChanged(SceneView source);
+ }
+
+ protected Paint mPaint;
+ protected IntervalValue<Float> mZoom;
+ protected IntervalValue<Float> mXPosition;
+ protected IntervalValue<Float> mYPosition;
+ protected SceneChange mListener;
+ protected float mSceneHeight;
+ protected float mSceneWidth;
+ protected float mDefaultZoomRatio;
+ protected float mDefaultXPos;
+ protected float mDefaultYPos;
+
+ /**
+ * Class constructor.
+ * @param context the context of the application to provide the canvas
+ * @param defZoom initial zoom ratio
+ * @param minZoom maximal allowed zoom out
+ * @param maxZoom maximal allowed zoom in
+ * @param defXCenter initial position of the scene
+ * @param minX minimal scene position on X axis
+ * @param maxX maximal scene position on X axis
+ * @param defYCenter initial position of the scene
+ * @param minY minimal scene position on Y axis
+ * @param maxY maximal scene position on Y axis
+ * @throws Exception
+ */
+ public SceneView(Context context,
+ float defZoom, float minZoom, float maxZoom,
+ float defXCenter, float minX, float maxX,
+ float defYCenter, float minY, float maxY) throws Exception {
+ super(context);
+ mDefaultZoomRatio = defZoom;
+ mDefaultXPos = defXCenter;
+ mDefaultYPos = defYCenter;
+ mZoom = new IntervalValue<Float>(defZoom, minZoom, maxZoom);
+ mXPosition = new IntervalValue<Float>(defXCenter, minX, maxX);
+ mYPosition = new IntervalValue<Float>(defYCenter, minY, maxY);
+ mListener = null;
+ mPaint = new Paint();
+ }
+
+ /**
+ * Default class constructor, all default values are set to zeros.
+ * @param context the context of the application to provide the canvas
+ * @throws Exception
+ */
+ public SceneView(Context context) throws Exception {
+ this(context, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
+ }
+
+ /**
+ * Set a listener of the events
+ * @param listener listener of the events
+ */
+ public void setListener(SceneChange listener) {
+ mListener = listener;
+ }
+
+ /**
+ * Set new default values. Default values are loaded when reset function is called.
+ * Values are stored only, not applied.
+ * @param zoom default zoom ratio
+ * @param x default x position
+ * @param y default y position
+ */
+ public void setDefaultValues(float zoom, float x, float y) {
+ mDefaultXPos = x;
+ mDefaultYPos = y;
+ mDefaultZoomRatio = zoom;
+ }
+
+ /**
+ * Zoom scene function. The scene can be zoomed in or out only in limits
+ * defined in constructor.
+ * @param deltaRatio when > 0 - zoom in,<br> when < 0 - zoom out
+ */
+ public void zoom(float deltaRatio) {
+ float ratio = mZoom.getValue();
+ ratio += deltaRatio;
+ if (mZoom.setValue(ratio) == true && mListener != null) {
+ mListener.onSceneChanged(this);
+ }
+ }
+
+ /**
+ * Move scene function. The scene can be moved only in the rectangle specified
+ * by limits defined in constructor.
+ * @param x change of the x coordinate relatively to the actual position
+ * @param y change of the y coordinate relatively to the actual position
+ */
+ public void move(float x, float y) {
+ boolean xWasSet = mXPosition.setValue(mXPosition.getValue() + x/mZoom.getValue()*2.2f);
+ boolean yWasSet = mYPosition.setValue(mYPosition.getValue() + y/mZoom.getValue()*2.2f);
+
+ if ((xWasSet || yWasSet) && mListener != null) {
+ mListener.onSceneChanged(this);
+ }
+ }
+
+ /**
+ * Reset the zoom ratio and scene position to default values.
+ */
+ public void reset() {
+ boolean xWasSet = mXPosition.setValue(mDefaultXPos);
+ boolean yWasSet = mYPosition.setValue(mDefaultYPos);
+ boolean zoomWasSet = mZoom.setValue(mDefaultZoomRatio);
+ if ((xWasSet || yWasSet || zoomWasSet) && mListener != null) {
+ mListener.onSceneChanged(this);
+ }
+ }
+
+ /**
+ * Abstract function for scene dimensions calculation to be implemented.
+ */
+ protected abstract void computeSceneDimmensions();
+
+ /**
+ * Abstract function with the drawing process to be implemented
+ */
+ public abstract void draw(Canvas c);
+
+ /**
+ * @return actual scene zoom ratio
+ */
+ public float getZoomRatio() {
+ return mZoom.getValue();
+ }
+
+ /**
+ * @return actual scene position on X axis
+ */
+ public float getXPosition() {
+ return mXPosition.getValue();
+ }
+
+ /**
+ * @return actual scene positoin on Y axis
+ */
+ public float getYPosition() {
+ return mYPosition.getValue();
+ }
+
+ /**
+ * @return how tall the scene is
+ */
+ public float getSceneHeight() {
+ return mSceneHeight;
+ }
+
+ /**
+ * @return how wide the scene is
+ */
+ public float getSceneWidth() {
+ return mSceneWidth;
+ }
+
+ @Override
+ protected void onDraw(Canvas c) {
+ draw(c);
+ super.onDraw(c);
+ }
+}
--- /dev/null
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context="cz.cvut.fel.dce.qrscanner.pdfviewer.PdfViewActivity">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/page_number_label"
+ android:id="@+id/textView"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentStart="true"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/page_state_scrolling"
+ android:id="@+id/textView2"
+ android:layout_alignParentEnd="true"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="1"
+ android:id="@+id/page_number"
+ android:layout_toEndOf="@+id/textView"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/pdf_viewer_state_label"
+ android:id="@+id/textView4"
+ android:layout_alignParentTop="true"
+ android:layout_toStartOf="@+id/textView2"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="/"
+ android:id="@+id/textView3"
+ android:layout_toEndOf="@+id/page_number"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="1"
+ android:id="@+id/total_pages_num"
+ android:layout_alignParentTop="true"
+ android:layout_toEndOf="@+id/textView3"/>
+
+ <FrameLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_below="@+id/textView"
+ android:layout_alignParentStart="true"
+ android:id="@+id/pdf_view_container">
+ </FrameLayout>
+
+</RelativeLayout>
--- /dev/null
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:context="cz.cvut.fel.dce.qrscanner.pdfviewer.PdfViewActivity">
+ <item android:id="@+id/action_settings"
+ android:title="@string/action_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never"/>
+</menu>
--- /dev/null
+<resources>
+ <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+ (such as screen margins) for screens with more than 820dp of available width. This
+ would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+ <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
--- /dev/null
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
<string name="show_pictured_manufacturing">Pictured manuf</string>
<string name="show_workshop">Workshow guide</string>
<string name="glass_voice_trigger">Skoda Manufacturer Helper</string>
+ <string name="title_activity_pdf_view">PdfViewActivity</string>
+ <string name="action_settings">Settings</string>
+ <string name="page_number_label">Page:</string>
+ <string name="pdf_viewer_state_label">State:</string>
+ <string name="page_state_scrolling">scrolling</string>
</resources>