stopping a handler thread button - java

Every 5 sec I want to current latitude longitude to the web application in Android app. if the user login to the app in that we using user logs by placing a button's. If the user hits log out button I need to stop the handler thread current run on same activity page by a different button (Log in )
I have done everything but while stopping the threads my application get crashed
if the user hit login button it automatically sends the data for every 5 sec
private void techlocation() {
handler = new Handler ();
locationManager = (LocationManager) User_deatils .this.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE); // Choose your accuracy requirement.
locationManager.getBestProvider(criteria, true);
if (ActivityCompat.checkSelfPermission(User_deatils.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(User_deatils.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 8000, 10, (LocationListener) User_deatils .this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 8000, 10, (LocationListener) User_deatils .this);
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
lat = location.getLatitude();
lon = location.getLongitude();
}
handler.postDelayed(runLocation, 5000);
}
This is the runnable threads sends data to server-side
public Runnable runLocation = new Runnable() {
#Override
public void run() {
latitude = String.valueOf(lat);
longitude = String.valueOf(lon);
arrLat.add(latitude);
arrLng.add(longitude);
User_deatils.this.handler.postDelayed(User_deatils.this.runLocation, 50000);
handler.removeCallbacksAndMessages(this);
Log.e("msg", "new" + handler);
}
}
log in button
b3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
.// SaveButtonState("b3");
techlocation(); // calling handler threads
}
});
log out button
b4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.removeCallbacksAndMessages(runLocation);
}
});

To start runnable and do work every 5 seconds do this.
Declare runnable this way with a boolean.
// flag that should be set true if handler should stop
boolean mStopHandler = false;
private Handler mHandler;
//initialize runnable in oncreate()
mHandler=new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
// do your stuff here
if (!mStopHandler) {
mHandler.postDelayed(this, 5000);
}
}
};
Call this to start this runnable on button click()
// start runnable
mHandler.post(runnable);
And finally use this to stop runnable
handler.removeCallbacks(runnable);

Related

LocationListner no longer listen for gps status change after upgrade to Android 7

