├── .gitignore ├── .idea ├── encodings.xml ├── gradle.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tecorb │ │ └── hrmarkeranimation │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── tecorb │ │ │ └── hrmarkeranimation │ │ │ ├── ActivitySplash.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-hdpi │ │ ├── car.png │ │ ├── splah.jpg │ │ └── splash2.png │ │ ├── drawable-mdpi │ │ └── car.png │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable-xhdpi │ │ └── car.png │ │ ├── drawable-xxhdpi │ │ └── car.png │ │ ├── drawable-xxxhdpi │ │ └── car.png │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ └── activity_splash.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── raw │ │ └── mapstyle.json │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── tecorb │ └── hrmarkeranimation │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hrmovecarmarkeranimation ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tecorb │ │ └── hrmovecarmarkeranimation │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── tecorb │ │ │ └── hrmovecarmarkeranimation │ │ │ ├── AnimationClass │ │ │ └── HRMarkerAnimation.java │ │ │ ├── CallBacks │ │ │ └── UpdateLocationCallBack.java │ │ │ └── Utils │ │ │ └── Utilities.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── tecorb │ └── hrmovecarmarkeranimation │ └── ExampleUnitTest.java ├── markerAnimation.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | /.idea/app/google-services.json 15 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 TecOrb Technologies 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HRCarMarkerAnimation 2 | 3 | [![](https://jitpack.io/v/TecOrb-Developers/HRMarkerAnimation.svg)](https://jitpack.io/#TecOrb-Developers/HRMarkerAnimation) 4 | 5 | 6 | Smooth marker animation on google map along with proper turns and camera bearing. 7 | 8 | # Demo 9 | 10 | 11 | 12 | # Steps: 13 | 14 | Pass the Marker to animate, googlemap, Location of current position and Old Location of the marker of the user, 15 | duration of the animation & UpdateLocationCallBack Callback interface. 16 | 17 | ``` 18 | 19 | java 20 | private Location mLastLocation; 21 | private Location oldLocation; 22 | 23 | new HRMarkerAnimation(googleMap,1000, new UpdateLocationCallBack() { 24 | @Override 25 | public void onUpdatedLocation(Location updatedLocation) { 26 | oldLocation = updatedLocation; 27 | } 28 | }).animateMarker(mLastLocation, oldLocation, marker); 29 | 30 | ``` 31 | 32 | Here marker, googlemap,mLastLocation refers to the position of marker,oldLocation position refers to the position of 33 | the maker for calculating the slop of marker. 34 | These four fields are mandatory. 35 | 36 | Duration refers to the animation time. By default it will take 1000. 37 | callback is the interface of Googlemap UpdatedLoation Callback return Old location. It requires when the user wants to animate the next animation after the first has finished. 38 | 39 | 40 | The isMarkerVisible method return true or false if marker is visible on user device screen then it return false 41 | whenever the marker is not visible means outside the screen then it automatically animate to center of the screen 42 | 43 | For eg- 44 | 45 | 46 | ``` 47 | 48 | java 49 | private boolean isMarkerVisible(GoogleMap googleMap, LatLng newLocation) { 50 | 51 | return googleMap.getProjection().getVisibleRegion().latLngBounds.contains(newLocation); 52 | } 53 | 54 | ``` 55 | 56 | # Note: 57 | 58 | If you are animating car onLocationChanged() then, 59 | Ideal location request for car animation should be as below. Greater than the interval mentioned will give 60 | more good results but less than this may hamper the animation. 61 | 62 | ``` 63 | 64 | java 65 | mLocationRequest = new LocationRequest(); 66 | mLocationRequest.setInterval(1000 * 5); 67 | mLocationRequest.setFastestInterval(1000 * 3); 68 | mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 69 | 70 | ``` 71 | 72 | 73 | ## Dependency 74 | 75 | ``` 76 | 77 | groovy 78 | App Level: 79 | dependencies { 80 | implementation 'com.github.TecOrb-Developers:HRMarkerAnimation:xyz' 81 | } 82 | groovy 83 | Project Level: 84 | maven { url 'https://jitpack.io' } 85 | 86 | ``` 87 | Replace xyz with latest version 88 | 89 | To get a small example, please download this repo add your Google API Key in values and execute it 90 | 91 | 92 | # Developers 93 | 94 | MIT License 95 | 96 | Copyright (c) 2019 TecOrb Technologies 97 | 98 | Permission is hereby granted, free of charge, to any person obtaining a copy 99 | of this software and associated documentation files (the "Software"), to deal 100 | in the Software without restriction, including without limitation the rights 101 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 102 | copies of the Software, and to permit persons to whom the Software is 103 | furnished to do so, subject to the following conditions: 104 | 105 | The above copyright notice and this permission notice shall be included in all 106 | copies or substantial portions of the Software. 107 | 108 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 109 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 110 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 111 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 112 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 113 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 114 | SOFTWARE. 115 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "com.tecorb.hrmarkeranimation" 7 | minSdkVersion 21 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | maven { url 'https://jitpack.io' } 23 | } 24 | } 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: 'libs', include: ['*.jar']) 29 | implementation 'com.android.support:appcompat-v7:28.0.0' 30 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 31 | testImplementation 'junit:junit:4.12' 32 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 34 | implementation 'com.google.android.gms:play-services-maps:16.1.0' 35 | implementation 'com.google.android.gms:play-services-location:16.0.0' 36 | implementation 'gun0912.ted:tedpermission:2.2.2' 37 | implementation 'com.github.TecOrb-Developers:HRMarkerAnimation:fe6f64e75b' 38 | 39 | 40 | } 41 | apply plugin: 'com.google.gms.google-services' -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/tecorb/hrmarkeranimation/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.tecorb.hrmarkeranimation; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.rahman.hrmarkeranimation", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/tecorb/hrmarkeranimation/ActivitySplash.java: -------------------------------------------------------------------------------- 1 | package com.tecorb.hrmarkeranimation; 2 | 3 | import android.Manifest; 4 | import android.content.Intent; 5 | import android.os.Handler; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.widget.Toast; 9 | 10 | import com.gun0912.tedpermission.PermissionListener; 11 | import com.gun0912.tedpermission.TedPermission; 12 | 13 | import java.util.List; 14 | 15 | public class ActivitySplash extends AppCompatActivity { 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_splash); 21 | 22 | TedPermission.with(this) 23 | .setPermissionListener(permissionlistener) 24 | .setDeniedMessage("If you reject permission,you can not use this service\n\nPlease turn on permissions at [Setting] > [Permission]") 25 | .setPermissions(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION) 26 | .check(); 27 | 28 | 29 | } 30 | 31 | PermissionListener permissionlistener = new PermissionListener() { 32 | @Override 33 | public void onPermissionGranted() { 34 | new Handler().postDelayed(new Runnable() { 35 | @Override 36 | public void run() { 37 | startActivity(new Intent(ActivitySplash.this,MainActivity.class)); 38 | } 39 | },1000); 40 | } 41 | 42 | @Override 43 | public void onPermissionDenied(List deniedPermissions) { 44 | Toast.makeText(ActivitySplash.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show(); 45 | } 46 | 47 | 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/tecorb/hrmarkeranimation/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.tecorb.hrmarkeranimation; 2 | 3 | import android.Manifest; 4 | import android.content.Context; 5 | import android.content.pm.PackageManager; 6 | import android.content.res.Resources; 7 | import android.graphics.Bitmap; 8 | import android.graphics.drawable.BitmapDrawable; 9 | import android.location.Location; 10 | import android.support.v4.app.ActivityCompat; 11 | import android.support.v7.app.AppCompatActivity; 12 | import android.os.Bundle; 13 | import android.util.Log; 14 | 15 | import com.google.android.gms.common.ConnectionResult; 16 | import com.google.android.gms.common.GooglePlayServicesUtil; 17 | import com.google.android.gms.common.api.GoogleApiClient; 18 | import com.google.android.gms.common.api.PendingResult; 19 | import com.google.android.gms.location.LocationListener; 20 | import com.google.android.gms.location.LocationRequest; 21 | import com.google.android.gms.location.LocationServices; 22 | import com.google.android.gms.maps.CameraUpdateFactory; 23 | import com.google.android.gms.maps.GoogleMap; 24 | import com.google.android.gms.maps.OnMapReadyCallback; 25 | import com.google.android.gms.maps.SupportMapFragment; 26 | import com.google.android.gms.maps.model.BitmapDescriptorFactory; 27 | import com.google.android.gms.maps.model.LatLng; 28 | import com.google.android.gms.maps.model.MapStyleOptions; 29 | import com.google.android.gms.maps.model.Marker; 30 | import com.google.android.gms.maps.model.MarkerOptions; 31 | import com.tecorb.hrmovecarmarkeranimation.AnimationClass.HRMarkerAnimation; 32 | import com.tecorb.hrmovecarmarkeranimation.CallBacks.UpdateLocationCallBack; 33 | 34 | public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, 35 | LocationListener, GoogleApiClient.ConnectionCallbacks, 36 | GoogleApiClient.OnConnectionFailedListener{ 37 | 38 | private static final String TAG = "LocationActivity"; 39 | private static final long INTERVAL = 2000; //1.5 min 40 | private static final long FASTEST_INTERVAL = 1000; //1.5 min 41 | private static final long DISPLACEMENT = 5; //5 meter 42 | private LocationRequest mLocationRequest; 43 | private GoogleApiClient mGoogleApiClient; 44 | private Location mLastLocation; 45 | private Location oldLocation; 46 | private Context context; 47 | private int markerCount=0; 48 | private SupportMapFragment mapFragment; 49 | private static final int REQUEST_LOCATION = 0; 50 | private boolean isFirstTime = true; 51 | private GoogleMap mMap; 52 | private Marker marker; 53 | 54 | @Override 55 | protected void onCreate(Bundle savedInstanceState) { 56 | super.onCreate(savedInstanceState); 57 | setContentView(R.layout.activity_main); 58 | 59 | context=this; 60 | mGoogleApiClient = new GoogleApiClient.Builder(this) 61 | .addApi(LocationServices.API) 62 | .addConnectionCallbacks(this) 63 | .addOnConnectionFailedListener(this).build(); 64 | createLocationRequest(); 65 | markerCount = 0; 66 | 67 | 68 | mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); 69 | mapFragment.getMapAsync(MainActivity.this); 70 | } 71 | 72 | @Override 73 | protected void onStart() { 74 | super.onStart(); 75 | if (!mGoogleApiClient.isConnected()) { 76 | mGoogleApiClient.connect(); 77 | } 78 | } 79 | 80 | @Override 81 | protected void onStop() { 82 | super.onStop(); 83 | } 84 | 85 | @Override 86 | protected void onPause() { 87 | super.onPause(); 88 | markerCount = 0; 89 | stopLocationUpdates(); 90 | } 91 | 92 | @Override 93 | protected void onResume() { 94 | super.onResume(); 95 | if (mGoogleApiClient.isConnected()) { 96 | startLocationUpdates(); 97 | } 98 | } 99 | 100 | @Override 101 | protected void onDestroy() { 102 | super.onDestroy(); 103 | } 104 | 105 | protected void createLocationRequest() { 106 | mLocationRequest = LocationRequest.create(); 107 | mLocationRequest.setInterval(INTERVAL); 108 | mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 109 | mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 110 | //mLocationRequest.setSmallestDisplacement(DISPLACEMENT); 111 | } 112 | 113 | private boolean isGooglePlayServicesAvailable() { 114 | int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 115 | if (ConnectionResult.SUCCESS == status) { 116 | return true; 117 | } else { 118 | GooglePlayServicesUtil.getErrorDialog(status, this, 0).show(); 119 | return false; 120 | } 121 | } 122 | 123 | @Override 124 | public void onConnected(Bundle bundle) { 125 | Log.d(TAG, "onConnected - isConnected ...............: " + 126 | mGoogleApiClient.isConnected()); 127 | startLocationUpdates(); 128 | displayLocation(); 129 | } 130 | 131 | protected void startLocationUpdates() { 132 | try { 133 | 134 | LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 135 | Log.d(TAG, "Location update started ..............: "); 136 | } catch (SecurityException e) { 137 | e.printStackTrace(); 138 | } 139 | } 140 | 141 | @Override 142 | public void onConnectionSuspended(int i) { 143 | } 144 | 145 | @Override 146 | public void onConnectionFailed(ConnectionResult connectionResult) { 147 | 148 | Log.d(TAG, "Connection failed: " + connectionResult.toString()); 149 | } 150 | 151 | @Override 152 | public void onLocationChanged(Location currentL) { 153 | mLastLocation = currentL; 154 | displayLocation(); 155 | } 156 | 157 | protected void stopLocationUpdates() { 158 | try { 159 | LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 160 | Log.d(TAG, "Location update stopped ......................."); 161 | } catch (Exception e) { 162 | e.printStackTrace(); 163 | } 164 | } 165 | 166 | public void onMapReady(final GoogleMap googleMap) { 167 | mMap = googleMap; 168 | 169 | try { 170 | boolean success = googleMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(context, R.raw.mapstyle)); 171 | 172 | if (!success) { 173 | Log.e(TAG, "Style parsing failed."); 174 | } 175 | } catch (Resources.NotFoundException e) { 176 | Log.e(TAG, "Can't find style. Error: ", e); 177 | } 178 | } 179 | 180 | public void addMarker(GoogleMap googleMap, double lat, double lon) { 181 | 182 | try { 183 | 184 | if (markerCount == 1) { 185 | if (oldLocation != null) { 186 | new HRMarkerAnimation(googleMap,1000, new UpdateLocationCallBack() { 187 | @Override 188 | public void onUpdatedLocation(Location updatedLocation) { 189 | oldLocation = updatedLocation; 190 | } 191 | }).animateMarker(mLastLocation, oldLocation, marker); 192 | } else { 193 | oldLocation = mLastLocation; 194 | } 195 | } else if (markerCount == 0) { 196 | if (marker != null) { 197 | marker.remove(); 198 | } 199 | mMap = googleMap; 200 | 201 | LatLng latLng = new LatLng(lat, lon); 202 | 203 | marker = mMap.addMarker(new MarkerOptions().position(new LatLng(lat, lon)) 204 | .icon(BitmapDescriptorFactory.fromResource(R.drawable.car))); 205 | mMap.setPadding(2000, 4000, 2000, 4000); 206 | mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 12f)); 207 | 208 | /*################### Set Marker Count to 1 after first marker is created ###################*/ 209 | 210 | markerCount = 1; 211 | 212 | if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 213 | ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 214 | // TODO: Consider calling 215 | return; 216 | } 217 | } 218 | } catch (Exception e) { 219 | e.printStackTrace(); 220 | } 221 | } 222 | 223 | public void displayLocation() { 224 | try { 225 | 226 | if (ActivityCompat.checkSelfPermission(context, 227 | Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 228 | ActivityCompat.checkSelfPermission(context, 229 | Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 230 | // TODO: Consider calling 231 | // Check Permissions Now 232 | ActivityCompat.requestPermissions(MainActivity.this, 233 | new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 234 | REQUEST_LOCATION); 235 | } else { 236 | 237 | 238 | mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 239 | 240 | if (mLastLocation != null && mLastLocation.getLongitude() != 0.0 && mLastLocation.getLongitude() != 0.0) { 241 | 242 | if (mMap != null) { 243 | addMarker(mMap, mLastLocation.getLatitude(), mLastLocation.getLongitude()); 244 | 245 | } 246 | 247 | } 248 | } 249 | 250 | } catch (Exception e) { 251 | e.printStackTrace(); 252 | } 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/drawable-hdpi/car.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/splah.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/drawable-hdpi/splah.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/splash2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/drawable-hdpi/splash2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/drawable-mdpi/car.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/drawable-xhdpi/car.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/drawable-xxhdpi/car.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/drawable-xxxhdpi/car.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/raw/mapstyle.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "featureType": "all", 4 | "elementType": "labels.text.fill", 5 | "stylers": [ 6 | { 7 | "color": "#7c93a3" 8 | }, 9 | { 10 | "lightness": "-10" 11 | } 12 | ] 13 | }, 14 | { 15 | "featureType": "administrative.country", 16 | "elementType": "geometry", 17 | "stylers": [ 18 | { 19 | "visibility": "on" 20 | } 21 | ] 22 | }, 23 | { 24 | "featureType": "administrative.country", 25 | "elementType": "geometry.stroke", 26 | "stylers": [ 27 | { 28 | "color": "#a0a4a5" 29 | } 30 | ] 31 | }, 32 | { 33 | "featureType": "administrative.province", 34 | "elementType": "geometry.stroke", 35 | "stylers": [ 36 | { 37 | "color": "#62838e" 38 | } 39 | ] 40 | }, 41 | { 42 | "featureType": "landscape", 43 | "elementType": "geometry.fill", 44 | "stylers": [ 45 | { 46 | "color": "#dde3e3" 47 | } 48 | ] 49 | }, 50 | { 51 | "featureType": "landscape.man_made", 52 | "elementType": "geometry.stroke", 53 | "stylers": [ 54 | { 55 | "color": "#3f4a51" 56 | }, 57 | { 58 | "weight": "0.30" 59 | } 60 | ] 61 | }, 62 | { 63 | "featureType": "poi", 64 | "elementType": "all", 65 | "stylers": [ 66 | { 67 | "visibility": "simplified" 68 | } 69 | ] 70 | }, 71 | { 72 | "featureType": "poi.attraction", 73 | "elementType": "all", 74 | "stylers": [ 75 | { 76 | "visibility": "on" 77 | } 78 | ] 79 | }, 80 | { 81 | "featureType": "poi.business", 82 | "elementType": "all", 83 | "stylers": [ 84 | { 85 | "visibility": "off" 86 | } 87 | ] 88 | }, 89 | { 90 | "featureType": "poi.government", 91 | "elementType": "all", 92 | "stylers": [ 93 | { 94 | "visibility": "off" 95 | } 96 | ] 97 | }, 98 | { 99 | "featureType": "poi.park", 100 | "elementType": "all", 101 | "stylers": [ 102 | { 103 | "visibility": "on" 104 | } 105 | ] 106 | }, 107 | { 108 | "featureType": "poi.place_of_worship", 109 | "elementType": "all", 110 | "stylers": [ 111 | { 112 | "visibility": "off" 113 | } 114 | ] 115 | }, 116 | { 117 | "featureType": "poi.school", 118 | "elementType": "all", 119 | "stylers": [ 120 | { 121 | "visibility": "off" 122 | } 123 | ] 124 | }, 125 | { 126 | "featureType": "poi.sports_complex", 127 | "elementType": "all", 128 | "stylers": [ 129 | { 130 | "visibility": "off" 131 | } 132 | ] 133 | }, 134 | { 135 | "featureType": "road", 136 | "elementType": "all", 137 | "stylers": [ 138 | { 139 | "saturation": "-100" 140 | }, 141 | { 142 | "visibility": "on" 143 | } 144 | ] 145 | }, 146 | { 147 | "featureType": "road", 148 | "elementType": "geometry.stroke", 149 | "stylers": [ 150 | { 151 | "visibility": "on" 152 | } 153 | ] 154 | }, 155 | { 156 | "featureType": "road.highway", 157 | "elementType": "geometry.fill", 158 | "stylers": [ 159 | { 160 | "color": "#bbcacf" 161 | } 162 | ] 163 | }, 164 | { 165 | "featureType": "road.highway", 166 | "elementType": "geometry.stroke", 167 | "stylers": [ 168 | { 169 | "lightness": "0" 170 | }, 171 | { 172 | "color": "#bbcacf" 173 | }, 174 | { 175 | "weight": "0.50" 176 | } 177 | ] 178 | }, 179 | { 180 | "featureType": "road.highway", 181 | "elementType": "labels", 182 | "stylers": [ 183 | { 184 | "visibility": "on" 185 | } 186 | ] 187 | }, 188 | { 189 | "featureType": "road.highway", 190 | "elementType": "labels.text", 191 | "stylers": [ 192 | { 193 | "visibility": "on" 194 | } 195 | ] 196 | }, 197 | { 198 | "featureType": "road.highway.controlled_access", 199 | "elementType": "geometry.fill", 200 | "stylers": [ 201 | { 202 | "color": "#ffffff" 203 | } 204 | ] 205 | }, 206 | { 207 | "featureType": "road.highway.controlled_access", 208 | "elementType": "geometry.stroke", 209 | "stylers": [ 210 | { 211 | "color": "#a9b4b8" 212 | } 213 | ] 214 | }, 215 | { 216 | "featureType": "road.arterial", 217 | "elementType": "labels.icon", 218 | "stylers": [ 219 | { 220 | "invert_lightness": true 221 | }, 222 | { 223 | "saturation": "-7" 224 | }, 225 | { 226 | "lightness": "3" 227 | }, 228 | { 229 | "gamma": "1.80" 230 | }, 231 | { 232 | "weight": "0.01" 233 | } 234 | ] 235 | }, 236 | { 237 | "featureType": "transit", 238 | "elementType": "all", 239 | "stylers": [ 240 | { 241 | "visibility": "off" 242 | } 243 | ] 244 | }, 245 | { 246 | "featureType": "water", 247 | "elementType": "geometry.fill", 248 | "stylers": [ 249 | { 250 | "color": "#a3c7df" 251 | } 252 | ] 253 | } 254 | ] 255 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | HRMarkerAnimation 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/tecorb/hrmarkeranimation/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.tecorb.hrmarkeranimation; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | jcenter() 7 | 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.4.2' 11 | classpath 'com.google.gms:google-services:4.2.0' 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | 16 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Jul 28 16:53:40 IST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 28 5 | 6 | 7 | defaultConfig { 8 | minSdkVersion 21 9 | targetSdkVersion 28 10 | versionCode 1 11 | versionName "1.0" 12 | 13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 14 | 15 | } 16 | 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | 24 | } 25 | 26 | dependencies { 27 | implementation fileTree(dir: 'libs', include: ['*.jar']) 28 | 29 | implementation 'com.android.support:appcompat-v7:28.0.0' 30 | testImplementation 'junit:junit:4.12' 31 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 32 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 33 | implementation 'com.google.android.gms:play-services-maps:16.1.0' 34 | implementation 'com.google.android.gms:play-services-location:16.0.0' 35 | } 36 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/src/androidTest/java/com/tecorb/hrmovecarmarkeranimation/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.tecorb.hrmovecarmarkeranimation; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.rahman.hrmovecarmarkeranimation.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/src/main/java/com/tecorb/hrmovecarmarkeranimation/AnimationClass/HRMarkerAnimation.java: -------------------------------------------------------------------------------- 1 | package com.tecorb.hrmovecarmarkeranimation.AnimationClass; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.location.Location; 5 | import android.view.animation.LinearInterpolator; 6 | 7 | import com.google.android.gms.maps.CameraUpdateFactory; 8 | import com.google.android.gms.maps.GoogleMap; 9 | import com.google.android.gms.maps.model.CameraPosition; 10 | import com.google.android.gms.maps.model.LatLng; 11 | import com.google.android.gms.maps.model.Marker; 12 | import com.tecorb.hrmovecarmarkeranimation.CallBacks.UpdateLocationCallBack; 13 | import com.tecorb.hrmovecarmarkeranimation.Utils.Utilities; 14 | 15 | 16 | public class HRMarkerAnimation { 17 | 18 | private UpdateLocationCallBack updateLocation; 19 | private ValueAnimator valueAnimator; 20 | private GoogleMap googleMap; 21 | private long animationDuration; 22 | 23 | public HRMarkerAnimation(GoogleMap googleMap,long duration , UpdateLocationCallBack updateLocation) { 24 | this.updateLocation = updateLocation; 25 | this.googleMap =googleMap; 26 | this.animationDuration=duration; 27 | } 28 | 29 | public void animateMarker(final Location destination, final Location oldLocation, final Marker marker) { 30 | if (marker != null) { 31 | final LatLng startPosition = marker.getPosition(); 32 | final LatLng endPosition = new LatLng(destination.getLatitude(), destination.getLongitude()); 33 | 34 | if (valueAnimator != null) 35 | valueAnimator.end(); 36 | 37 | final Utilities.LatLngInterpolator latLngInterpolator = new Utilities.LatLngInterpolator.LinearFixed(); 38 | valueAnimator = ValueAnimator.ofFloat(0, 1); 39 | valueAnimator.setDuration(animationDuration); // duration 1 second 40 | valueAnimator.setInterpolator(new LinearInterpolator()); 41 | valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 42 | @Override 43 | public void onAnimationUpdate(ValueAnimator animation) { 44 | try { 45 | float v = animation.getAnimatedFraction(); 46 | LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, endPosition); 47 | marker.setPosition(newPosition); 48 | //marker.setRotation(computeRotation(v, startRotation, destination.getBearing())); 49 | marker.setRotation(Utilities.computeRotation(v, marker.getRotation(), 50 | (float)Utilities.bearingBetweenLocations(startPosition, newPosition))); 51 | marker.setAnchor(0.5f, 0.5f); 52 | marker.setFlat(true); 53 | 54 | 55 | // add new location into old location 56 | updateLocation.onUpdatedLocation(destination); 57 | 58 | 59 | //when marker goes out from screen it automatically move into center 60 | if (googleMap!=null){ 61 | if (!Utilities.isMarkerVisible(googleMap,newPosition)){ 62 | googleMap.animateCamera(CameraUpdateFactory 63 | .newCameraPosition(new CameraPosition.Builder() 64 | .target(newPosition) 65 | .zoom(googleMap.getCameraPosition().zoom) 66 | .build())); 67 | }else { 68 | try { 69 | googleMap.animateCamera(CameraUpdateFactory 70 | .newCameraPosition(new CameraPosition.Builder() 71 | .target(newPosition) 72 | .tilt(0) 73 | .zoom(googleMap.getCameraPosition().zoom) 74 | .build())); 75 | }catch (Exception e){ 76 | e.printStackTrace(); 77 | } 78 | 79 | } 80 | 81 | } 82 | } catch (Exception ex) { 83 | ex.printStackTrace(); 84 | // handle exception here 85 | } 86 | } 87 | 88 | }); 89 | valueAnimator.start(); 90 | } 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/src/main/java/com/tecorb/hrmovecarmarkeranimation/CallBacks/UpdateLocationCallBack.java: -------------------------------------------------------------------------------- 1 | package com.tecorb.hrmovecarmarkeranimation.CallBacks; 2 | 3 | import android.location.Location; 4 | 5 | public interface UpdateLocationCallBack { 6 | 7 | void onUpdatedLocation(Location updatedLocation); 8 | } 9 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/src/main/java/com/tecorb/hrmovecarmarkeranimation/Utils/Utilities.java: -------------------------------------------------------------------------------- 1 | package com.tecorb.hrmovecarmarkeranimation.Utils; 2 | 3 | import com.google.android.gms.maps.GoogleMap; 4 | import com.google.android.gms.maps.model.LatLng; 5 | 6 | public class Utilities { 7 | 8 | public static boolean isMarkerVisible(GoogleMap googleMap, LatLng newLocation) { 9 | return googleMap.getProjection().getVisibleRegion().latLngBounds.contains(newLocation); 10 | } 11 | 12 | public static double bearingBetweenLocations(LatLng latLng1, LatLng latLng2) { 13 | 14 | double PI = 3.14159; 15 | double lat1 = latLng1.latitude * PI / 180; 16 | double long1 = latLng1.longitude * PI / 180; 17 | double lat2 = latLng2.latitude * PI / 180; 18 | double long2 = latLng2.longitude * PI / 180; 19 | 20 | double dLon = (long2 - long1); 21 | 22 | double y = Math.sin(dLon) * Math.cos(lat2); 23 | double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) 24 | * Math.cos(lat2) * Math.cos(dLon); 25 | 26 | double brng = Math.atan2(y, x); 27 | 28 | brng = Math.toDegrees(brng); 29 | brng = (brng + 360) % 360; 30 | 31 | return brng; 32 | } 33 | 34 | public interface LatLngInterpolator { 35 | LatLng interpolate(float fraction, LatLng a, LatLng b); 36 | 37 | class LinearFixed implements LatLngInterpolator { 38 | @Override 39 | public LatLng interpolate(float fraction, LatLng a, LatLng b) { 40 | double lat = (b.latitude - a.latitude) * fraction + a.latitude; 41 | double lngDelta = b.longitude - a.longitude; 42 | // Take the shortest path across the 180th meridian. 43 | if (Math.abs(lngDelta) > 180) { 44 | lngDelta -= Math.signum(lngDelta) * 360; 45 | } 46 | double lng = lngDelta * fraction + a.longitude; 47 | return new LatLng(lat, lng); 48 | } 49 | } 50 | } 51 | 52 | public static float computeRotation(float fraction, float start, float end) { 53 | float normalizeEnd = end - start; // rotate start to 0 54 | float normalizedEndAbs = (normalizeEnd + 360) % 360; 55 | 56 | float direction = (normalizedEndAbs > 180) ? -1 : 1; // -1 = anticlockwise, 1 = clockwise 57 | float rotation; 58 | if (direction > 0) { 59 | rotation = normalizedEndAbs; 60 | } else { 61 | rotation = normalizedEndAbs - 360; 62 | } 63 | float result = fraction * rotation + start; 64 | return (result + 360) % 360; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | HRMoveCarMarkerAnimation 3 | 4 | -------------------------------------------------------------------------------- /hrmovecarmarkeranimation/src/test/java/com/tecorb/hrmovecarmarkeranimation/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.tecorb.hrmovecarmarkeranimation; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /markerAnimation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TecOrb-Developers/HRCarMarkerAnimation/4f156f3f5cdee2877df8167a94aa52b78110419c/markerAnimation.gif -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------