Initial commit

This commit is contained in:
2018-12-30 13:59:29 +11:00
commit 934134621d
72 changed files with 4542 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
*.iml
.gradle
/local.properties
/.idea/caches/build_file_checksums.ser
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
/captures
.externalNativeBuild

29
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,29 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>

7
.idea/dictionaries/h_mal.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<component name="ProjectDictionaryState">
<dictionary name="h_mal">
<words>
<w>retreived</w>
</words>
</dictionary>
</component>

18
.idea/gradle.xml generated Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

38
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="7">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

12
.idea/runConfigurations.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

1
app/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

32
app/build.gradle Normal file
View File

@@ -0,0 +1,32 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.appttude.h_mal.exchangemap"
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.google.android.gms:play-services-maps:16.0.0'
implementation 'com.google.android.gms:play-services-places:16.0.0'
implementation "com.google.android.gms:play-services-location:16.0.0"
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'
}

21
app/proguard-rules.pro vendored Normal file
View File

@@ -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

View File

@@ -0,0 +1,26 @@
package com.appttude.h_mal.exchangemap;
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 <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.appttude.h_mal.exchangemap", appContext.getPackageName());
}
}

View File

@@ -0,0 +1,24 @@
<resources>
<!--
TODO: Before you run your application, you need a Google Maps API key.
To get one, follow this link, follow the directions and press "Create" at the end:
https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=E1:12:18:59:7E:FA:B2:FC:23:8C:8E:03:36:89:BE:3E:09:BC:5D:FB%3Bcom.appttude.h_mal.exchangemap
You can also add your credentials to an existing key, using these values:
Package name:
E1:12:18:59:7E:FA:B2:FC:23:8C:8E:03:36:89:BE:3E:09:BC:5D:FB
SHA-1 certificate fingerprint:
E1:12:18:59:7E:FA:B2:FC:23:8C:8E:03:36:89:BE:3E:09:BC:5D:FB
Alternatively, follow the directions here:
https://developers.google.com/maps/documentation/android/start#get-key
Once you have your key (it starts with "AIza"), replace the "google_maps_key"
string in this file.
-->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyA8DdDZvG6ihSrR5TlkG4FXb6ffyt19_Pg</string>
</resources>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.appttude.h_mal.exchangemap">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1,96 @@
package com.appttude.h_mal.exchangemap;
import android.app.Dialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
public class CustomDialogClass extends Dialog implements android.view.View.OnClickListener{
Context context;
ListView listView;
TextView textView;
EditText editText;
int selection;
public CustomDialogClass(@NonNull Context context, TextView textView) {
super(context);
this.context = context;
this.textView = textView;
if (textView.getId() == R.id.currency_one){
selection = 1;
}else{
selection = 2;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_dialog);
// getWindow().setBackgroundDrawableResource(android.R.color.transparent);
//
// getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//
// listView = (ListView) findViewById(R.id.list_view);
// editText = (EditText) findViewById(R.id.search_text) ;
//
// final ArrayAdapter<CharSequence> arrayAdapter = ArrayAdapter.createFromResource(context,R.array.currency_arrays,android.R.layout.simple_list_item_1);
// listView.setAdapter(arrayAdapter);
//
// editText.addTextChangedListener(new TextWatcher() {
// @Override
// public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//
// }
//
// @Override
// public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
// arrayAdapter.getFilter().filter(charSequence);
// }
//
// @Override
// public void afterTextChanged(Editable editable) {
//
// }
// });
//
// listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// @Override
// public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// textView.setText(adapterView.getItemAtPosition(i).toString());
// SharedPreferences.Editor editor = pref.edit();
// if (selection == 1) {
// editor.putString(CURRENCY_ONE,adapterView.getItemAtPosition(i).toString());
// }else{
// editor.putString(CURRENCY_TWO,adapterView.getItemAtPosition(i).toString());
// }
// editor.apply();
// currencyOneEditText.setText("");
// currencyTwoEditText.setText("");
// String stringURL = UriBuilder(currencyOne.getText().toString().substring(0,3),
// currencyTwo.getText().toString().substring(0,3));
// MyAsyncTask task = new MyAsyncTask();
// task.execute(stringURL);
// dismiss();
// }
// });
}
@Override
public void onClick(View view) {
}
}

View File

