I have this code which I use to position a map app. I tested it in a Galaxy S2 device and works fine, but when I tested it in a nexus 4 device the onLocationChanged callback never gets called. What could I be doing wrong?
Here is my activity code:
public class BaseMapActivity extends FragmentActivity implements Injectable,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private MapEntity component;
private boolean yetStarted = false;
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
private Location location;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_activity);
mLocationClient = new LocationClient(this, this, this);
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // TODO
mLocationRequest.setInterval(5000); // TODO
mLocationRequest.setFastestInterval(5000); // TODO
replaceFragment(R.id.map_container, mapFragment);
// Agrega el fragment de extras
Fragment extrasFragment = component.getExtrasFragment();
replaceFragment(R.id.map_extras, extrasFragment);
}
#Override
protected void onStart() {
super.onStart();
mLocationClient.connect();
}
#Override
protected void onStop() {
if (mLocationClient.isConnected()) {
mLocationClient.removeLocationUpdates(this);
mLocationClient.disconnect();
}
super.onStop();
}
#Override
public void onConnected(Bundle arg0) {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
location = mLocationClient.getLastLocation();
if (location == null) {
return;
}
Toast.makeText(this, "onConnected", Toast.LENGTH_SHORT).show();
}
#Override
public void onDisconnected() {
mLocationClient.removeLocationUpdates(this);
Toast.makeText(this, "onDisconnected. Please re-connect.",
Toast.LENGTH_SHORT).show();
}
#Override
public void onLocationChanged(Location location) {
component.setCenter(location);
String msg = "Updated Location: "
+ Double.toString(location.getLatitude()) + ","
+ Double.toString(location.getLongitude());
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST:
switch (resultCode) {
case Activity.RESULT_OK:
break;
}
}
}
#SuppressLint("ShowToast")
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, "An error ocurred getting current location",
Toast.LENGTH_SHORT);
}
}
}
Whats weird is that its working in one device but not in the other.
Try to set location mock up to see if the locationChange is called or not.
Here you have an example i was using for this before production.
private Location createMockLocation() {
if (mockLocation == null) {
mockLocation = new Location("mock");
mockLocation.setLatitude(41.4934133);
mockLocation.setLongitude(-23.8729252);
mockLocation.setAccuracy(1.0f);
mockLocation.setTime(new Date().getTime());
} else {
mockLocation.setLatitude(mockLocation.getLatitude() + 0.00003);
mockLocation.setLongitude(mockLocation.getLongitude() + 0.00001);
mockLocation.setTime(new Date().getTime());
}
return mockLocation;
}
private void mockLocation() {
LocationServices.FusedLocationApi.setMockMode(clientApi, true);
LocationServices.FusedLocationApi.setMockLocation(clientApi, createMockLocation());
final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
LocationServices.FusedLocationApi.setMockLocation(clientApi, createMockLocation());
// Log.d("MockLocation",
// "mockLocation: Lat:"+mockLocation.getLatitude()+" Long:"+mockLocation.getLongitude());
}
}, 0, NORMAL_INTERVAL, TimeUnit.MILLISECONDS);
}
With this method you get an update position each NORMAL_INTERVAL in ms.
Hope this helps :).
Related
Im creating an app in android studio where I want 10 clips to be played at the same time side by side. Im having some problems with some lags already at three clips and I wounder if Im better off using threads? In that case how?
Any hint would be very much apreciated
Here is my code so far. I know it is not very efficient and I am better off using an array of a player object for example but Im just testing so far:
public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {
private MediaPlayer mp1, mp2, mp3;
private TextureView tv1, tv2, tv3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = findViewById(R.id.textureView1);
tv2 = findViewById(R.id.textureView2);
tv3 = findViewById(R.id.textureView3);
tv1.setSurfaceTextureListener(this);
tv2.setSurfaceTextureListener(this);
tv3.setSurfaceTextureListener(this);
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
Surface surface = new Surface(surfaceTexture);
mp1 = MediaPlayer.create(this, R.raw.a7);
mp1.setSurface(surface);
// mp1.prepareAsync(); //
mp1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp1) {
mp1.start();
}
});
Surface surface2 = new Surface(surfaceTexture);
mp2 = MediaPlayer.create(this, R.raw.a9);
mp2.setSurface(surface2);
// mp1.prepareAsync(); //
mp2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp2) {
mp2.start();
}
});
Surface surface3 = new Surface(surfaceTexture);
mp3 = MediaPlayer.create(this, R.raw.a10);
mp3.setSurface(surface3);
// mp1.prepareAsync(); //
mp3.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp3) {
mp3.start();
}
});
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
#Override
protected void onPause() {
if (mp1 != null && mp1.isPlaying()) {
mp1.pause();
}
super.onPause();
}
#Override
protected void onResume() {
if (mp1 != null) {
mp1.start();
}
super.onResume();
}
#Override
protected void onDestroy() {
if (mp1 != null) {
mp1.stop();
mp1.release();
mp1 = null;
}
super.onDestroy();
}
}
You should play media in a different non-ui thread. like this:-
public class MediaService extends Service {
private MediaPlayer mp1, mp2, mp3;
private static final String ACTION_START = TAG + ".ACTION_START";
private IBinder mBinder = new MyBinder();
private MediaPlayer.OnPreparedListener mMediaPrepared = new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "MediaPlayer.onPrepared");
onCommandPlay(mp);
}
};
#Override
public IBinder onBind(Intent intent) {
Log.v(TAG, "onBind");
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
m1 = MediaPlayer.create(this, R.raw.a1);
m2 = MediaPlayer.create(this, R.raw.a2);
m3 = MediaPlayer.create(this, R.raw.a9);
}
#Override
public void onDestroy() {
super.onDestroy();
if (m1 != null) m1 .release();
if (m2 != null) m2 .release();
if (m3 != null) m3 .release();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String action = intent.getAction();
Log.d(TAG, "onStartCommand: " + intent.getAction());
if (ACTION_START.equals(action)) {
onCommandStart();
return START_STICKY;
}
stopSelf();
return Service.START_STICKY_COMPATIBILITY;
}
/**
* Performs actions related to media player when Service onStartCommand method is called
*
*/
private void onCommandStart() {
// Create Notifications with remote views
mNotification = new NotificationCompat.Builder(this).setTicker("Media Service started...")
.setSmallIcon(R.mipmap.ic_launcher)
.setContent(collapsed)
.setAutoCancel(false)
.setOngoing(true)
.build();
startForeground(NOTIFICATION_ID, mNotification);
startPlaying();
}
private void onCommandPlay(MediaPlayer mp) {
try {
mp.start();
} catch (IllegalStateException e) {
Log.e(TAG, "onCommandPlay", e);
}
}
/**
* Start playing the provided media item
*
*/
private void startPlaying() {
mCurrent = item;
try {
mp1.reset();
mp1.setOnPreparedListener(mMediaPrepared);
mp2.reset();
mp2.setOnPreparedListener(mMediaPrepared);
mp3.reset();
mp3.setOnPreparedListener(mMediaPrepared);
AssetFileDescriptor afd1 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a9););
AssetFileDescriptor afd2 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a10););
AssetFileDescriptor afd3 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a8););
mp1.setDataSource(afd1 .getFileDescriptor(), afd1 .getStartOffset(), afd1.getLength());
mp2.setDataSource(afd2 .getFileDescriptor(), afd2 .getStartOffset(), afd2 .getLength());
mp3.setDataSource(afd3 .getFileDescriptor(), afd3 .getStartOffset(), afd3 .getLength());
mp1.prepareAsync();
mp2.prepareAsync();
mp3.prepareAsync();
} catch (IOException e) {
Log.e(TAG, "startPlaying", e);
}
}
public class MyBinder extends Binder {
public MediaService getService() {
return MediaService.this;
}
}
}
then start the service from Activity like this:
Intent intent = new Intent(context, MediaService.class);
intent.setAction(ACTION_START);
startServie(intent);
You should also handle different media playing use-cases. You can refer this link for more.
I'm trying to use the mapbox SDK to get my current location and set the navigation, but it's not working. I was trying to implement this code following the tutorial from the mapbox website.
public class pos extends AppCompatActivity implements LocationEngineListener, PermissionsListener {
private MapView mapView;
// variables for adding location layer
private MapboxMap map;
private PermissionsManager permissionsManager;
private LocationLayerPlugin locationPlugin;
private LocationEngine locationEngine;
private Location originLocation;
// variables for adding a marker
private Marker destinationMarker;
private LatLng originCoord;
private LatLng destinationCoord;
// variables for calculating and drawing a route
private Point originPosition;
private Point destinationPosition;
private DirectionsRoute currentRoute;
private static final String TAG = "DirectionsActivity";
private NavigationMapRoute navigationMapRoute;
//private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this,"pk.eyJ1IjoiaWhkaW5hIiwiYSI6ImNqaDRveHdhcjB1ZTIyd253M2R2MGhwY28ifQ.If9oJq_rILeuaK1sjp9-nw");
setContentView(R.layout.activity_pos);
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(final MapboxMap mapboxMap) {
map = mapboxMap;
enableLocationPlugin();
originCoord = new LatLng(originLocation.getLatitude(), originLocation.getLongitude());
mapboxMap.addOnMapClickListener(new MapboxMap.OnMapClickListener() {
#Override
public void onMapClick(#NonNull LatLng point) {
if (destinationMarker != null) {
mapboxMap.removeMarker(destinationMarker);
}
destinationCoord = point;
destinationMarker = mapboxMap.addMarker(new MarkerOptions()
.position(destinationCoord)
);
destinationPosition = Point.fromLngLat(destinationCoord.getLongitude(), destinationCoord.getLatitude());
originPosition = Point.fromLngLat(originCoord.getLongitude(), originCoord.getLatitude());
getRoute(originPosition, destinationPosition);
/* button.setEnabled(true);
button.setBackgroundResource(R.color.mapboxBlue);*/
}
;
});
/*button = findViewById(R.id.startButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Point origin = originPosition;
Point destination = destinationPosition;
// Pass in your Amazon Polly pool id for speech synthesis using Amazon Polly
// Set to null to use the default Android speech synthesizer
String awsPoolId = null;
boolean simulateRoute = true;
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.origin(origin)
.destination(destination)
.awsPoolId(awsPoolId)
.shouldSimulateRoute(simulateRoute)
.build();
// Call this method with Context from within an Activity
NavigationLauncher.startNavigation(NavigationActivity.this, options);
}
});*/
}
;
});
}
private void getRoute(Point origin, Point destination) {
NavigationRoute.builder()
.accessToken(Mapbox.getAccessToken())
.origin(origin)
.destination(destination)
.build()
.getRoute(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
// You can get the generic HTTP info about the response
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
} else if (response.body().routes().size() < 1) {
Log.e(TAG, "No routes found");
return;
}
currentRoute = response.body().routes().get(0);
// Draw the route on the map
if (navigationMapRoute != null) {
navigationMapRoute.removeRoute();
} else {
navigationMapRoute = new NavigationMapRoute(null, mapView, map, R.style.NavigationMapRoute);
}
navigationMapRoute.addRoute(currentRoute);
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
Log.e(TAG, "Error: " + throwable.getMessage());
}
});
}
#SuppressWarnings( {"MissingPermission"})
private void enableLocationPlugin() {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {
// Create an instance of LOST location engine
initializeLocationEngine();
locationPlugin = new LocationLayerPlugin(mapView, map, locationEngine);
locationPlugin.setLocationLayerEnabled(true);
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}
#SuppressWarnings( {"MissingPermission"})
private void initializeLocationEngine() {
locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable();
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.activate();
Location lastLocation = locationEngine.getLastLocation();
if (lastLocation != null) {
originLocation = lastLocation;
setCameraPosition(lastLocation);
} else {
locationEngine.addLocationEngineListener(this);
}
}
private void setCameraPosition(Location location) {
map.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(location.getLatitude(), location.getLongitude()), 13));
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
#Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
}
#Override
public void onPermissionResult(boolean granted) {
if (granted) {
enableLocationPlugin();
} else {
finish();
}
}
#Override
#SuppressWarnings( {"MissingPermission"})
public void onConnected() {
locationEngine.requestLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
originLocation = location;
setCameraPosition(location);
locationEngine.removeLocationEngineListener(this);
}
}
#Override
#SuppressWarnings( {"MissingPermission"})
protected void onStart() {
super.onStart();
if (locationEngine != null) {
locationEngine.requestLocationUpdates();
}
if (locationPlugin != null) {
locationPlugin.onStart();
}
mapView.onStart();
}
#Override
protected void onStop() {
super.onStop();
if (locationEngine != null) {
locationEngine.removeLocationUpdates();
}
if (locationPlugin != null) {
locationPlugin.onStop();
}
mapView.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
if (locationEngine != null) {
locationEngine.deactivate();
}
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
#Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}
Try modifying your methods with this:
private void enableLocationPlugin() {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {
initializeLocationEngine();
locationPlugin = new LocationLayerPlugin(mapView, map, locationEngine);
locationPlugin.setLocationLayerEnabled(true);
locationPlugin.setCameraMode(CameraMode.TRACKING);
locationPlugin.setRenderMode(RenderMode.COMPASS);
getLifecycle().addObserver(locationPlugin);
Log.e(TAG, "enableLocationPlugin:Permission Granted" );
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
Log.e(TAG, "enableLocationPlugin:Permission Not Granted" );
}
}
private void initializeLocationEngine() {
locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable();
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.addLocationEngineListener(this);
locationEngine.activate();
Location lastLocation = locationEngine.getLastLocation();
if (lastLocation != null) {
setCameraPosition(lastLocation);
} else {
locationEngine.addLocationEngineListener(this);
}
}
and your onStart with this:
#Override
#SuppressWarnings({"MissingPermission"})
protected void onStart() {
super.onStart();
if (locationEngine != null) {
locationEngine.requestLocationUpdates();
locationEngine.addLocationEngineListener(this);
}
if (locationPlugin != null) {
locationPlugin.onStart();
}
mapView.onStart();
}
I think my app enters loop because once it starts in device, it doesn't respond to any commands including lisener the button. I believe that the problem is the methods for permits in RunTime. I'm sorry for my English.
My code is:
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final int REQUEST_RESOLVE_ERROR = 3;
private GoogleApiClient mGoogleApiClient;
private volatile Location mCurrentLocation;
private static final int REQUEST_PERMISSION_LOCATE = 2;
private static final int LOCATION_DURATE_TIME = 5000;
private boolean mResolvingError = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Toast.makeText(MainActivity.this, "ciao", Toast.LENGTH_LONG).show();
}
});
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
Toast.makeText(MainActivity.this, "connesso", Toast.LENGTH_LONG).show();
}
#Override
protected void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
manageLocationPermission();
}
#Override
public void onConnectionSuspended(int i) {
}
//gestione dell'errore
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult)
{
if (mResolvingError) {
// If we're already managing an error we skip the invocation of this method
return;
} else if (connectionResult.hasResolution()) {
// Here we check if the ConnectionResult has already the solution. If it has
// we start the resolution process
try {
// Starting resolution
mResolvingError = true;
// We launch the Intent using a request id
connectionResult.startResolutionForResult(MainActivity.this, REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
// If we have an error during resolution we can start again.
mGoogleApiClient.connect();
}
} else {
// The ConnectionResult in the worse case has the error code we have to manage
// into a Dialog
// Starting resolution
mResolvingError = true;
}
}
//location update
private void updateLocation()
{
LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setNumUpdates(1)
.setExpirationDuration(LOCATION_DURATE_TIME);
LocationServices.FusedLocationApi
.requestLocationUpdates(mGoogleApiClient, locationRequest, new LocationListener() {
#Override
public void onLocationChanged(Location location)
{
mCurrentLocation = location;
}
});
}
private void startLocationListener()
{
updateLocation();
}
//permessi in RunTime
private void manageLocationPermission()
{
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
{
new AlertDialog.Builder(this)
.setTitle("Permesso di geolocalizzazione")
.setMessage("Devi dare il permesso alla geolocalizzazione")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSION_LOCATE);
}
})
.create()
.show();
}
else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSION_LOCATE);
}
}else
{
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
manageLocationPermission();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == REQUEST_PERMISSION_LOCATE)
{
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
//se mi hanno accettato i permessi
startLocationListener();
}
else{
new AlertDialog.Builder(this)
.setTitle("Permesso di geolocalizzazione")
.setMessage("Devi dare il permesso alla geolocalizzazione")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.create()
.show();
}
}
}
}
If manageLocationPermission() is called with the permissions already granted, your code enters the following else clause
} else {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
manageLocationPermission();
}
Here you're calling the same function again, and since the permissions are granted, you will enter the same else clause, and again the same thing... You see where this is going? Just remove manageLocationPermission() from this else clause
I am a learner in android. I am trying to get weather on current location. There is a "Refresh" button in my app to update the UI with latest weather details. When the app loads, it shows weather of 0.0, 0.0 latitude and longitude. When I click on "Refresh" button, it shows the weather of my current location. How can I get the weather of my current location when the app loads? I have used Google Play Services to get the current location. Below is my code.
MainActivity.java
public class MainActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
public String apiKey;
public double latitude;
public double longitude;
public String forecastUrl;
public static final String TAG = MainActivity.class.getSimpleName();
private GoogleApiClient mGoogleApiClient;
protected Location mLastLocation;
public MainActivity() {
apiKey = “XXXXXXXXXX";
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buildGoogleApiClient();
mRefreshImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getForecast();
}
});
getForecast();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onResume() {
super.onResume();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
private void getForecast() {
if (isNetworkAvailable()) {
forecastUrl = “http://www.forecastUrlGoesHere.com/" + apiKey + “/“ + latitude + "," + longitude;
toggleRefresh();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(forecastUrl).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
toggleRefresh();
}
});
}
#Override
public void onResponse(Response response) throws IOException {
runOnUiThread(new Runnable() {
#Override
public void run() {
toggleRefresh();
}
});
try {
String jsonData = response.body().string();
if (response.isSuccessful()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
updateView(); //updates the screen ui
}
});
} else {
alertUserAboutError();
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
}
}
});
} else {
Toast.makeText(this, getString(R.string.network_error_message), Toast.LENGTH_LONG).show();
}
}
private void updateView() {
//code to update ui
}
private boolean isNetworkAvailable() {
//check network availability
}
private void alertUserAboutError() {
AlertDialogFragment dialog = new AlertDialogFragment();
dialog.show(getFragmentManager(), "error_dialog");
}
private void toggleRefresh() {
}
#Override
public void onConnected(Bundle bundle) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
latitude = mLastLocation.getLatitude();
longitude = mLastLocation.getLongitude();
Toast.makeText(this, latitude + " " + longitude, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, getString(R.string.no_location_detected), Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(this, 9000);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "Connection failed, ERROR: " + connectionResult.getErrorCode());
}
}
}
Well there are a few ways to get the expected result. Let me write the steps for one of them:
a) Use a ProgressDialog and start it in onCreate
b) Move the getForecast() from onCreate
c) In the onConnected method, once the lat and long are available, check if the ProgressDialog is still visible. If yes, dismiss this dialog and call getForecast
ProgressDialog link
http://developer.android.com/reference/android/app/ProgressDialog.html
In your onConnected callback, call getForecast();:
#Override
public void onConnected(Bundle bundle) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
latitude = mLastLocation.getLatitude();
longitude = mLastLocation.getLongitude();
Toast.makeText(this, latitude + " " + longitude, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, getString(R.string.no_location_detected), Toast.LENGTH_LONG).show();
}
getForecast();
}
i using call function to javascript to android . i using my android code below how to stop android mthread.i used for MyBackgroudMethod mThread but i want to stop this thread in sendCheckOutBackgroundKill();how to possible.please help me!!!
public class EmployeeManager extends CordovaActivity implements
LocationListener{
JavaScriptInterface jsInterface;
LocationManager locationManager;
boolean isGPSEnabled = false;
boolean network_enabled = false;
String provider;
String lati = "";
String latlong = "";
String accuracy = "";
Location currentLocation;
LocationManager mLocationManager;
String devieID = "";
boolean backgroundtask = false;
String iSGps = "";
String mTime="";
String mEmployeeId="";
String mAttendanceId="";
MyBackgroudMethod mThread;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_employee_manager_main);
super.loadUrl("file:///android_asset/www/index.html");
//mThread = new MyBackgroudMethod();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
/**/
jsInterface = new JavaScriptInterface(EmployeeManager.this);
appView.addJavascriptInterface(jsInterface, "JSInterface");
appView.getSettings().setJavaScriptEnabled(true);
appView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
devieID = getUniquePsuedoID();
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
network_enabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
// Creating an empty criteria object
Criteria criteria = new Criteria();
// Getting the name of the provider that meets the criteria
provider = locationManager.getBestProvider(criteria, false);
if (provider != null && !provider.equals("")) {
// Get the location from the given provider
Location location = locationManager.getLastKnownLocation(provider);
if (isGPSEnabled) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
} else if (network_enabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
}
// locationManager.requestLocationUpdates(provider, 1000, 0, this);
if (location != null) {
onLocationChanged(location);
} else {
Toast.makeText(getBaseContext(), "Location can't be retrieved",
Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getBaseContext(), "No Provider Found",Toast.LENGTH_SHORT).show();
}
}
public static String getUniquePsuedoID()
{
String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);
String serial = null;
try
{
serial = android.os.Build.class.getField("SERIAL").get(null).toString();
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
catch (Exception e)
{
serial = "serial"; // some value
}
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
public class JavaScriptInterface {
public Activity mContext;
public JavaScriptInterface(Activity c) {
this.mContext = c;
}
#JavascriptInterface
public void sendToAndroid(boolean deviceID) {
Log.v("log", "Sent TO android");
runOnUiThread(new Runnable() {
public void run() {
appView.loadUrl("javascript:passLatLong(\"" + lati + "\",\"" + latlong + "\",\"" + accuracy + "\");");
appView.setEnabled(false);
}
});
}
#JavascriptInterface
public void sendToDeviceId() {
runOnUiThread(new Runnable() {
public void run() {
appView.loadUrl("javascript:passDevieId(\"" + devieID + "\");");
}
});
}
#JavascriptInterface
public void sendCheckInBackground(String time, String employeeId, String attendanceId) {
mTime= time;
mEmployeeId = employeeId;
mAttendanceId = attendanceId;
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(EmployeeManager.this, "Check In Background Native", 3000).show();
mThread = new MyBackgroudMethod();
mThread.setDaemon(true);
mThread.start();
}
});
}
public void sendCheckOutBackgroundKill() {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(EmployeeManager.this, "Check Out Background Native Kill", 3000).show();
mThread.interrupt();
}
});
}
}
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("GPS is settings");
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
private class MyBackgroudMethod extends Thread {
#Override
public void run() {
while (true) {
checkInternetConnection();
try {
Thread.sleep(Integer.parseInt(mTime)*60*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void checkInternetConnection() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
// test for connection
if (cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isAvailable()
&& cm.getActiveNetworkInfo().isConnected()) {
new JSONTask().execute(mTime,mEmployeeId,mAttendanceId);
} else {
Log.v(TAG, "Internet Connection Not Present");
}
}
#Override
public void onLocationChanged(Location location) {
if(location.getAccuracy() < 400) {
lati = Double.toString(location.getLatitude());
latlong = Double.toString(location.getLongitude());
accuracy = Double.toString(location.getAccuracy());
}
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
public class JSONTask extends AsyncTask<String, Void, String> {
public void onPreExecute() {
// progress.show();
}
protected String doInBackground(String... arg) {
// This value will be returned to your
// onPostExecute(result) method
String time1 = arg[0];
String employeeId2 = arg[1];
String attendenceId2 = arg[2];
String img_url = DBAdpter.onFieldCheckIn(employeeId2, attendenceId2, lati, latlong, accuracy);
return img_url;
}
protected void onPostExecute(String result) {
Toast.makeText(EmployeeManager.this, "JSON TASK", 4000).show();
}
}
}
The loop isn't exiting after the interruption. Put a "break;" inside the catch-clause. That's all.