After updated my app to support Android 7 the GPS listner no longer is invoked when the GPS on/off is triggerd. If I refresh my activity it works as expected on Android 6, but not in Android 7. Does anyone have any idea. I have added both my listner, and code releated to gps change in my activity.
I have if its difficult a theory to override the backpressed or activity resumed to recreate view, but havn't suceeded with that either .
GPSListner.java
public abstract class GPSListener implements LocationListener {
private Context context;
public GPSListener(Context context) {
this.context = context;
}
#Override
public void onProviderEnabled(String provider) {
onGPSOn();
}
#Override
public void onProviderDisabled(String provider) {
onGPSOff();
}
public abstract void onGPSOff();
public abstract void onGPSOn();
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
My class
gpsListener = new GPSListener(this) {
#Override
public void onGPSOff() {
gpsImg.setImageResource(R.drawable.notok);
}
#Override
public void onGPSOn() {
gpsImg.setImageResource(R.drawable.ok);
}
};
final LocationManager manager;
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
final ImageView gpsImg = (ImageView) findViewById(R.id.gpsstatus);
if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
gpsImg.setImageResource(R.drawable.ok);
} else {
gpsImg.setImageResource(R.drawable.notok); //not ok
}
This last method opens the gps settings.
public View.OnClickListener onButtongpsClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent gpsOptionsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(gpsOptionsIntent);
}
};
Obtaining location is a bit tricky itself. Only GPS can have line-of-sight issues and would vary depending on device too, not just Android version. Over the years Android location services have matured and using up-to-date standard practices does result in higher consistency with respect to results.
By the way, LocationClient is deprecated. FusedLocationProviderApi does not use it anymore.
It works through a GoogleApiClient and this part makes the GooglePlayServices mandatory. You have options if this does not suit your app.
Making your app location aware suggests:
The Google Play services location APIs are preferred over the Android
framework location APIs (android.location) as a way of adding location
awareness to your app. If you are currently using the Android
framework location APIs, you are strongly encouraged to switch to the
Google Play services location APIs as soon as possible.
You can break it into parts to understand it better, like;
Building the GoogleApiClient
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this) //this = activity
.addApi(LocationServices.API)
.addConnectionCallbacks(this) //interfaces implemented
.addOnConnectionFailedListener(this)
.build();
}
Requesting location,
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
Try the last known location, if that requirement works for you,
#Override
public void onConnected(Bundle bundle) {
Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
...}
onConnected() is the callback from GoogleApiClient...
So there is more to location than initialising a client and implementing the listener. I recommend you go through a few questions or android docs to ensure you implement what suits your requirement.
Also,
instead of
Intent gpsOptionsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); ,
use SettingsApi
can refer to Enabling location mode...
Some useful Q&As:
Comprehensive answer for obtaining location
Good to go through LocationRequest part here if you want to avoid reading in detail
final LocationManager manager;
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Do i even have to comment on this one? Read it again and you will understand what is wrong with it.
Hint. Try:
final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
You can used fused location api to get the location
Fused Location Api :
Fused Location Provider automatically decides best location from the available options for that it uses GPS and Network Provider, So if the device GPS is off we can still get the location from Network provider vice versa.
Why Fused Location Api ?
Consumption of power while fetching location.
It will give accurate
location based on user priority.
Piggyback which means you can get
location every time when other application hits for location for you
advantage is user not blame you for that you just getting those
location which other application request.
We don’t have to pick the
provider(GPS or network provider)
please refer code for following for getting location.
LocationService : We required these for getting continues location and these register as pending intent so whenever device got new location these service invoke.
public class LocationService extends IntentService {
private String TAG = this.getClass().getSimpleName();
public LocationService() {
super("Fused Location");
}
public LocationService(String name) {
super("Fused Location");
}
#Override
protected void onHandleIntent(Intent intent) {
Location location = intent.getParcelableExtra(LocationClient.KEY_LOCATION_CHANGED);
if(location !=null){
Log.i(TAG, "onHandleIntent " + location.getLatitude() + "," + location.getLongitude());
// write your code here.
}
}
}
MainActivity : which register callbacks for it which tell us whether we are connected or disconnected with api.
public class MainActivity extends Activity implements GooglePlayServicesClient.ConnectionCallbacks,GooglePlayServicesClient.OnConnectionFailedListener,LocationListener {
private String TAG = this.getClass().getSimpleName();
private LocationClient locationclient;
private LocationRequest locationrequest;
private Intent mIntentService;
private PendingIntent mPendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIntentService = new Intent(this,LocationService.class);
mPendingIntent = PendingIntent.getService(this, 1, mIntentService, 0);
int resp =GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resp == ConnectionResult.SUCCESS){
locationclient = new LocationClient(this,this,this);
locationclient.connect();
}
else{
Toast.makeText(this, "Google Play Service Error " + resp, Toast.LENGTH_LONG).show();
}
}
public void buttonClicked(View v){
if(v.getId() == R.id.btnLastLoc){
if(locationclient!=null && locationclient.isConnected()){
Location loc =locationclient.getLastLocation();
Log.i(TAG, "Last Known Location :" + loc.getLatitude() + "," + loc.getLongitude());
txtLastKnownLoc.setText(loc.getLatitude() + "," + loc.getLongitude());
}
}
if(v.getId() == R.id.btnStartRequest){
if(locationclient!=null && locationclient.isConnected()){
if(((Button)v).getText().equals("Start")){
locationrequest = LocationRequest.create();
locationrequest.setInterval(Long.parseLong(etLocationInterval.getText().toString()));
locationclient.requestLocationUpdates(locationrequest, this);
((Button) v).setText("Stop");
}
else{
locationclient.removeLocationUpdates(this);
((Button) v).setText("Start");
}
}
}
if(v.getId() == R.id.btnRequestLocationIntent){
if(((Button)v).getText().equals("Start")){
locationrequest = LocationRequest.create();
locationrequest.setInterval(100);
locationclient.requestLocationUpdates(locationrequest, mPendingIntent);
((Button) v).setText("Stop");
}
else{
locationclient.removeLocationUpdates(mPendingIntent);
((Button) v).setText("Start");
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(locationclient!=null)
locationclient.disconnect();
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "onConnected");
txtConnectionStatus.setText("Connection Status : Connected");
}
#Override
public void onDisconnected() {
Log.i(TAG, "onDisconnected");
txtConnectionStatus.setText("Connection Status : Disconnected");
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "onConnectionFailed");
txtConnectionStatus.setText("Connection Status : Fail");
}
#Override
public void onLocationChanged(Location location) {
if(location!=null){
Log.i(TAG, "Location Request :" + location.getLatitude() + "," + location.getLongitude());
}
}
}
For more reference refer below link
https://github.com/riteshreddyr/fused-location-provider
https://github.com/kpbird/fused-location-provider-example
Hope these help you.