@@ -0,0 +1,367 @@
package com.appttude.h_mal.exchangemap;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.text.TextPaint;
import android.text.style.CharacterStyle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.common.data.DataBufferUtils;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.AutocompletePrediction;
import com.google.android.gms.location.places.AutocompletePredictionBufferResponse;
import com.google.android.gms.location.places.GeoDataClient;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.PlaceBufferResponse;
import com.google.android.gms.location.places.PlaceDetectionClient;
import com.google.android.gms.location.places.PlaceLikelihood;
import com.google.android.gms.location.places.PlaceLikelihoodBufferResponse;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.RuntimeExecutionException;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static android.content.ContentValues.TAG;
import static com.appttude.h_mal.exchangemap.MapsJsonCall.*;
import static com.google.android.gms.location.places.AutocompleteFilter.TYPE_FILTER_ADDRESS;
import static com.google.android.gms.location.places.AutocompleteFilter.TYPE_FILTER_ESTABLISHMENT;
public class FragmentMap extends Fragment implements OnMapReadyCallback {
private GoogleMap mMap;
private GeoDataClient mGeoDataClient;
private PlaceDetectionClient mPlaceDetectionClient;
LatLngBounds bounds;
private String TAG = getClass().getSimpleName();
public FragmentMap() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootview = inflater.inflate(R.layout.fragment_maps, container, false);
FloatingActionButton fab = rootview.findViewById(R.id.floatingActionButton);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = (MapsActivity.fragmentManager).beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right)
.replace(R.id.container,new FragmentSearch())
.addToBackStack("search").commit();
}
});
return rootview;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment supportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
supportMapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng current = new LatLng(getLatLong.latitude, getLatLong.longitude);
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}else{
mMap.setMyLocationEnabled(true);
}
mMap.addCircle(new CircleOptions().center(current));
// mMap.addMarker(new MarkerOptions().position(current).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(current));
double radiusDegrees = 0.;
LatLng northEast = new LatLng(current.latitude + radiusDegrees, current.longitude + radiusDegrees);
LatLng southWest = new LatLng(current.latitude - radiusDegrees, current.longitude - radiusDegrees);
bounds = LatLngBounds.builder()
.include(northEast)
.include(southWest)
.build();
mGeoDataClient = Places.getGeoDataClient(getContext());
getLocationOnMap locationOnMap = new getLocationOnMap();
locationOnMap.execute(current);
// AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
// .setTypeFilter(TYPE_FILTER_ESTABLISHMENT )
// .build();
//
// Task<AutocompletePredictionBufferResponse> results =
// mGeoDataClient.getAutocompletePredictions("currency", bounds, typeFilter);
//
//
// LocationAsyncTask locationAsyncTask = new LocationAsyncTask();
// locationAsyncTask.execute(results);
}
private void showCurrentPlace() {
if (mMap == null) {
return;
}
// final LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
// LatLngBounds newBounds = null;
try{
@SuppressWarnings("MissingPermission") final
Task<PlaceLikelihoodBufferResponse> placeResult =
mPlaceDetectionClient.getCurrentPlace(null);
placeResult.addOnCompleteListener
(new OnCompleteListener<PlaceLikelihoodBufferResponse>() {
@Override
public void onComplete(@NonNull Task<PlaceLikelihoodBufferResponse> task) {
if (task.isSuccessful() && task.getResult() != null) {
PlaceLikelihoodBufferResponse likelyPlaces = task.getResult();
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
// Build a list of likely places to show the user.
Place myPlace = placeLikelihood.getPlace();
Log.i(TAG, "Place found: " + myPlace.getName());
mMap.addMarker(new MarkerOptions().position(myPlace.getLatLng()).title(myPlace.getName().toString()));
// boundsBuilder.include(placeLikelihood.getPlace().getLatLng());
}
// Release the place likelihood buffer, to avoid memory leaks.
likelyPlaces.release();
} else {
Log.e(TAG, "Exception: %s", task.getException());
}
}
});
// newBounds = boundsBuilder.build();
}catch (Exception e){
Log.e(TAG, "showCurrentPlace: ", e);
}finally {
// try {
// CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(newBounds, 10);
// mMap.animateCamera(cameraUpdate);
// }catch (Exception e){
// Log.e(TAG, "onPostExecute: ", e);
// }finally {
// if (newBounds == null){
// mMap.animateCamera( CameraUpdateFactory.newLatLngBounds(bounds, 0) );
// }
// }
}
}
private class getLocationOnMap extends AsyncTask<LatLng,Void,MapItem>{
@Override
protected MapItem doInBackground(LatLng... latLngs) {
String json = null;
MapItem mapItem = null;
try {
Log.i(TAG, "doInBackground: " + UriBuilder(latLngs[0]) );
URL url = createUrl(UriBuilder(latLngs[0]));
json = makeHttpRequest(url);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (json != null){
mapItem = extractFeatureFromJson(json);
}
}
return mapItem;
}
@Override
protected void onPostExecute(MapItem mapItem) {
super.onPostExecute(mapItem);
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
LatLngBounds newBounds = null;
try {
ArrayList<MapItem.result> results = mapItem.getResults();
for (int i=0; i <results.size(); i++){
String id = results.get(i).getPlace_id();
boundsBuilder.include(mapItem.getResults().get(i).getGeometry().getLocation());
mGeoDataClient.getPlaceById(id).addOnCompleteListener(new OnCompleteListener<PlaceBufferResponse>() {
@Override
public void onComplete(@NonNull Task<PlaceBufferResponse> task) {
if (task.isSuccessful()) {
PlaceBufferResponse places = task.getResult();
Place myPlace = places.get(0);
Log.i(TAG, "Place found: " + myPlace.getName());
mMap.addMarker(new MarkerOptions().position(myPlace.getLatLng()).title(myPlace.getName().toString()));
places.release();
} else {
Log.e(TAG, "Place not found.");
}
}
});
}
newBounds = boundsBuilder.build();
}catch (Exception e){
Log.e(TAG, "onPostExecute: ",e );
}finally {
try {
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(newBounds, 10);
mMap.animateCamera(cameraUpdate);
}catch (Exception e){
Log.e(TAG, "onPostExecute: ", e);
}finally {
if (newBounds == null){
mMap.animateCamera( CameraUpdateFactory.newLatLngBounds(bounds, 0) );
}
}
}
}
}
private class LocationAsyncTask extends AsyncTask<Task<AutocompletePredictionBufferResponse>, Void, AutocompletePredictionBufferResponse>{
@Override
protected AutocompletePredictionBufferResponse doInBackground(Task<AutocompletePredictionBufferResponse>... tasks) {
try {
Tasks.await(tasks[0], 60, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException e) {
e.printStackTrace();
}
return tasks[0].getResult();
}
@Override
protected void onPostExecute(AutocompletePredictionBufferResponse response) {
super.onPostExecute(response);
try {
Log.i(TAG, "Query completed. Received " + response.getCount()
+ " predictions.");
String [] ids = {"ChIJndkxNgNakWsRjHGZBzHxu8M","ChIJUcxf7YxbkWsRsndgEcBNlLQ","ChIJk-7r9ARakWsRv16cDh3GXzU","ChIJh4SRLgNakWsRuyWBDLouw-4","ChIJL533ngRakWsRUp51ucHAp5Q","ChIJy1uXvQRakWsRT6xLCK9LmzY","ChIJcTZWngRakWsRm8Cz7egsDm8","ChIJDfur3xxakWsR4WP10zl01Hg"};
for (int i=0; i <ids.length; i++){
mGeoDataClient.getPlaceById(ids[i]).addOnCompleteListener(new OnCompleteListener<PlaceBufferResponse>() {
@Override
public void onComplete(@NonNull Task<PlaceBufferResponse> task) {
if (task.isSuccessful()) {
PlaceBufferResponse places = task.getResult();
Place myPlace = places.get(0);
Log.i(TAG, "Place found: " + myPlace.getName());
mMap.addMarker(new MarkerOptions().position(myPlace.getLatLng()).title(myPlace.getName().toString()));
places.release();
} else {
Log.e(TAG, "Place not found.");
}
}
});
}
// for (int i = 0; i < response.getCount(); i++){
// final String retrievedId = response.get(i).getPlaceId();
//
// mGeoDataClient.getPlaceById(retrievedId).addOnCompleteListener(new OnCompleteListener<PlaceBufferResponse>() {
// @Override
// public void onComplete(@NonNull Task<PlaceBufferResponse> task) {
// if (task.isSuccessful()) {
// PlaceBufferResponse places = task.getResult();
// Place myPlace = places.get(0);
// Log.i(TAG, "Place found: " + myPlace.getName());
// mMap.addMarker(new MarkerOptions().position(myPlace.getLatLng()).title(myPlace.getName().toString()));
// places.release();
// } else {
// Log.e(TAG, "Place not found.");
// }
// }
// });
// }
// // Freeze the results immutable representation that can be stored safely.
// ArrayList<AutocompletePrediction> al = DataBufferUtils.freezeAndClose(response);
//
// for (AutocompletePrediction p : al) {
// CharSequence cs = p.getFullText(new CharacterStyle() {
// @Override
// public void updateDrawState(TextPaint tp) {
// mMap.addMarker(new MarkerOptions().position().title("Marker in Sydney"));
// }
// });
// Log.i(TAG, cs.toString());
// }
} catch (RuntimeExecutionException e) {
// If the query did not complete successfully return null
Log.e(TAG, "Error getting autocomplete prediction API call", e);
} finally {
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,0));
}
}
}
}

