diff --git a/.gitignore b/.gitignore index 0df7064..4d78963 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ *.iml .gradle -/local.properties -/.idea/ +local.properties +.idea .DS_Store -/build -/captures +build +captures .externalNativeBuild diff --git a/app/build.gradle b/app/build.gradle index b0aefae..c172c75 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,9 +1,5 @@ apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -apply plugin: 'kotlin-android-extensions' - android { compileSdkVersion 28 defaultConfig { @@ -30,17 +26,11 @@ android { } dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + 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.volley:volley:1.1.1' implementation 'com.loopj.android:android-async-http:1.4.9' implementation 'org.jsoup:jsoup:1.7.2' - implementation group: 'commons-io', name: 'commons-io', version: '2.4' -// implementation 'com.squareup.retrofit2:retrofit:2.1.0' -// implementation 'com.google.code.gson:gson:2.8.2' -// implementation 'com.squareup.retrofit2:converter-gson:2.1.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/src/androidTest/java/eu/dasancti/reversee/ExampleInstrumentedTest.java b/app/src/androidTest/java/eu/dasancti/reversee/ExampleInstrumentedTest.java new file mode 100644 index 0000000..0b5fd87 --- /dev/null +++ b/app/src/androidTest/java/eu/dasancti/reversee/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package eu.dasancti.reversee; + +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("eu.dasancti.reversee", appContext.getPackageName()); + } +} diff --git a/app/src/androidTest/java/eu/dasancti/reversee/ExampleInstrumentedTest.kt b/app/src/androidTest/java/eu/dasancti/reversee/ExampleInstrumentedTest.kt deleted file mode 100644 index 94158fa..0000000 --- a/app/src/androidTest/java/eu/dasancti/reversee/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package eu.dasancti.reversee - -import android.support.test.InstrumentationRegistry -import android.support.test.runner.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getTargetContext() - assertEquals("eu.dasancti.reversee", appContext.packageName) - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f9c6b08..8fd9108 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + package="eu.dasancti.reversee"> @@ -10,7 +9,7 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme"> + android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"> @@ -19,5 +18,4 @@ - - \ No newline at end of file + diff --git a/app/src/main/java/eu/dasancti/reversee/MainActivity.java b/app/src/main/java/eu/dasancti/reversee/MainActivity.java index 6eacf12..42ace02 100644 --- a/app/src/main/java/eu/dasancti/reversee/MainActivity.java +++ b/app/src/main/java/eu/dasancti/reversee/MainActivity.java @@ -5,7 +5,10 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; +import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.TextView; @@ -33,8 +36,10 @@ public class MainActivity extends AppCompatActivity { private static final String API_SCH_VALUE = "sch"; private static final String API_ENCODED_IMAGE_KEY = "encoded_image"; private static final String API_USER_AGENT_KEY = "User-Agent"; + private static final int REQUEST_PERMISSION_EXTERNAL_STORAGE_STATE = 99; private TextView progressStatus; + private Uri requestPermissionsFallbackUri; @Override protected void onCreate(Bundle savedInstanceState) { @@ -45,11 +50,16 @@ protected void onCreate(Bundle savedInstanceState) { Intent intent = getIntent(); String action = intent.getAction(); + if (action == null) { + Toast.makeText(MainActivity.this, "No action sent to application, closing.", Toast.LENGTH_SHORT).show(); + this.finish(); + return; + } if (isPermissionGranted()) { if (action.equals(Intent.ACTION_SEND)) { progressStatus.setText(getString(R.string.progress_status_recieved_intent)); try { - handleImageSearch(intent); + handleImageSearch(intent.getParcelableExtra(Intent.EXTRA_STREAM)); } catch (FileNotFoundException e) { String err = "Failed to handle Share image intent:"+e.getMessage(); Log.e("INTENT_HANDLE",err); @@ -57,12 +67,47 @@ protected void onCreate(Bundle savedInstanceState) { } } } else { - Toast.makeText(this, "The app wasn't allowed permissions to manage files.", Toast.LENGTH_LONG).show(); + android.support.v7.app.AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Read storage permission required."); + builder.setMessage("This application requires READ_EXTERNAL_STORAGE permission in order to function properly."); + builder.setPositiveButton("Grant permission", (dialog, which) -> { + ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSION_EXTERNAL_STORAGE_STATE); + if (action.equals(Intent.ACTION_SEND)) { + requestPermissionsFallbackUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); + } + }); + builder.setNegativeButton("Deny permission", ((dialog, which) -> { + Toast.makeText(MainActivity.this, "Permission not granted, closing.", Toast.LENGTH_SHORT).show(); + this.finish(); + })); + builder.create().show(); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String permissions[], + @NonNull int[] grantResults) { + switch (requestCode) { + case REQUEST_PERMISSION_EXTERNAL_STORAGE_STATE: + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show(); + try { + handleImageSearch(this.requestPermissionsFallbackUri); + } catch (FileNotFoundException e) { + String err = "Failed to handle Share image intent:"+e.getMessage(); + Log.e("INTENT_HANDLE",err); + Toast.makeText(getApplicationContext(), err, Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(MainActivity.this, "Permission not granted, closing.", Toast.LENGTH_SHORT).show(); + this.finish(); + } + break; } } - private void handleImageSearch(Intent intent) throws FileNotFoundException { - Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); + private void handleImageSearch(Uri imageUri) throws FileNotFoundException { progressStatus.setText(getString(R.string.progress_status_handling_image)); AtomicReference reverseSearchRedirectURL = new AtomicReference<>(); AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml index 6348baa..c7bd21d 100644 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -1,34 +1,34 @@ + xmlns:aapt="http://schemas.android.com/aapt" + android:width="108dp" + android:height="108dp" + android:viewportHeight="108" + android:viewportWidth="108"> + android:fillType="evenOdd" + android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z" + android:strokeColor="#00000000" + android:strokeWidth="1"> + android:endX="78.5885" + android:endY="90.9159" + android:startX="48.7653" + android:startY="61.0927" + android:type="linear"> + android:color="#44000000" + android:offset="0.0" /> + android:color="#00000000" + android:offset="1.0" /> + android:fillColor="#FFFFFF" + android:fillType="nonZero" + android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z" + android:strokeColor="#00000000" + android:strokeWidth="1" /> diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index a0ad202..2408e30 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,10 +1,10 @@ + android:height="108dp" + android:width="108dp" + android:viewportHeight="108" + android:viewportWidth="108" + xmlns:android="http://schemas.android.com/apk/res/android"> Reversee - Recieved intent data (image share) + Recieved intent data (image share) Handling google reverse image search. Google request successful. Found redirect URL, opening browser intent. diff --git a/app/src/test/java/eu/dasancti/reversee/ExampleUnitTest.java b/app/src/test/java/eu/dasancti/reversee/ExampleUnitTest.java new file mode 100644 index 0000000..3b71d6a --- /dev/null +++ b/app/src/test/java/eu/dasancti/reversee/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package eu.dasancti.reversee; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/app/src/test/java/eu/dasancti/reversee/ExampleUnitTest.kt b/app/src/test/java/eu/dasancti/reversee/ExampleUnitTest.kt deleted file mode 100644 index af4f0b2..0000000 --- a/app/src/test/java/eu/dasancti/reversee/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package eu.dasancti.reversee - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} diff --git a/build.gradle b/build.gradle index a3176b9..8d3ef8e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.2.71' + repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.2.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files