Getting the user's location in Android when the phone is locked

I am looking for a solution to get the user's location in a specific time-interval in Android API 17 (Android 4.2) and when the phone is locked.
I've already tried some different code, checked a lot tutorials and searched almost everywhere on the web. The solution might be there, but I think it's a combination of lack of experience with Android developing and interpreting the different right solutions and approaches.
At first I had some pretty basic code, which worked very well when the screen was turned on. Even in the background, the location got updated (as I could check via a Toast message with the longitude and latitude).
I used a Handler to do so:
public void locationRunnable() {
final Handler locationHandler = new Handler();
final int distanceDelay = 5000; // milliseconds
locationHandler.postDelayed(new Runnable(){
public void run() {
// code
mMap.clear();
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
mMap.setMyLocationEnabled(true);
mMap.setBuildingsEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
myLocation = locationManager.getLastKnownLocation(provider);
if (myLocation != null) {
latitudeCurrentPosition = myLocation.getLatitude();
longitudeCurrentPosition = myLocation.getLongitude();
}
currentPattern = shortTest;
Notification.Builder notificationBuilderChecking = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentTitle("Test app")
.setAutoCancel(true)
.setOnlyAlertOnce(false)
.setContentText("Getting location!")
.setPriority(Notification.PRIORITY_MAX)
.setLights(0xffffffff, 200, 200)
.setVibrate(currentPattern);
Notification notification2 = notificationBuilderChecking.build();
NotificationManager notificationMngr2 = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationMngr2.notify(NOTIFICATION_ID, notification2);
locationHandler.postDelayed(this, distanceDelay);
}
}, distanceDelay);
}
It's just a snippet and the purpose is that in the background, when the screen is locked, this will loop every 10 seconds. And it does. Even when the phone is locked, but only for about 3 times. After 3 times the timer goes up and the phone vibrates less frequent (Doze feature in the way?).
Also, the phone does vibrate, but the location isn't updated. When I unlock the phone with the app in the foreground, the location is still at the place when I locked the phone. After a while (10 seconds) it updates. I use a marker on the map to check.
Again: it works when the phone is unlocked.
Now I'm trying to use a Service, a Service (Intent Service), or a Broadcast Receiver, and start a new Thread, but I don't know how and nothing is working.
Some of the last code I have contains a not functioning Broadcast Receiver and the most recent code contains a AlarmManager:
public void getLocation(Context context) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmIntent.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
//After after 30 seconds
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, System.currentTimeMillis(), 10000, pi);
context.getSystemService(Context.CONNECTIVITY_SERVICE);
mMap.clear();
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
myLocation = locationManager.getLastKnownLocation(provider);
latitudeCurrentPosition = myLocation.getLatitude();
longitudeCurrentPosition = myLocation.getLongitude();
LatLng latLngCurrent = new LatLng(latitudeCurrentPosition, longitudeCurrentPosition);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLngCurrent));
mMap.animateCamera(CameraUpdateFactory.zoomTo(distZoom));
currentPattern = shortTest;
showNotification(context);
mHereIAm = mMap.addMarker(new MarkerOptions()
.position(new LatLng(latitudeCurrentPosition, longitudeCurrentPosition))
.title(weAreHere)
.draggable(false)
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.marker_iconv3)));
mHereIAm.setTag(0);
mHereIAm.showInfoWindow();
}
AndroidManifest permissions:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
But at the long of 10000, Android Studio is telling me "Value will be forced up to 60000 as of Android 5.1; don't rely on this to be exact..." etc. So an AlarmManager isn't useful either.
With the last code, my app isn't even running anymore.
But still: vibrations and stuff still occur, but location updates don't.
In short:
I need some basic (at least, I think it just can't be so difficult, as the only problem is that it's not working when the screen is locked) code, that updates my location on a certain, variable interval.
Maybe I have to use a Handler/Runnable, start a new Thread, use a Service or a Broadcast Receiver. Maybe an AlarmManager may work as well, but I don't know how and which to use.
This is my first post. If anything misses or you guys need more information, please ask. I'm trying to be as precise as possible, without using to much overhead.
Edit 01
Can I use a Job Service to do so? - I've updated the API to 21, so I can make use of this service, but I don't know if that's the right solution I'm looking for? Got some great tutorials for the use of it.
Edit 02
Let me be more clear with less overhead: I am looking for a solution to get the user's current location when the device is locked: with an API, a Service, an IntentService, a BroadcastReceiver, ... - every tutorial tells me something different, even here at Stack Overflow I have troubles with finding the right solution.
I was able to use a Service as well as an Intent Service, but I cannot request any location updates, because of some errors, like:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.name.name/com.name.name.MapsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.setMyLocationEnabled(b‌​oolean)' on a null object reference - searching for a solution for this error, gives me another error later on, and on, and on... I got myself stuck in an error-loop and a lot of unnecessary code.
I hope there is a simple way to get the user's location and you guys could help me. Thanks again.
Edit 03
I've followed the instructions on this tutorial and the location is checking. See the following code:
public class LocationService extends Service implements LocationListener {
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public LocationService(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
//isNetworkEnabled = locationManager
// .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(LocationService.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
* On pressing Settings button will lauch Settings Options
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
I've disabled Network location and only allowed GPS location for testing - tested both.
And my MapsActivity:
public void getLocation(){
gps = new LocationService(MapsActivity.this);
if(gps.canGetLocation()) { // gps enabled} // return boolean true/false
latitudeCurrentPosition = gps.getLatitude(); // returns latitude
longitudeCurrentPosition = gps.getLongitude(); // returns longitude
latLngCurrent = new LatLng(latitudeCurrentPosition, longitudeCurrentPosition);
Toast toastLatCur = makeText(getApplicationContext(), "Lat Current: " + latitudeCurrentPosition + "" ,Toast.LENGTH_SHORT);
toastLatCur.show();
Toast toastLongCur = makeText(getApplicationContext(), "Long Current: " + longitudeCurrentPosition + "" ,Toast.LENGTH_SHORT);
toastLongCur.show();
}
else {
gps.showSettingsAlert();
}
if(goToLocation){
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLngCurrent));
goToLocation = false;
if(firstStart){
mMap.animateCamera(CameraUpdateFactory.zoomTo(distZoom));
firstStart = false;
}
}
vibrateNotification();
}
When the screen is locked, the phone vibrates as I told in vibrateNotificatoin() - works perfectly every 10 seconds. But the location doesn't get updated! So a Service is not the right way to solve this. Help!
You should use the service to perform tasks which are needed to be done even when the application is not running. Give a try.