View File

@@ -0,0 +1,101 @@
package com.appttude.h_mal.exchangemap;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EdgeEffect;
import android.widget.EditText;
import android.widget.ImageView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.AutocompletePrediction;
import com.google.android.gms.location.places.PlaceDetectionClient;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.location.places.ui.PlaceAutocomplete;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import static com.appttude.h_mal.exchangemap.MapsActivity.getLocationName;
import static com.google.android.gms.location.places.AutocompleteFilter.TYPE_FILTER_ADDRESS;
import static com.google.android.gms.location.places.AutocompleteFilter.TYPE_FILTER_CITIES;
import static com.google.android.gms.location.places.AutocompleteFilter.TYPE_FILTER_ESTABLISHMENT;
public class FragmentSearch extends Fragment implements GoogleApiClient.OnConnectionFailedListener {
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
private GoogleApiClient googleApiClient;
private PlaceAutocompleteAdapter mAutocompleteAdapter;
public static final LatLngBounds LAT_LNG_BOUNDS = new LatLngBounds(
new LatLng(-40,-160),new LatLng(71,136)
);
public FragmentSearch() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_search, container, false);
String[] airports = getResources().getStringArray(R.array.airports);
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, airports);
final AutoCompleteTextView homeLocationEditText = rootView.findViewById(R.id.location_home);
ImageView myLocation = rootView.findViewById(R.id.my_loc);
myLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String myLocation = getLocationName(getContext(),getLatLong.latitude,getLatLong.longitude);
homeLocationEditText.setText(myLocation);
}
});
AutoCompleteTextView departureEditText = rootView.findViewById(R.id.location_home_departure);
departureEditText.setAdapter(adapter);
AutoCompleteTextView arrivalEditText = rootView.findViewById(R.id.location_arrival_airport);
arrivalEditText.setAdapter(adapter);
googleApiClient = new GoogleApiClient.Builder(getContext())
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.enableAutoManage(getActivity(),this)
.build();
AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
.setTypeFilter(TYPE_FILTER_CITIES )
// .setTypeFilter(TYPE_FILTER_ADDRESS)
.build();
mAutocompleteAdapter = new PlaceAutocompleteAdapter(getContext(),googleApiClient,LAT_LNG_BOUNDS,typeFilter);
AutoCompleteTextView destinationEditText = rootView.findViewById(R.id.location_arrival_);
destinationEditText.setAdapter(mAutocompleteAdapter);
homeLocationEditText.setAdapter(mAutocompleteAdapter);
return rootView;
}
}

