diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..30aa626 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..37a7509 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0afbb86 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..d3577b4 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,29 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "com.example.imageviewer" + minSdkVersion 16 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'com.android.support:support-v4:28.0.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/androidTest/java/com/example/imageviewer/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/imageviewer/ExampleInstrumentedTest.java new file mode 100644 index 0000000..053c822 --- /dev/null +++ b/app/src/androidTest/java/com/example/imageviewer/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.imageviewer; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.example.imageviewer", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c88840a --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/imageviewer/DetailsActivity.java b/app/src/main/java/com/example/imageviewer/DetailsActivity.java new file mode 100644 index 0000000..b7b825e --- /dev/null +++ b/app/src/main/java/com/example/imageviewer/DetailsActivity.java @@ -0,0 +1,82 @@ +package com.example.imageviewer; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import java.io.Serializable; + +public class DetailsActivity extends AppCompatActivity implements Serializable { + + Context context; + ImageView iVHandler; + TextView uriHandler; + TextView inameHandler; + + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.i(getLocalClassName(), "onCreate"); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_details); + + context = this; + iVHandler = findViewById(R.id.picImage); //attacthing imageview to handler + + Intent intent = getIntent(); //retrieving an intent + final Uri storeImage = Uri.parse(intent.getStringExtra(Intent.EXTRA_STREAM)); // retriving image uri. was txt. convert back to uri to display TODO getStringExtra + + iVHandler.setImageURI(storeImage); + + iVHandler.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(context, FullscreenActivity.class); + intent.putExtra(Intent.EXTRA_STREAM, storeImage.toString()); + startActivity(intent); + } + }); + + uriHandler = findViewById(R.id.view_image_uri); + uriHandler.setText(storeImage.toString()); + + inameHandler = findViewById(R.id.view_image_name); + inameHandler.setText(intent.getStringExtra(Intent.EXTRA_TEXT)); + } + + @Override + protected void onStart() { + super.onStart(); + Log.i(getLocalClassName(), "onStart"); + } + + @Override + protected void onResume() { + super.onResume(); + Log.i(getLocalClassName(), "onResume"); + } + + @Override + protected void onPause() { + super.onPause(); + Log.i(getLocalClassName(), "onPause"); + } + + @Override + protected void onStop() { + super.onStop(); + Log.i(getLocalClassName(), "onStop"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.i(getLocalClassName(), "onDestroy"); + } + +} diff --git a/app/src/main/java/com/example/imageviewer/FullscreenActivity.java b/app/src/main/java/com/example/imageviewer/FullscreenActivity.java new file mode 100644 index 0000000..c9d6f5d --- /dev/null +++ b/app/src/main/java/com/example/imageviewer/FullscreenActivity.java @@ -0,0 +1,202 @@ +package com.example.imageviewer; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.net.Uri; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.ImageView; + +/** + * An example full-screen activity that shows and hides the system UI (i.e. + * status bar and navigation/system bar) with user interaction. + */ +public class FullscreenActivity extends AppCompatActivity { + /** + * Whether or not the system UI should be auto-hidden after + * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds. + */ + private static final boolean AUTO_HIDE = true; + + /** + * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after + * user interaction before hiding the system UI. + */ + private static final int AUTO_HIDE_DELAY_MILLIS = 3000; + + /** + * Some older devices needs a small delay between UI widget updates + * and a change of the status and navigation bar. + */ + private static final int UI_ANIMATION_DELAY = 300; + private final Handler mHideHandler = new Handler(); + private ImageView mContentView; + private final Runnable mHidePart2Runnable = new Runnable() { + @SuppressLint("InlinedApi") + @Override + public void run() { + // Delayed removal of status and navigation bar + + // Note that some of these constants are new as of API 16 (Jelly Bean) + // and API 19 (KitKat). It is safe to use them, as they are inlined + // at compile-time and do nothing on earlier devices. + mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); + } + }; + private View mControlsView; + private final Runnable mShowPart2Runnable = new Runnable() { + @Override + public void run() { + // Delayed display of UI elements + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.show(); + } + mControlsView.setVisibility(View.VISIBLE); + } + }; + private boolean mVisible; + private final Runnable mHideRunnable = new Runnable() { + @Override + public void run() { + hide(); + } + }; + /** + * Touch listener to use for in-layout UI controls to delay hiding the + * system UI. This is to prevent the jarring behavior of controls going away + * while interacting with activity UI. + */ + private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() { + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + if (AUTO_HIDE) { + delayedHide(AUTO_HIDE_DELAY_MILLIS); + } + return false; + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Log.i(this.getClass().getSimpleName(), "onCreate"); + setContentView(R.layout.activity_fullscreen); + + mVisible = true; + mControlsView = findViewById(R.id.fullscreen_content_controls); + mContentView = findViewById(R.id.fullscreen_content); + + Intent intent = getIntent(); + Uri storeImage = Uri.parse(intent.getStringExtra(Intent.EXTRA_STREAM)); + + mContentView.setImageURI(storeImage); + + // Set up the user interaction to manually show or hide the system UI. + mContentView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + toggle(); + } + }); + + // Upon interacting with UI controls, delay any scheduled hide() + // operations to prevent the jarring behavior of controls going away + // while interacting with the UI. + } + + @Override + protected void onStart() { + super.onStart(); + Log.i(this.getClass().getSimpleName(), "onStart"); + } + + @Override + protected void onResume() { + super.onResume(); + Log.i(this.getClass().getSimpleName(), "onResume"); + } + + @Override + protected void onPause() { + super.onPause(); + Log.i(this.getClass().getSimpleName(), "onPause"); + } + + @Override + protected void onStop() { + super.onStop(); + Log.i(this.getClass().getSimpleName(), "onStop"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.i(this.getClass().getSimpleName(), "onDestroy"); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + + // Trigger the initial hide() shortly after the activity has been + // created, to briefly hint to the user that UI controls + // are available. + delayedHide(100); + } + + private void toggle() { + if (mVisible) { + hide(); + } else { + show(); + } + } + + private void hide() { + // Hide UI first + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); + } + mControlsView.setVisibility(View.GONE); + mVisible = false; + + // Schedule a runnable to remove the status and navigation bar after a delay + mHideHandler.removeCallbacks(mShowPart2Runnable); + mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY); + } + + @SuppressLint("InlinedApi") + private void show() { + // Show the system bar + mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + mVisible = true; + + // Schedule a runnable to display UI elements after a delay + mHideHandler.removeCallbacks(mHidePart2Runnable); + mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY); + } + + /** + * Schedules a call to hide() in delay milliseconds, canceling any + * previously scheduled calls. + */ + private void delayedHide(int delayMillis) { + mHideHandler.removeCallbacks(mHideRunnable); + mHideHandler.postDelayed(mHideRunnable, delayMillis); + } +} + + diff --git a/app/src/main/java/com/example/imageviewer/ImageData.java b/app/src/main/java/com/example/imageviewer/ImageData.java new file mode 100644 index 0000000..fe0a0e1 --- /dev/null +++ b/app/src/main/java/com/example/imageviewer/ImageData.java @@ -0,0 +1,40 @@ +package com.example.imageviewer; + +import android.net.Uri; +import java.io.Serializable; + + +public class ImageData implements Serializable { + private String uri, name; + private int id; + + public ImageData(Uri uri, int id){ + this.uri = uri.toString(); + this.id = id; + this.name = "Image" +id; + } + + + + public ImageData(String Uri, String name) { + this.uri = Uri; + this.name = name; + } + + public Uri getUri() { + return Uri.parse(uri); + } + + public void setUri(Uri uri) { + this.uri = uri.toString(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/app/src/main/java/com/example/imageviewer/MainActivity.java b/app/src/main/java/com/example/imageviewer/MainActivity.java new file mode 100644 index 0000000..6c68a82 --- /dev/null +++ b/app/src/main/java/com/example/imageviewer/MainActivity.java @@ -0,0 +1,108 @@ +package com.example.imageviewer; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.util.TypedValue; +import android.view.View; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; + + + +public class MainActivity extends AppCompatActivity { + + public static final int IMAGE_REQUEST_CODE = 1; + Context context; + ImageData imageData; + static int nextId = 0; + + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.i(getLocalClassName(), "onCreate"); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + context = this; //TODO find out more on =this part + + ((Button)findViewById(R.id.main_button)).setOnClickListener(new View.OnClickListener() { //making button clickable + @Override + public void onClick(View v) { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); //creating new implicit internet that grabs pic from elsewehre + intent.setType("image/*"); //allows any type of pic + startActivityForResult(intent, IMAGE_REQUEST_CODE); //start new activity for results TODO look up startActivityForResult for beter understanding + } + }); + + } + + @Override + protected void onStart() { + super.onStart(); + Log.i(getLocalClassName(), "onStart"); + } + + @Override + protected void onResume() { + super.onResume(); + Log.i(getLocalClassName(), "onResume"); + } + + @Override + protected void onPause() { + super.onPause(); + Log.i(getLocalClassName(), "onPause"); + } + + @Override + protected void onStop() { + super.onStop(); + Log.i(getLocalClassName(), "onStop"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.i(getLocalClassName(), "onDestroy"); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK && requestCode == IMAGE_REQUEST_CODE) { // if statement checking if result are valid the request is valid + if (data != null) { // making sure data is not null + + Uri picUri = data.getData(); //get image uri + imageData = new ImageData(picUri, nextId++); //created new image object that hold uri and id, id increments and is used part of imageName + ((LinearLayout)findViewById(R.id.main_linear_layout)).addView(genText(imageData.getName())); // adding textview to linear layout, call genText method and passes in imageName + + } + } + } + + private TextView genText(String imageName){ //parameter for image name. after image created. "saves name" + TextView view = new TextView(context); // create new textview + view.setText(imageName); // setting text to pic name with + view.setPadding(15, 15, 15, 15); // density pixels + view.setTextSize(TypedValue.COMPLEX_UNIT_SP,18); // scale pixels (text - scale to users phone) + + view.setOnClickListener(new View.OnClickListener() { //set when imageName pressed info pops up in new activity pic,uri,uri name,desc + @Override + public void onClick(View v) { + Intent intent = new Intent(context, DetailsActivity.class); //creats new explicit intent + intent.putExtra(Intent.EXTRA_STREAM, imageData.getUri().toString()); // TODO look up putExtra for better understanding. + intent.putExtra(Intent.EXTRA_TEXT, imageData.getName()); // TODO + startActivity(intent); // starts activity based on intent in para + } + }); + + return view; + } + + +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_details.xml b/app/src/main/res/layout/activity_details.xml new file mode 100644 index 0000000..1b0cc75 --- /dev/null +++ b/app/src/main/res/layout/activity_details.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_fullscreen.xml b/app/src/main/res/layout/activity_fullscreen.xml new file mode 100644 index 0000000..7140182 --- /dev/null +++ b/app/src/main/res/layout/activity_fullscreen.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..2e0e28d --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,33 @@ + + + + + + /LinearLayout> + + +