Alarm ringing stops when cleared from ram

I am making an alarm clock which asks user to do a particular work in order to close the alarm when it rings. It is working fine but the problem is that if the user closes the alarm app from the recent activities while the alarm is ringing, the alarm stops ringing. I want that even if the user clears the app while its ringing, it should not stop ringing. It should only stop once the task given is completed. How can I implement this?
Edit #1: Activity that is called when alarm rings
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(LOG_TAG, "in AlarmAlert");
unlockScreen();
setContentView(R.layout.activity_alarm_alert);
Bundle bundle = this.getIntent().getExtras();
alarm = (Alarm) bundle.getSerializable("alarm");
alarmDatabase = new AlarmDatabase(this);
//Uri uri = alarm.getRingtonePath();
question = (TextView)findViewById(R.id.question);
answer = (TextView) findViewById(R.id.answer);
oldColors = answer.getTextColors();
diff = alarm.getDifficulty().toString();
questionString = GenerateMathsQuestion.generateQuestion(diff);
question.setText(questionString);
actualAnswer = EvaluateString.evaluate(questionString);
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int result = am.requestAudioFocus(focusChangeListener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.setLooping(true);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
try {
mediaPlayer.setDataSource(this, Uri.parse(alarm.getRingtonePath()));
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
if(alarm.getIsVibrate()) {
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
long[] pattern = {1000, 200, 200, 200};
vibrator.vibrate(pattern, 0);
}
}
public void closeAlarm(){
Log.v(LOG_TAG, "will now stop");
mediaPlayer.stop();
if(vibrator!=null)
vibrator.cancel();
Log.v(LOG_TAG, "will now release");
mediaPlayer.release();
Log.v(LOG_TAG, "id of ringing alarm: " + alarm.getAlarmId());
alarm.setIsActive(false);
alarmDatabase.updateData(alarm);
cursor = alarmDatabase.sortQuery();
while(cursor.moveToNext()){
int id = cursor.getInt(cursor.getColumnIndex(AlarmDatabase.COLUMN_UID));
currentAlarm = alarmDatabase.getAlarm(id);
Log.v(LOG_TAG, "id of next alarm " + id);
if(currentAlarm != null) {
if (currentAlarm.getIsActive() == true) {
currentAlarm.scheduleAlarm(this, true);
break;
}
}
}
this.finish();
}
You should use Services. Take a look at it, that is what you want it. Generally you can make it to run an operation, and a service wont return any result. But it runs indefinitely even when you kill the app from task manager or free RAM.
I suggest this tutorial for reading about services.
UPDATE
Implement your activity with the service in the following way so it can talk with the layout and stops the alarm when required.
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
#Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}

Android: Redirect to another Activity after delay

So I am developing a simple app for a college project, And I have been able to integrate a Facebook login using fragments.
But I now am stuck trying to redirect the user after they login. I simply want to redirect them to the second activity page
Here is my code for the Facebook login success
private FacebookCallback<LoginResult> mCallback=new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
AccessToken accessToken = loginResult.getAccessToken();
Profile profile = Profile.getCurrentProfile();
if (profile != null) {
display.setText("Welcome: " + profile.getFirstName());
//Redirect to Second Activity
}
}
To make a delayed transition use Handler class's postDelayed(Runnable r, long delayMillis) method, for example:
Java
Runnable r = new Runnable() {
#Override
public void run() {
// if you are redirecting from a fragment
// then use getActivity() as the context.
startActivity(new Intent(CurrentActivity.this, TargetActivity.class));
}
};
Handler h = new Handler();
// The Runnable will be executed after the given delay time
h.postDelayed(r, 1500); // will be delayed for 1.5 seconds
Kotlin with Anko
val someThread = Runnable {
startActivity(intentFor<TargetActivity>())
}
Handler().postDelayed(someThread, 1500)
Simply call a new activity through intent:
Intent i = new Intent(LoginActivity.this, HomeActivity.class);
startActivity(i);
finish();
Check this:-
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i=new Intent(CurrentActivity.this,Next.class);
startActivity(i);
}
}, 3000);
A Handler allows you to send and process Message and Runnable objects
associated with a thread's MessageQueue. Each Handler instance is
associated with a single thread and that thread's message queue. When
you create a new Handler, it is bound to the thread / message queue of
the thread that is creating it -- from that point on, it will deliver
messages and runnables to that message queue and execute them as they
come out of the message queue.
You can use Handler postDelayed Method easily .
Handler hd = new Handler();
hd.postDelayed(new Runnable() {
#Override
public void run() {
// Add Your Intent
}
}, 2000); // Time Delay ,2 Seconds
}
In Kotlin;
val r = Runnable {
startActivity(Intent(this, AuthorActivity::class.java))
}
val h = Handler()
h.postDelayed(r, 10)