View File

@@ -0,0 +1,197 @@
package com.appttude.h_mal.exchangemap;
import android.support.annotation.Nullable;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import java.net.URL;
import java.util.ArrayList;
public class MapItem {
private String next_page_token;
private ArrayList<result> results;
public static class result{
private String formatted_Address;
private Geometry geometry;
private URL icon;
private String placeId;
private String name;
private OpeningHours openingHours;
private ArrayList<Photo> photos;
private String place_id;
private PlusCode plusCode;
private Double rating;
private String reference;
private ArrayList<String> types;
public result(String formatted_Address, Geometry geometry, URL icon, String placeId, String name,
@Nullable OpeningHours openingHours, @Nullable ArrayList<Photo> photos, String place_id, PlusCode plusCode, Double rating,
String reference, ArrayList<String> types) {
this.formatted_Address = formatted_Address;
this.geometry = geometry;
this.icon = icon;
this.placeId = placeId;
this.name = name;
this.openingHours = openingHours;
this.photos = photos;
this.place_id = place_id;
this.plusCode = plusCode;
this.rating = rating;
this.reference = reference;
this.types = types;
}
public String getFormatted_Address() {
return formatted_Address;
}
public Geometry getGeometry() {
return geometry;
}
public URL getIcon() {
return icon;
}
public String getPlaceId() {
return placeId;
}
public String getName() {
return name;
}
public OpeningHours getOpeningHours() {
return openingHours;
}
public ArrayList<Photo> getPhotos() {
return photos;
}
public String getPlace_id() {
return place_id;
}
public PlusCode getPlusCode() {
return plusCode;
}
public Double getRating() {
return rating;
}
public String getReference() {
return reference;
}
public ArrayList<String> getTypes() {
return types;
}
}
private String status;
public MapItem(String next_page_token, ArrayList<result> results, String status) {
this.next_page_token = next_page_token;
this.results = results;
this.status = status;
}
public String getNext_page_token() {
return next_page_token;
}
public ArrayList<result> getResults() {
return results;
}
public String getStatus() {
return status;
}
public static class Geometry{
private LatLng location;
private LatLngBounds viewport;
public Geometry(LatLng location, LatLngBounds viewport) {
this.location = location;
this.viewport = viewport;
}
public LatLng getLocation() {
return location;
}
public LatLngBounds getViewport() {
return viewport;
}
}
public static class OpeningHours{
private Boolean openNow;
public OpeningHours(Boolean openNow) {
this.openNow = openNow;
}
public Boolean getOpenNow() {
return openNow;
}
}
public static class Photo{
private int height;
private String htmlAttributions;
private String photoReference;
private int width;
public Photo(int height, String htmlAttributions, String photoReference, int width) {
this.height = height;
this.htmlAttributions = htmlAttributions;
this.photoReference = photoReference;
this.width = width;
}
public int getHeight() {
return height;
}
public String getHtmlAttributions() {
return htmlAttributions;
}
public String getPhotoReference() {
return photoReference;
}
public int getWidth() {
return width;
}
}
public static class PlusCode {
private String globalCode;
private String compoundCode;
public PlusCode(String globalCode, String compoundCode) {
this.globalCode = globalCode;
this.compoundCode = compoundCode;
}
public String getGlobalCode() {
return globalCode;
}
public String getCompoundCode() {
return compoundCode;
}
}
}

