Initial commit
11
.gitignore
vendored
Normal 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1 @@
|
||||
/build
|
||||
32
app/build.gradle
Normal 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
@@ -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
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
24
app/src/debug/res/values/google_maps_api.xml
Normal 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>
|
||||
43
app/src/main/AndroidManifest.xml
Normal 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>
|
||||
BIN
app/src/main/ic_launcher-web.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
197
app/src/main/java/com/appttude/h_mal/exchangemap/MapItem.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
8
app/src/main/res/anim/enter_from_left.xml
Normal 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>
|
||||
8
app/src/main/res/anim/enter_from_right.xml
Normal 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>
|
||||
8
app/src/main/res/anim/exit_to_left.xml
Normal 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>
|
||||
8
app/src/main/res/anim/exit_to_right.xml
Normal 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>
|
||||
34
app/src/main/res/drawable-v24/ic_launcher_foreground.xml
Normal 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>
|
||||
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal 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>
|
||||
42
app/src/main/res/layout/custom_dialog.xml
Normal 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>
|
||||
34
app/src/main/res/layout/fragment_maps.xml
Normal 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>
|
||||
|
||||
|
||||
105
app/src/main/res/layout/fragment_search.xml
Normal 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>
|
||||
18
app/src/main/res/layout/main_layout.xml
Normal 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>
|
||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal 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>
|
||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal 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>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_home.png
Normal file
|
After Width: | Height: | Size: 509 B |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_notif.png
Normal file
|
After Width: | Height: | Size: 671 B |
BIN
app/src/main/res/mipmap-hdpi/ic_world.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_home.png
Normal file
|
After Width: | Height: | Size: 350 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_notif.png
Normal file
|
After Width: | Height: | Size: 881 B |
BIN
app/src/main/res/mipmap-mdpi/ic_world.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_home.png
Normal file
|
After Width: | Height: | Size: 764 B |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_notif.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_world.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_home.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_notif.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_world.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_home.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_notif.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_world.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
6
app/src/main/res/values/colors.xml
Normal 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>
|
||||
4
app/src/main/res/values/dimens.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="transaction_duration">200</dimen>
|
||||
</resources>
|
||||
4
app/src/main/res/values/ic_launcher_background.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#000000</color>
|
||||
</resources>
|
||||
1999
app/src/main/res/values/strings.xml
Normal file
21
app/src/main/res/values/styles.xml
Normal 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>
|
||||
20
app/src/release/res/values/google_maps_api.xml
Normal 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>
|
||||
@@ -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
@@ -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
@@ -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
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal 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
@@ -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
@@ -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
@@ -0,0 +1 @@
|
||||
include ':app'
|
||||