how to get the google map blue point latitude and longitude in android

My objective is to track the user's location and give an alert on reaching marked location. So first I get the location to reach and marked that. Then I get the current location and compare it with marked location. But it is not working. Even I placed the marker at current location. It is not giving the toast message. Here is the code -
public class MainActivity extends FragmentActivity implements LocationListener{
LocationManager locationManager;
String provider;
ToggleButton toggle;
public static double lat,lang,value1,value2,value3,value4;
public static String strlat,strlat1;
public LatLng loc,loc1;
public double latitude,longitude;
public static String strlang,strlang1 ;
Location location;
public LocationManager locationmanager;
// Google Map
private GoogleMap googleMap;
LocationListener Locationlistener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
// 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
final Location location = locationManager.getLastKnownLocation(provider);
locationManager.requestLocationUpdates(provider, 1000, 1, this);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
if(location!=null){
lat = location.getLatitude();
lang = location.getLongitude();
value3 =Double.parseDouble(new DecimalFormat("##.##").format(lat));
value4 =Double.parseDouble(new DecimalFormat("##.##").format(lang));
strlat = String.valueOf(value3);
strlang = String.valueOf(value4);
loc1 =new LatLng(lat, lang);
if((value1 == value3) && (value2 == value4))
{
Toast.makeText(getApplicationContext(), "target reached", Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(getBaseContext(), "Location can't be retrieved", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getBaseContext(), "No Provider Found", Toast.LENGTH_SHORT).show();
}
handler.postDelayed(this, 1000);
}
};
handler.post(runnable);
}
try {
// Loading map
initilizeMap();
// Changing map type
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
// googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
// googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
// googleMap.setMapType(GoogleMap.MAP_TYPE_NONE);
// Showing / hiding your current location
googleMap.setMyLocationEnabled(true);
// Enable / Disable zooming controls
googleMap.getUiSettings().setZoomControlsEnabled(false);
// Enable / Disable my location button
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
// Enable / Disable Compass icon
googleMap.getUiSettings().setCompassEnabled(true);
// Enable / Disable Rotate gesture
googleMap.getUiSettings().setRotateGesturesEnabled(true);
// Enable / Disable zooming functionality
googleMap.getUiSettings().setZoomGesturesEnabled(true);
// create marker
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
} catch (Exception e) {
e.printStackTrace();
}
googleMap.setOnMapClickListener(new OnMapClickListener(){
public void onMapClick(LatLng point){
Toast.makeText(getBaseContext(),
point.latitude + ", " + point.longitude,
Toast.LENGTH_LONG).show();
latitude = point.latitude;
longitude = point.longitude;
value1 =Double.parseDouble(new DecimalFormat("##.##").format(latitude));
value2 =Double.parseDouble(new DecimalFormat("##.##").format(longitude));
strlat1 = String.valueOf(value1);
strlang1 = String.valueOf(value2);
loc=new LatLng(point.latitude, point.longitude);
MarkerOptions marker = new MarkerOptions().position(loc).title("Hello Maps ");
// adding marker
googleMap.addMarker(marker);
}
});
}
#Override
protected void onResume() {
super.onResume();
initilizeMap();
}
/**
* function to load map If map is not created it will create it for you
* */
private void initilizeMap() {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
}
/*
* creating random position around a location for testing purpose only
*/
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
}
There are a few things wrong in your code.
You can't compare coordinates with == because you will never have an exact match for lat/lon coordinates when tracking the device's location. You need to figure out a threshold, and if the device gets within that threshold, then show the alert.
Next, you're not using your onLocationChanged() callback, so you are just looking at the current location one time at app start-up.
Take a look at the code in my other answer here which is about determining if the device is within a circle. This is a similar problem.
So, if you were to make your threshold 10 meters, and consider the target reached if the device is within 10 meters of the target location, you would implement your onLocationChanged() method something like this:
#Override
public void onLocationChanged(Location location) {
float[] distance = new float[2];
Location.distanceBetween( location.getLatitude(), location.getLongitude(),
latitude, longitude, distance);
if( distance[0] < 10 ){
//target location reached
Toast.makeText(getApplicationContext(), "target reached", Toast.LENGTH_SHORT).show();
}
}
one more daniel.i changed above code now it was working now have some more problem.
1.i tried to set splash screen like in my second.class.i set the above code for google map.it was running for five second while moving from one to another it get stopped
new Timer().schedule(new TimerTask(){
public void run() {
Intent intent = new Intent (MainActivity.this, SecondActivity.class);
PendingIntent pendIntent = PendingIntent.getActivity(getBaseContext(), 1000, intent, 0);
}
}, 5000);
2.i want set search in google map how to set that i tried that it not working give some idea.

Categories