View File

@@ -0,0 +1,172 @@
package com.appttude.h_mal.exchangemap;
import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class MapsActivity extends FragmentActivity {
public static int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
public static FragmentManager fragmentManager;
private String currentFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
if (ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
}
getLatLong.configLatLong(this);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
// SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
// .findFragmentById(R.id.map);
// mapFragment.getMapAsync(this);
fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container,new FragmentMap()).addToBackStack("main")
// .setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left)
.commit();
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
List<Fragment> f = fragmentManager.getFragments();
Fragment frag = f.get(0);
currentFragment = frag.getClass().getSimpleName();
}
});
}
public static String getLocationName(Context context, Double latitude, Double longitude) {
Geocoder geoCoder = new Geocoder(context, Locale.getDefault());
String result = "";
List<Address> list = null;
try {
list = geoCoder.getFromLocation(latitude, longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (list != null & list.size() > 0) {
Address address = list.get(0);
result = address.getLocality();
}
}
return result;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
getLatLong.configLatLong(this);
} catch (Exception e) {
System.out.println("error msg: " + e);
}
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onBackPressed() {
switch (currentFragment) {
case "FragmentMap":
new AlertDialog.Builder(this)
.setTitle("Leave?")
.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
finish();
System.exit(0);
}
}).create().show();
return;
// case "FragmentAddItem":
// if(FragmentAddItem.mRadioGroup.getCheckedRadioButtonId() == -1) {
// fragmentManager.popBackStack();
// }else{
// new AlertDialog.Builder(this)
// .setTitle("Discard Changes?")
// .setMessage("Are you sure you want to discard changes?")
// .setNegativeButton(android.R.string.no, null)
// .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
// public void onClick(DialogInterface arg0, int arg1) {
// fragmentManager.popBackStack();
// }
// }).create().show();
//
// }
// return;
default:
if (fragmentManager.getBackStackEntryCount() > 1) {
fragmentManager.popBackStack();
}
}
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
}

View File

@@ -0,0 +1,217 @@
package com.appttude.h_mal.exchangemap;
import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import com.appttude.h_mal.exchangemap.MapItem.*;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
public class MapsJsonCall {
private static String TAG = MapsJsonCall.class.getSimpleName();
private static Context context;
protected static String UriBuilder(LatLng l){
Uri.Builder builder = new Uri.Builder();
builder.scheme("https")
.authority("maps.googleapis.com")
.appendPath("maps")
.appendPath("api")
.appendPath("place")
.appendPath("textsearch")
.appendPath("json")
.appendQueryParameter("query","currency exchange")
.appendQueryParameter("location",l.latitude+","+l.longitude)
.appendQueryParameter("radius","3")
.appendQueryParameter("key","QUl6YVN5QThEZERadkc2aWhTclI1VGxrRzRGWGI2ZmZ5dDE5X1Bn");
return builder.build().toString().replace("%2C",",").replace("%20", "+");
}
public static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e("ERROR", "Error with creating URL ", e);
}
return url;
}
public static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = null;
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(30000);
urlConnection.setConnectTimeout(30000);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e("", "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e("", "Problem retrieving the JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = "";
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
Log.d("", output.toString());
return output.toString();
}
public static MapItem extractFeatureFromJson(String newsJSON) {
if (TextUtils.isEmpty(newsJSON)) {
return null;
}
String next_page_token = "";
ArrayList<MapItem.result> results = new ArrayList<>();
String status = "";
try {
JSONObject baseJsonResponse = new JSONObject(newsJSON);
// next_page_token = baseJsonResponse.getString("next_page_token");
JSONArray resultsArray = baseJsonResponse.getJSONArray("results");
for (int i = 0; i < resultsArray.length(); i++) {
JSONObject currentResult = resultsArray.getJSONObject(i);
String formatted_Address = currentResult.getString("formatted_address");
JSONObject geometryObject = currentResult.getJSONObject("geometry");
JSONObject locationObject = geometryObject.getJSONObject("location");
LatLng location = new LatLng(locationObject.getDouble("lat"),locationObject.getDouble("lng"));
JSONObject viewPointObject = geometryObject.getJSONObject("viewport");
// LatLngBounds viewPort= new LatLngBounds(
LatLng northEast = new LatLng(viewPointObject.getJSONObject("northeast").getDouble("lat"),
viewPointObject.getJSONObject("northeast").getDouble("lng"));
LatLng southWest = new LatLng(viewPointObject.getJSONObject("southwest").getDouble("lat"),
viewPointObject.getJSONObject("southwest").getDouble("lng"));
LatLngBounds viewPort = LatLngBounds.builder().include(northEast).include(southWest).build();
MapItem.Geometry geometry = new Geometry(location,viewPort);
URL icon = createUrl(currentResult.getString("icon"));
String placeId = currentResult.getString("id");
String name = currentResult.getString("name");
JSONObject openingHoursObject = null;
OpeningHours openingHours = null;
try {
openingHoursObject = currentResult.getJSONObject("opening_hours");
}catch (Exception e){
Log.i(TAG, "extractFeatureFromJson: " + "no opening hours");
}finally {
if (openingHoursObject != null){
openingHours = new OpeningHours(openingHoursObject.getBoolean("open_now"));
}
}
JSONArray photosArray = null;
ArrayList<Photo> photos = null;
try {
photosArray = currentResult.getJSONArray("photos");
}catch (Exception e){
Log.i(TAG, "extractFeatureFromJson: " + "no photo");
}finally {
if (photosArray != null){
photos = new ArrayList<>();
for (int p = 0; p < photosArray.length(); p++) {
JSONObject photoObject = photosArray.getJSONObject(p);
int height = photoObject.getInt("height");
String htmlAttributions = photoObject.getString("html_attributions");
String photoReference = photoObject.getString("photo_reference");
int width = photoObject.getInt("width");
photos.add(new Photo(height,htmlAttributions,photoReference,width));
}
}
}
String place_id = currentResult.getString("place_id");
JSONObject plusCodeObject = currentResult.getJSONObject("plus_code");
PlusCode plusCode = new PlusCode(plusCodeObject.getString("compound_code"),
plusCodeObject.getString("global_code"));
Double rating = currentResult.getDouble("rating");
String reference = currentResult.getString("reference");
JSONArray typesObject = currentResult.getJSONArray("types");
ArrayList<String> types = new ArrayList<>();
for (int t = 0; t < typesObject.length(); t++) {
types.add(typesObject.get(t).toString());
}
MapItem.result result = new MapItem.result(formatted_Address,geometry,icon,placeId,name,openingHours,photos,place_id,plusCode,rating,reference,types);
results.add(result);
}
status = baseJsonResponse.getString("status");
} catch (JSONException e) {
Log.e("Error", "Problem parsing the book JSON results", e);
}
return new MapItem(next_page_token, results, status);
}
}

View File

@@ -0,0 +1,242 @@
package com.appttude.h_mal.exchangemap;/*
* Copyright (C) 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.common.data.DataBufferUtils;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.AutocompletePrediction;
import com.google.android.gms.location.places.AutocompletePredictionBuffer;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.model.LatLngBounds;
import android.content.Context;
import android.graphics.Typeface;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
/**
* Adapter that handles Autocomplete requests from the Places Geo Data API.
* {@link AutocompletePrediction} results from the API are frozen and stored directly in this
* adapter. (See {@link AutocompletePrediction#freeze()}.)
* <p>
* Note that this adapter requires a valid {@link com.google.android.gms.common.api.GoogleApiClient}.
* The API client must be maintained in the encapsulating Activity, including all lifecycle and
* connection states. The API client must be connected with the {@link Places#GEO_DATA_API} API.
*/
public class PlaceAutocompleteAdapter
extends ArrayAdapter<AutocompletePrediction> implements Filterable {
private static final String TAG = "PlaceAutoCompleteAd";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
/**
* Current results returned by this adapter.
*/
private ArrayList<AutocompletePrediction> mResultList;
/**
* Handles autocomplete requests.
*/
private GoogleApiClient mGoogleApiClient;
/**
* The bounds used for Places Geo Data autocomplete API requests.
*/
private LatLngBounds mBounds;
/**
* The autocomplete filter used to restrict queries to a specific set of place types.
*/
private AutocompleteFilter mPlaceFilter;
/**
* Initializes with a resource for text rows and autocomplete query bounds.
*
* @see android.widget.ArrayAdapter#ArrayAdapter(android.content.Context, int)
*/
public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
/**
* Sets the bounds for all subsequent queries.
*/
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
/**
* Returns the number of results received in the last autocomplete query.
*/
@Override
public int getCount() {
return mResultList.size();
}
/**
* Returns an item from the last autocomplete query.
*/
@Override
public AutocompletePrediction getItem(int position) {
return mResultList.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
// Sets the primary and secondary text for a row.
// Note that getPrimaryText() and getSecondaryText() return a CharSequence that may contain
// styling based on the given CharacterStyle.
AutocompletePrediction item = getItem(position);
TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
textView1.setText(item.getPrimaryText(STYLE_BOLD));
textView2.setText(item.getSecondaryText(STYLE_BOLD));
return row;
}
/**
* Returns the filter for the current set of autocomplete results.
*/
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// We need a separate list to store the results, since
// this is run asynchronously.
ArrayList<AutocompletePrediction> filterData = new ArrayList<>();
// Skip the autocomplete query if no constraints are given.
if (constraint != null) {
// Query the autocomplete API for the (constraint) search string.
filterData = getAutocomplete(constraint);
}
results.values = filterData;
if (filterData != null) {
results.count = filterData.size();
} else {
results.count = 0;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
mResultList = (ArrayList<AutocompletePrediction>) results.values;
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
@Override
public CharSequence convertResultToString(Object resultValue) {
// Override this method to display a readable result in the AutocompleteTextView
// when clicked.
if (resultValue instanceof AutocompletePrediction) {
return ((AutocompletePrediction) resultValue).getFullText(null);
} else {
return super.convertResultToString(resultValue);
}
}
};
}
/**
* Submits an autocomplete query to the Places Geo Data Autocomplete API.
* Results are returned as frozen AutocompletePrediction objects, ready to be cached.
* objects to store the Place ID and description that the API returns.
* Returns an empty list if no results were found.
* Returns null if the API client is not available or the query did not complete
* successfully.
* This method MUST be called off the main UI thread, as it will block until data is returned
* from the API, which may include a network request.
*
* @param constraint Autocomplete query string
* @return Results from the autocomplete API or null if the query was not successful.
* @see Places#GEO_DATA_API#getAutocomplete(CharSequence)
* @see AutocompletePrediction#freeze()
*/
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "Starting autocomplete query for: " + constraint);
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
// This method should have been called off the main UI thread. Block and wait for at most 60s
// for a result from the API.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
// Confirm that the query completed successfully, otherwise return null
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
}

View File

@@ -0,0 +1,68 @@
package com.appttude.h_mal.exchangemap;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
/**
* Created by h_mal on 05/05/2018.
*/
public class getLatLong {
static Location location;
public static Double longitude;
public static Double latitude;
private static String TAG = getLatLong.class.getSimpleName();
public getLatLong(){
super();
}
public static void configLatLong(Context context) {
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
if(ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
!=PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context, "Location permission denied", Toast.LENGTH_SHORT).show();
} else {
try {
location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}catch (Exception e){
Log.e("latlong error", "configLatLong: ", e);
}finally {
if (location == null){
Log.i(TAG, "configLatLong: location initially was null");
try{
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}catch (Exception e){
Log.e(TAG, "configLatLong: ", e);
}finally {
if (location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.i(TAG, "onSuccess: Latitude:" + location.getLatitude()
+ "\n longitude: " + location.getLongitude());
}
}
}else{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="200"/>
</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:shareInterpolator="false">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="200" />
</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:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="200"/>
</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:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="200" />
</set>

View File

@@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
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:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
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:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="@android:color/transparent"
android:orientation="vertical">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_weight="1"
android:layout_height="0dp"
android:layout_width="match_parent"
card_view:cardCornerRadius="22dp"
android:layout_marginTop="45dp">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="45dp"
android:layout_marginTop="20dp"
card_view:cardCornerRadius="22dp">
<EditText
android:id="@+id/search_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:hint="Search Currency" />
</android.support.v7.widget.CardView>
</LinearLayout>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:alpha="0.7"
android:clickable="true"
android:focusable="true"
android:tint="@android:color/background_dark"
app:backgroundTint="#ffffff"
app:srcCompat="@android:drawable/ic_search_category_default" />
</RelativeLayout>

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".FragmentSearch">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:orientation="vertical"
android:padding="12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<AutoCompleteTextView
android:id="@+id/location_home"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:layout_weight="1"
android:ems="10"
android:hint="Search home location"
android:padding="12dp"
android:selectAllOnFocus="true" />
<ImageView
android:id="@+id/my_loc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@android:drawable/ic_menu_mylocation" />
</LinearLayout>
<AutoCompleteTextView
android:id="@+id/location_home_departure"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:ems="10"
android:hint="Search departure airport"
android:padding="12dp"
android:selectAllOnFocus="true" />
<AutoCompleteTextView
android:id="@+id/location_arrival_airport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:ems="10"
android:hint="Search arrival airport"
android:padding="12dp"
android:selectAllOnFocus="true" />
<AutoCompleteTextView
android:id="@+id/location_arrival_"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:ems="10"
android:hint="Search destination"
android:padding="12dp"
android:selectAllOnFocus="true" />
<android.support.v7.widget.CardView
style="@style/cardview_theme"
android:layout_marginBottom="12dp">
<TextView
android:id="@+id/currency_one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:text="Currency to hand"
android:textColor="@android:color/white"
android:textSize="18sp" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
style="@style/cardview_theme"
android:layout_marginBottom="3dp">
<TextView
android:id="@+id/currency_teo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:text="Desired Currency"
android:textColor="@android:color/white"
android:textSize="18sp" />
</android.support.v7.widget.CardView>
</LinearLayout>
</RelativeLayout>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MapsActivity">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="transaction_duration">200</dimen>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#000000</color>
</resources>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
<style name="cardview_theme" parent="CardView">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="cardBackgroundColor">@android:color/holo_blue_bright</item>
<item name="cardCornerRadius">22dp</item>
<!--<item name="cardElevation">0dp</item>-->
</style>
</resources>

View File

@@ -0,0 +1,20 @@
<resources>
<!--
TODO: Before you release your application, you need a Google Maps API key.
To do this, you can either add your release key credentials to your existing
key, or create a new key.
Note that this file specifies the API key for the release build target.
If you have previously set up a key for the debug target with the debug signing certificate,
you will also need to set up a key for your release certificate.
Follow the directions here:
https://developers.google.com/maps/documentation/android/signup
Once you have your key (it starts with "AIza"), replace the "google_maps_key"
string in this file.
-->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">YOUR_KEY_HERE</string>
</resources>

View File

@@ -0,0 +1,17 @@
package com.appttude.h_mal.exchangemap;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

27
build.gradle Normal file
View File

@@ -0,0 +1,27 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

15
gradle.properties Normal file
View File

@@ -0,0 +1,15 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

172
gradlew vendored Normal file
View File

@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

1
settings.gradle Normal file
View File

@@ -0,0 +1 @@
include ':app'