I'm new to android developing, and i'm tring to create an app which gets your coordinates like this tutorial http://developer.android.com/training/location/receive-location-updates.html
but my app crashes. I didn't to the last part "Save the State of the Activity" because i dont know what my LOCATION_KEY or REQUESTING_LOCATION_UPDATES_KEY is.
my code:
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.common.SupportErrorDialogFragment;
import java.text.DateFormat;
import java.util.Date;
public class StepCounter extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
// Request code to use when launching the resolution activity
private static final int REQUEST_RESOLVE_ERROR = 1001;
// Unique tag for the error dialog fragment
private static final String DIALOG_ERROR = "dialog_error";
// Bool to track whether the app is already resolving an error
private boolean mResolvingError = false;
//keys
protected final static String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
protected final static String LOCATION_KEY = "location-key";
protected final static String LAST_UPDATED_TIME_STRING_KEY = "last-updated-time-string-key";
GoogleApiClient mGoogleApiClient;
TextView mLatitudeText;
TextView mLongitudeText;
TextView mcLatitudeText;
TextView mcLongitudeText;
Location mLastLocation;
Location mCurrentLocation;
LocationRequest mLocationRequest;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_step_counter);
mLatitudeText = (TextView) findViewById(R.id.lat);
mLongitudeText = (TextView) findViewById(R.id.lon);
mcLatitudeText = (TextView) findViewById(R.id.llat);
mcLongitudeText = (TextView) findViewById(R.id.llon);
mResolvingError = savedInstanceState != null
&& savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);
createLocationRequest();
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onStart() {
super.onStart();
if(!mResolvingError)
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(StepCounter.this);
dialogBuilder.setMessage("onStop");
dialogBuilder.setPositiveButton("Ok", null);
dialogBuilder.show();
mGoogleApiClient.disconnect();
super.onStop();
}
public void onConnected(Bundle connectionHint) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
mCurrentLocation = mLastLocation;
if (mLastLocation != null) {
mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
}
//modified
startLocationUpdates();
}
//pana aici merge de aici vine partea cu update
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
protected void createLocationRequest() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onLocationChanged(Location location) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(StepCounter.this);
dialogBuilder.setMessage("onLocationChanged");
dialogBuilder.setPositiveButton("Ok", null);
dialogBuilder.show();
mLastLocation = mCurrentLocation;
mCurrentLocation = location;
updateUI();
}
public void updateUI()
{
mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
mcLatitudeText.setText(String.valueOf(mCurrentLocation.getLatitude()));
mcLongitudeText.setText(String.valueOf(mCurrentLocation.getLongitude()));
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
#Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
}
}
// De aici partea cu rezolvatu problemei
#Override
public void onConnectionSuspended(int i) {
//todo nust...
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (mResolvingError) {
// Already attempting to resolve an error.
return;
} else if (result.hasResolution()) {
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
// Show dialog using GoogleApiAvailability.getErrorDialog()
showErrorDialog(result.getErrorCode());
mResolvingError = true;
}
}
// The rest of this code is all about building the error dialog
/* Creates a dialog for an error message */
private void showErrorDialog(int errorCode) {
// Create a fragment for the error dialog
ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
// Pass the error that should be displayed
Bundle args = new Bundle();
args.putInt(DIALOG_ERROR, errorCode);
dialogFragment.setArguments(args);
dialogFragment.show(getFragmentManager(), "errordialog");
}
/* Called from ErrorDialogFragment when the dialog is dismissed. */
public void onDialogDismissed() {
mResolvingError = false;
}
/* A fragment to display an error dialog */
public static class ErrorDialogFragment extends DialogFragment {
public ErrorDialogFragment() { }
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the error code and retrieve the appropriate dialog
int errorCode = this.getArguments().getInt(DIALOG_ERROR);
return GoogleApiAvailability.getInstance().getErrorDialog(
this.getActivity(), errorCode, REQUEST_RESOLVE_ERROR);
}
#Override
public void onDismiss(DialogInterface dialog) {
((StepCounter) getActivity()).onDialogDismissed();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_RESOLVE_ERROR) {
mResolvingError = false;
if (resultCode == RESULT_OK) {
// Make sure the app is not already connected or attempting to connect
if (!mGoogleApiClient.isConnecting() &&
!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
}
}
private static final String STATE_RESOLVING_ERROR = "resolving_error";
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}
}
And this is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
//android:theme="#android:style/Theme.Holo"
<activity
android:name=".LoginScreen"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Register"
android:label="#string/title_activity_register" >
</activity>
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
</activity>
<activity
android:name=".StepCounter"
android:label="#string/title_activity_step_counter" >
</activity>
</application>
When i run my app with the emulator (which doesn't have google services) and i click the update google services i get this error (i don't think this is the problem because i have google services on my phone) :
08-26 09:54:24.640 7191-7191/com.persasrl.paul.quickfit E/SettingsRedirect﹕ Can't redirect to app settings for Google Play services
08-26 09:54:24.653 7191-7191/com.persasrl.paul.quickfit D/AndroidRuntime﹕ Shutting down VM
08-26 09:54:24.654 7191-7191/com.persasrl.paul.quickfit E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.persasrl.paul.quickfit, PID: 7191
java.lang.RuntimeException: Unable to pause activity {com.persasrl.paul.quickfit/com.persasrl.paul.quickfit.StepCounter}: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3613)
at android.app.ActivityThread.access$1300(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.common.api.zzf.zzb(Unknown Source)
at com.google.android.gms.common.api.zzg.zzb(Unknown Source)
at com.google.android.gms.location.internal.zzd.removeLocationUpdates(Unknown Source)
at com.persasrl.paul.quickfit.StepCounter.stopLocationUpdates(StepCounter.java:148)
at com.persasrl.paul.quickfit.StepCounter.onPause(StepCounter.java:144)
at android.app.Activity.performPause(Activity.java:6101)
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1310)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3603)
I tried to delete the startLocationUpdates part and it doesn't crash anymore... but also it doesn't update location...
SOLVED IT
so the problem was that i declared mLocationRequest twice at the start of the project:
LocationRequest mLocationRequest;
and in
createLocationRequest()
LocationRequest mLocationRequest = new LocationRequest();
i changed in crateLocationRequest LocationRequest mLocationRequest = new LocationRequest(); to mLocationRequest = new LocationRequest(); and now it doesn't crash.
Related
I'm getting
java.lang.ClassCastException: com.example.BellasHBG.LocationService cannot be cast to com.google.android.gms.location.LocationListener
but I don't know how to resolve. Removing keyword abstract does not fix the problem. This is new to me, and I'm not that knowledgeable of java so any help is appreciated. The error seems top be occurring in LocationService on the following line: LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mlocationRequest, (com.google.android.gms.location.LocationListener) this);
The intent is to get location updates and send a notification to the app user if the location sells this particular bakery product.
Below are my MainActivity, LocationService and AndroidManifest.xml
MainActivity
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.view.KeyEvent;
import android.webkit.WebViewClient;
import android.widget.TextView;
import com.google.android.gms.location.LocationRequest;
//import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private WebView webView = null;
public static boolean orignotifsetting = false;
//PendingIntent pendingIntent;
private Alarm alarm;
MyToolBox mtools = new MyToolBox();
LocationIntentService mLocationIntentService = new LocationIntentService();
public LocationManager mlocManager;
//LocationListener mlocListener = new MyLocationListener();
//LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//public static GoogleApiClient mGoogleApiClient;
private Location mCurrentLocation;
LocationRequest mLocationRequest;
PendingIntent resultPendingIntent;
public Intent resultIntent = new Intent();
LocationServiceImpl mLocationService = new LocationServiceImpl();
public static boolean prevNotificationsSetting;
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i("myTag", "in onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set the default values first time run but don't overwrite them if they have been set
// ----------------------------------------------------------------| - true will leave them alone, false will clear them every time
PreferenceManager.setDefaultValues(this, R.xml.pref_notification, true);
this.webView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
//myWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
//myWebView.setWebViewClient(new WebViewClient());
WebViewClientImpl webViewClient = new WebViewClientImpl(this);
webView.setWebViewClient(webViewClient);
webView.loadUrl("https://www.bellashbg.com");
mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && this.webView.canGoBack()) {
this.webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onResume() {
Log.i("myTag", "in onResume");
super.onResume();
Intent msgIntent = new Intent(MainActivity.this, LocationService.class);
if ((mtools.notificationsSetting(this)) & (prevNotificationsSetting == false)) {
prevNotificationsSetting = true;
startService(msgIntent);
}
else {
if ((!mtools.notificationsSetting(this)) & (prevNotificationsSetting == true)) {
// mLocationService.stopLocationUpdates();
prevNotificationsSetting = false;
boolean result = stopService(msgIntent);
if (result){
Log.d("MainActivity", "stopService true");
}
else {
Log.d("MainActivity", "stopService false");
}
//mLocationService.stopLocationUpdates();
//android.os.Process.killProcess(android.os.Process.myPid());
}
}
}
#Override
public void onPause() {
Log.i("myTag", "in onPause");
super.onPause();
}
#Override
public void onStop() {
Log.i("myTag", "in onStop");
super.onStop();
}
public void onDestroy() {
Log.i("myTag", "in onDestroy");
super.onDestroy();
//if (mSensorManager!=null){mSensorManager.unregisterListener(listener);}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.i("myTag", "in onCreateOptionsMenu");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.settings_menu, menu);
return super.onCreateOptionsMenu(menu); // cmnted 10/25/2015
//super.onCreateOptionsMenu(menu);
//return true;
// return true; stack overflow 6439085 says to return true to pop up menu
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.i("myTag", "in onOptionsItemSelected");
//LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); //added 11/12/2015 to remove updates
switch (item.getItemId()) {
case R.id.settings:
Intent settingsintent = new Intent(MainActivity.this, SettingsActivity.class);
MainActivity.this.startActivity(settingsintent);
break;
case R.id.help:
break;
case R.id.about:
break;
}
return true;
}
// Get the notifications status bar setting
public boolean notificationsSettingNotificationBar() {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean notificationsNewMessageNotificationBar = SP.getBoolean("notifications_new_message_notification_bar", true);
return notificationsNewMessageNotificationBar;
}
// Get the notifications ringtone
public String notificationsSettingRingtone() {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String notificationsNewMessageRingtone = SP.getString("notifications_new_message_ringtone", "NULL");
return notificationsNewMessageRingtone;
}
// Get the notifications vibrate setting
public boolean notificationsNewMessageSetting() {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean notificationNewMessageVibrate = SP.getBoolean("notifications_new_message_vibrate", true);
return notificationNewMessageVibrate;
}
private TextView latituteField;
private Context mContext;
}
LocationService
package com.example.BellasHBG;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import androidx.core.app.TaskStackBuilder;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
//import com.google.android.gms.location.LocationListener;
//import android.support.v7.app.AppCompatActivity;
//import android.support.v4.app.NotificationCompat;
//import android.support.v4.app.TaskStackBuilder;
//import com.google.android.gms.common.ConnectionResult;
//import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
//import com.google.android.gms.location.LocationListener;
//import com.google.android.gms.location.LocationRequest;
//import com.google.android.gms.location.LocationServices;
/**
* Created by craigmartensen on 4/7/16.
*/
public abstract class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 60000 * 1; // 1000 milliseconds in 1 second
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 5;
public static final long LOCATION_DISTANCE_IN_METERS = 3;
MyToolBox mtools = new MyToolBox();
public static GoogleApiClient mGoogleApiClient;
//public static GoogleSignInClient mSignInClient;
public static GoogleSignInAccount mSignInClient;
LocationRequest mlocationRequest;
private boolean isRemoving = false;
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#SuppressWarnings("static-access")
#Override
public void onCreate() {
isRemoving = false;
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
//alarm.SetAlarm(this);
//return START_STICKY;
super.onStartCommand(intent, flags, startId);
//Toast.makeText(this, "onHandleIntent", Toast.LENGTH_SHORT).show();
//mGoogleApiClient.connect();
Log.d("onStartCommand", "Service Started");
return Service.START_STICKY;
}
#Override
public void onConnected(Bundle connectionHint) {
if (isRemoving) {
stopLocationUpdates();
}
else {
isRemoving = false;
mlocationRequest = new LocationRequest();
mlocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mlocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mlocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mlocationRequest.setSmallestDisplacement(LOCATION_DISTANCE_IN_METERS);
Intent locationIntent = new Intent(getApplicationContext(), LocationIntentService.class);
locationIntent.putExtra("ID", "FusedLcation");
PendingIntent locationPendingIntent = PendingIntent.getService(getApplicationContext(), 0, locationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mlocationRequest, locationPendingIntent);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mlocationRequest, (com.google.android.gms.location.LocationListener) this);
}
}
public void onLocationChanged(Location loc)
{
Log.d("onLocationChanged", "Entering method");
//Toast.makeText(this, "onLocationChanged", Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
//Toast.makeText(getApplicationContext(), "entering onLocationChanged", Toast.LENGTH_SHORT).show();
String myText;
double mlat = loc.getLatitude();
double mlong = loc.getLongitude();
DBHelper myDBHelper = new DBHelper(this);
// use the following line if you just want to know if the location is found ie, sells Bellas
//boolean soldHere = myDBHelper.doesLocationSellBellas("my_table",41.685471,-73.975393);
// the following line retrieves the name of the location that sells bellas, null if it's not found
//String locName = myDBHelper.getLocationName("my_table", 41.685471, -73.975393);
String locName = myDBHelper.getLocationName(DBHelper.LOCATION_TABLE_NAME, mlat, mlong);
// set up for notification in the notification status bar
if (locName != null) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Bella's sold here");
// .setStyle(new NotificationCompat.BigTextStyle().bigText("Bella's sold here"));
// .setSubText(todaysjolt);
// .setDefaults(Notification.DEFAULT_SOUND)
//.setContentText("Bella's sold here");
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mBuilder.setContentText(locName);
mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(locName));
// new 10/14/2015 - set up to allow user to go to website from notification
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, MainActivity.class);
// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
// end new 10/14/2015
mNotifyMgr.notify(000, mBuilder.build());
Toast.makeText(getApplicationContext(), "You are at " + locName, Toast.LENGTH_SHORT).show();
//LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
}
protected void startLocationUpdates() {
if (mtools.notificationsSetting(this)) {
MainActivity.orignotifsetting = true;
//LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
public void stopLocationUpdates() {
if(!mGoogleApiClient.isConnected()){
isRemoving = true; //added
mGoogleApiClient.connect();
}
else {
//if (mGoogleApiClient != null) {
// if (!mGoogleApiClient.isConnected()) {
PendingIntent locationPendingIntent = PendingIntent.getService(this, 0, new Intent(this, LocationIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT);
//LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationPendingIntent); //moved below 1/28/2016
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) com.example.BellasHBG.LocationService.this);
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
stopSelf(); // stop the service
}
//}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this, "Connection Failed", Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionSuspended(int i) {
Log.d("LocationUpdateService", "Connection Suspended");
}
#Override
public void onDestroy(){
stopLocationUpdates();
//reportarGPS.interrupt();
//reportarGPS = null;
//LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) this);
//mGoogleApiClient.disconnect();
//mGoogleApiClient = null;
//mHandler.removeCallbacksAndMessages(null);
//Thread.currentThread().interrupt();
super.onDestroy();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.BellasHBG">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="21"/>
<application
android:allowBackup="true"
android:icon="#drawable/bellas_logo_48x36"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.BellasHBG"
android:usesCleartextTraffic="true">
<activity
android:name="com.example.BellasHBG.SettingsActivity"
android:label="#string/action_settings"/>
<activity
android:name="com.example.BellasHBG.CreateNotificationOnBar"
android:label="create_notification_on_bar"/>
<activity
android:name="com.example.BellasHBG.CustomPreference"
android:label="custom_preference"/>
<activity
android:name=".MainActivity"
android:label="Bella's Home Baked Goods" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.example.BellasHBG.Alarm" />
<service android:enabled='true' android:name="com.example.BellasHBG.LocationService" />
</application>
</manifest>
Please uncomment the import for com.google.android.gms.location.LocationListener on LocationService and give a try again.
I was trying to run the wifidirectdemo app provided on wifip2p page of documentation but on android 10 its not running perfectly.I tried the solution mentioned on WifiP2pManager.discoverPeers fails in android 10 ,but nothing helped.All other wifip2p functions are running normally only this is causing issue and returns 0 i.e. ERROR code.
Thanks for any suggestion.
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.deom">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- Google Play filtering -->
<uses-feature android:name="android.hardware.wifi.direct" android:required="true"/>
<application android:theme="#android:style/Theme.Holo" android:label="#string/app_name" android:icon="#drawable/ic_launcher">
<activity android:name=".WiFiDirectActivity" android:label="#string/app_name" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
<!-- Used for transferring files after a successful connection -->
<service android:name=".FileTransferService" android:enabled="true"/>
</application>
</manifest>
WifiDirectActivity.java
package com.example.deom;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.ChannelListener;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
/**
* An activity that uses WiFi Direct APIs to discover and connect with available
* devices. WiFi Direct APIs are asynchronous and rely on callback mechanism
* using interfaces to notify the application of operation success or failure.
* The application should also register a BroadcastReceiver for notification of
* WiFi state related events.
*/
public class WiFiDirectActivity extends Activity implements ChannelListener, DeviceListFragment.DeviceActionListener {
public static final String TAG = "wifidirectdemo";
private static final int PERMISSIONS_REQUEST_CODE_ACCESS_FINE_LOCATION = 1001;
private WifiP2pManager manager;
private boolean isWifiP2pEnabled = false;
private boolean retryChannel = false;
private final IntentFilter intentFilter = new IntentFilter();
private Channel channel;
private BroadcastReceiver receiver = null;
/**
* #param isWifiP2pEnabled the isWifiP2pEnabled to set
*/
public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) {
this.isWifiP2pEnabled = isWifiP2pEnabled;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_CODE_ACCESS_FINE_LOCATION:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "Fine location permission is not granted!");
finish();
}
break;
}
}
private boolean initP2p() {
// Device capability definition check
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
Log.e(TAG, "Wi-Fi Direct is not supported by this device.");
return false;
}
// Hardware capability check
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (wifiManager == null) {
Log.e(TAG, "Cannot get Wi-Fi system service.");
return false;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (!wifiManager.isP2pSupported()) {
Log.e(TAG, "Wi-Fi Direct is not supported by the hardware or Wi-Fi is off.");
return false;
}
}
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
if (manager == null) {
Log.e(TAG, "Cannot get Wi-Fi Direct system service.");
return false;
}
channel = manager.initialize(this, getMainLooper(), null);
if (channel == null) {
Log.e(TAG, "Cannot initialize Wi-Fi Direct.");
return false;
}
return true;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// add necessary intent values to be matched.
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
if (!initP2p()) {
finish();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
WiFiDirectActivity.PERMISSIONS_REQUEST_CODE_ACCESS_FINE_LOCATION);
// After this point you wait for callback in
// onRequestPermissionsResult(int, String[], int[]) overridden method
}
}
/** register the BroadcastReceiver with the intent values to be matched */
#Override
public void onResume() {
super.onResume();
receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
registerReceiver(receiver, intentFilter);
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
/**
* Remove all peers and clear all fields. This is called on
* BroadcastReceiver receiving a state change event.
*/
public void resetData() {
DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
if (fragmentList != null) {
fragmentList.clearPeers();
}
if (fragmentDetails != null) {
fragmentDetails.resetViews();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_items, menu);
return true;
}
/*
* (non-Javadoc)
* #see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*/
#SuppressLint("MissingPermission")
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.atn_direct_enable:
if (manager != null && channel != null) {
// Since this is the system wireless settings activity, it's
// not going to send us a result. We will be notified by
// WiFiDeviceBroadcastReceiver instead.
startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
} else {
Log.e(TAG, "channel or manager is null");
}
return true;
case R.id.atn_direct_discover:
if (!isWifiP2pEnabled) {
Toast.makeText(WiFiDirectActivity.this, R.string.p2p_off_warning,
Toast.LENGTH_SHORT).show();
return true;
}
final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
fragment.onInitiateDiscovery();
manager.discoverPeers(channel, new ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(WiFiDirectActivity.this, "Discovery Initiated",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reasonCode) {
Toast.makeText(WiFiDirectActivity.this, "Discovery Failed : " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void showDetails(WifiP2pDevice device) {
DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
fragment.showDetails(device);
}
#SuppressLint("MissingPermission")
#Override
public void connect(WifiP2pConfig config) {
manager.connect(channel, config, new ActionListener() {
#Override
public void onSuccess() {
// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
}
#Override
public void onFailure(int reason) {
Toast.makeText(WiFiDirectActivity.this, "Connect failed. Retry.",
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void disconnect() {
final DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
fragment.resetViews();
manager.removeGroup(channel, new ActionListener() {
#Override
public void onFailure(int reasonCode) {
Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
}
#Override
public void onSuccess() {
fragment.getView().setVisibility(View.GONE);
}
});
}
#Override
public void onChannelDisconnected() {
// we will try once more
if (manager != null && !retryChannel) {
Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show();
resetData();
retryChannel = true;
manager.initialize(this, getMainLooper(), this);
} else {
Toast.makeText(this,
"Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
Toast.LENGTH_LONG).show();
}
}
#Override
public void cancelDisconnect() {
/*
* A cancel abort request by user. Disconnect i.e. removeGroup if
* already connected. Else, request WifiP2pManager to abort the ongoing
* request
*/
if (manager != null) {
final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
if (fragment.getDevice() == null
|| fragment.getDevice().status == WifiP2pDevice.CONNECTED) {
disconnect();
} else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE
|| fragment.getDevice().status == WifiP2pDevice.INVITED) {
manager.cancelConnect(channel, new ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(WiFiDirectActivity.this, "Aborting connection",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reasonCode) {
Toast.makeText(WiFiDirectActivity.this,
"Connect abort request failed. Reason Code: " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
From android 10, location permission even though if granted at runtime by the user ,the app will not run.We have to either turn on manually the gps(location) from settings bar or open the setting programmatically to turn on gps and then run the app.This time as long as the gps(location) is ON discoverPeers() will run normally with no errors.Though on below devices GPS is not required.
I am using the classic GPS tracker code to retrieve my current location, but I always get 0 as a return for both lat and lon, even though I try to change positions its still always 0. please note that I have used the following code in previews apps and it worked.
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.apostolis.map1sttest">
<!-- Permition list bellow !-->
<uses-permission android:name="android.permission.INTERNET" /> <!-- internet -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- internet 3g/4g enabled-->
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <!-- Google accounts -->
<uses-permission android:name="android.permission.NETWORK" /> <!-- internet -->
<uses-permission android:name="android.permission.USE_CREDENTIALS" /> <!-- Google acconts -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/> <!-- phone info -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- GPS -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <!-- GPS -->
<uses-feature android:name="android.hardware.location.gps" /> <!-- GPS (needed for android 5.0+) -->
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
GPStracker.java
package com.example.apostolis.map1sttest;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.widget.Toast;
/**
* Created by Apostolis on 10/27/2016.
*/
public class GPStracker extends Service implements LocationListener {
private final Context context;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location;
double latitude;
double longituzzde;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
private static final long MIN_TIME_BW_UPDATES = 100;
protected LocationManager locationManager;
public GPStracker(Context context){
this.context = context;
getLocation();
}
public Location getLocation(){
try {
locationManager = (LocationManager)context.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(locationManager.NETWORK_PROVIDER);
if(!isGPSEnabled && !isGPSEnabled) {
} else {
this.canGetLocation = true;
if(isNetworkEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
if(isGPSEnabled) {
if(location == null) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
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;
}
public void stopUsingGPS(){
if(locationManager != null) {
locationManager.removeUpdates(GPStracker.this);
}
}
public double getLatitude() {
if(location != null) {
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude(){
if(location != null) {
longitude = location.getLongitude();
}
return longitude;
}
public boolean canGetLocation() {
return this.canGetLocation;
}
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setTitle("GPS SETTINGS");
alertDialog.setMessage("GPS is not enabled.Go to Settings menu and enable it?");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
}) ;
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
this.location = location;
getLatitude();
getLongitude();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
MainActivity.java
package com.example.apostolis.map1sttest;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
GPStracker gps;
private String lat,lon;
Button btnGetLocation;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private double mCurrentLatitude,mCurrentLongitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnGetLocation = (Button) findViewById(R.id.btgps);
//creating onClick listener for GPS.
btnGetLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
gps = new GPStracker(MainActivity.this);
if (gps.canGetLocation()) {
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
lat = Double.toString(latitude);
lon = Double.toString(longitude);
Toast.makeText(MainActivity.this,
"Your Location is: Lat: " + lat.toString() + " Lon:" + lon.toString(), Toast.LENGTH_LONG).show();
} else {
gps.showSettingsAlert();
}
}
});
};
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, 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;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this);
} else {
mCurrentLatitude = location.getLatitude();
mCurrentLongitude = location.getLongitude();
Toast.makeText(this, mCurrentLongitude + " * ********"+mCurrentLatitude, Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.apostolis.map1sttest.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:id="#+id/btgps" />
</RelativeLayout>
implement GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener
in your activity and past below code in override methods
#Override
public void onConnected(#Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, 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;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this);
} else {
Toast.makeText(this, location.getLatitude() + " * ********"+location.getLongitude(), Toast.LENGTH_LONG).show();
}
}
create variables
private LocationRequest mLocationRequest;
protected GoogleApiClient mGoogleApiClient;
add this inside your onCreate method
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.build();
and add this inside your onResume
if (!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting()) {
Log.e("Google API", "Connecting");
mGoogleApiClient.connect();
}
Problem is when I run service on emulator(android 4.0.3), then all is working(data is sent once per hour), but when i run it on my phone it's start sending data every minute. I can't figure out why, hope someone can help me with this.
The service is sending data to http://gprsbtn.herokuapp.com/coordinates where it's going to database.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aravov.gprsbtn"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.aravov.gprsbtn.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="MyService"></service>
<receiver android:name=".AlarmReciever"/>
</application>
</manifest>
MainActivity.java
package com.aravov.gprsbtn;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
final String LOG_TAG = "myLogs";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void btnClc(View v) {
startService(new Intent(this, MyService.class));
Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
}
public void btnClc2(View v) {
stopService(new Intent(this, MyService.class));
}
}
GPSTracker.java
package com.aravov.gprsbtn;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
public class GPSTracker 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 GPSTracker(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;
// 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(GPSTracker.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;
}
}
MyService.java
package com.aravov.gprsbtn;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.json.JSONObject;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service {
PendingIntent pendingIntent;
AlarmManager alarmManager;
BroadcastReceiver mReceiver;
final String LOG_TAG = "myLogs";
public void onCreate() {
super.onCreate();
Log.d(LOG_TAG, "onCreate");
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(LOG_TAG, "onStartCommand");
someTask();
sendNotif();
return super.onStartCommand(intent, flags, startId);
}
public void sendNotif() {
Notification notification = new Notification(R.drawable.ic_stat_gprsbtn, "Text in status bar",
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, "Notification's title", "Notification's text", pendingIntent);
startForeground(1992, notification);
}
public void onDestroy() {
stop();
super.onDestroy();
Log.d(LOG_TAG, "onDestroy");
}
public IBinder onBind(Intent intent) {
Log.d(LOG_TAG, "onBind");
return null;
}
void someTask() {
mReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
action();
}
};
registerReceiver(mReceiver, new IntentFilter("gprs.post"));
pendingIntent = PendingIntent.getBroadcast( this, 0, new Intent("gprs.post"),0 );
alarmManager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
// timer here <<< 1000 * 60 = 1 minute
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, 1000 * 60 * 60 , pendingIntent);
}
public void action() {
GPSTracker gps = new GPSTracker(MyService.this);
//final double latitude = gps.getLatitude();
//final double longitude = gps.getLongitude();
final String lat = Double.toString(gps.latitude);
final String lon = Double.toString(gps.longitude);
// check if GPS enabled
if(gps.canGetLocation())
{
//posting
Thread t = new Thread(){
public void run(){
postData(lat, lon);
}
};
t.start();
}
else
{
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
}
public void postData(String latitude, String longitude) {
try {
HttpParams p = new BasicHttpParams();
HttpClient client = new DefaultHttpClient(p);
HttpPost post = new HttpPost("http://gprsbtn.herokuapp.com/coordinates");
JSONObject params = new JSONObject();
params.put("latitude",latitude);
params.put("longitude",longitude);
StringEntity ent = new StringEntity(params.toString());
post.setEntity(ent);
post.setHeader("Content-type", "application/json");
client.execute(post);
Log.d(LOG_TAG, "onDataSent");
} catch (Exception e) {
e.printStackTrace();
}
}
// stop the alarm receiver
public void stop() {
try {
unregisterReceiver(mReceiver);
Toast.makeText(this, "Service stoped", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
}
}
}
I want to integrate google+ sign in my android app. I have given permissions in android manifest file and also initialized plusclient object but when using sign in button I'm getting an error "Unfortunately application has stopped!".
Android manifest file is:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.abs"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<application
android:allowBackup="true"
android:icon="#drawable/abs_icon"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.abs.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.abs.Bank"
android:label="#string/title_activity_bank" >
</activity>
<activity
android:name="com.abs.Scheme"
android:label="#string/title_activity_scheme" >
</activity>
<activity
android:name="com.abs.Login"
android:label="#string/title_activity_login" >
</activity>
</application>
</manifest>
Mainactivity is:
package com.abs;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
Button bank;
Button scheme;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bank = (Button) findViewById(R.id.button1);
scheme = (Button) findViewById(R.id.button2);
}
public void onClick_bank(View v){
Toast.makeText(MainActivity.this, "Searching by bank", Toast.LENGTH_SHORT).show();
Intent ibank = new Intent(v.getContext(),Bank.class);
startActivityForResult(ibank, 0);
}
public void onClick_scheme(View v){
Toast.makeText(MainActivity.this, "Searching by scheme", Toast.LENGTH_SHORT).show();
Intent ischeme = new Intent(v.getContext(),Scheme.class);
startActivityForResult(ischeme, 0);
}
public void onClick_login(View v){
Toast.makeText(MainActivity.this, "Please login with gmail id", Toast.LENGTH_SHORT).show();
Intent islog = new Intent(v.getContext(),Login.class);
startActivityForResult(islog, 0);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Login activity for google+ sign in is given below and i have taken the code from google examples: for switching to login.class from mainactivity i had to comment onstart() because mplusclient.connect() is not working, Please help...
package com.abs;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.plus.PlusClient;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class Login extends Activity implements OnClickListener,
PlusClient.ConnectionCallbacks, PlusClient.OnConnectionFailedListener,
PlusClient.OnAccessRevokedListener {
private static final int DIALOG_GET_GOOGLE_PLAY_SERVICES = 1;
private static final int REQUEST_CODE_SIGN_IN = 1;
private static final int REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES = 2;
private TextView mSignInStatus;
private PlusClient mPlusClient;
private SignInButton mSignInButton;
private View mSignOutButton;
private View mRevokeAccessButton;
private ConnectionResult mConnectionResult;
private ProgressDialog mConnectionProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mPlusClient = new PlusClient.Builder(Login.this, Login.this, Login.this)
.setActions("http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity")
.setScopes(Scopes.PLUS_LOGIN)
.build();
mConnectionProgressDialog = new ProgressDialog(this);
mConnectionProgressDialog.setMessage("Signing in...");
mSignInStatus = (TextView) findViewById(R.id.sign_in_status);
mSignInButton = (SignInButton) findViewById(R.id.sign_in_button);
mSignInButton.setOnClickListener(this);
mSignOutButton = findViewById(R.id.sign_out_button);
mSignOutButton.setOnClickListener(this);
mRevokeAccessButton = findViewById(R.id.revoke_access_button);
mRevokeAccessButton.setOnClickListener(this);
}
/*
#Override
public void onStart() {
super.onStart();
mPlusClient.connect();
}
#Override
public void onStop() {
mPlusClient.disconnect();
super.onStop();
}
*/
#SuppressWarnings("deprecation")
#Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.sign_in_button:
if(!mPlusClient.isConnected()){
mPlusClient.connect();
}
//mPlusClient.connect();
/*
int available = GooglePlayServicesUtil.isGooglePlayServicesAvailable(Login.this);
if (available == ConnectionResult.SUCCESS) {
showDialog(DIALOG_GET_GOOGLE_PLAY_SERVICES);
return;
}
try {
mSignInStatus.setText("Signing in");
mConnectionResult.startResolutionForResult(Login.this, REQUEST_CODE_SIGN_IN);
}
catch (IntentSender.SendIntentException e) {
// Fetch a new result to start.
mPlusClient.connect();
}
*/
break;
case R.id.sign_out_button:
if (mPlusClient.isConnected()) {
mPlusClient.clearDefaultAccount();
mPlusClient.disconnect();
mPlusClient.connect();
}
else{Toast.makeText(Login.this, "You are not connected to internet", Toast.LENGTH_LONG).show();}
break;
case R.id.revoke_access_button:
if (mPlusClient.isConnected()) {
mPlusClient.revokeAccessAndDisconnect(this);
updateButtons(false /* isSignedIn */);
}
else{Toast.makeText(Login.this, "You are not connected to internet", Toast.LENGTH_LONG).show();}
break;
}
}
#Override
protected Dialog onCreateDialog(int id) {
if (id != DIALOG_GET_GOOGLE_PLAY_SERVICES) {
return super.onCreateDialog(id);
}
int available = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (available == ConnectionResult.SUCCESS) {
return null;
}
if (GooglePlayServicesUtil.isUserRecoverableError(available)) {
return GooglePlayServicesUtil.getErrorDialog(
available, Login.this, REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES);
}
return new AlertDialog.Builder(this)
.setMessage("+ generic error")
.setCancelable(true)
.create();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Toast.makeText(Login.this, "activity result disabled", Toast.LENGTH_LONG).show();
if (requestCode == REQUEST_CODE_SIGN_IN
|| requestCode == REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES) {
if (resultCode == RESULT_OK && !mPlusClient.isConnected()
&& !mPlusClient.isConnecting()) {
// This time, connect should succeed.
mPlusClient.connect();
}
}
}
#Override
public void onAccessRevoked(ConnectionResult status) {
Toast.makeText(Login.this, "Access revoke not available", Toast.LENGTH_LONG).show();
if (status.isSuccess()) {
mSignInStatus.setText("revoke access status");
} else {
mSignInStatus.setText("revoke access status error");
mPlusClient.disconnect();
}
mPlusClient.connect();
}
#Override
public void onConnected(Bundle connectionHint) {
Toast.makeText(Login.this, "Client is connected", Toast.LENGTH_LONG).show();
String currentPersonName = mPlusClient.getCurrentPerson() != null
? mPlusClient.getCurrentPerson().getDisplayName()
: "Signed in currentPersonName";
mSignInStatus.setText("signed in as you");
updateButtons(true );/* isSignedIn */
}
#Override
public void onDisconnected() {
Toast.makeText(Login.this, "Client is disconnected", Toast.LENGTH_LONG).show();
mSignInStatus.setText("Loading status");
mPlusClient.connect();
updateButtons(false );/* isSignedIn */
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Toast.makeText(Login.this, "Connection failed", Toast.LENGTH_LONG).show();
mConnectionResult = result;
updateButtons(false );/* isSignedIn */
}
private void updateButtons(boolean isSignedIn) {
if (isSignedIn) {
mSignInButton.setVisibility(View.INVISIBLE);
mSignOutButton.setEnabled(true);
mRevokeAccessButton.setEnabled(true);
} else {
if (mConnectionResult == null) {
// Disable the sign-in button until onConnectionFailed is called with result.
mSignInButton.setVisibility(View.INVISIBLE);
mSignInStatus.setText("Loading status");
} else {
// Enable the sign-in button since a connection result is available.
mSignInButton.setVisibility(View.VISIBLE);
mSignInStatus.setText("Signed out");
}
mSignOutButton.setEnabled(false);
mRevokeAccessButton.setEnabled(false);
}
}
}
Thank you!!
I have been messing with the same code and finally got it running with some modifications.
According to me mPlusClient.connect(); must be called before click as it connects async and if used in the onclick it will give error.
here is my onclick() function
#Override
public void onClick(View arg0) {
int available = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (available != ConnectionResult.SUCCESS) {
showGoogleDialog();
return;
}
try {
mConnectionResult.startResolutionForResult(this, REQUEST_CODE_SIGN_IN);
} catch (IntentSender.SendIntentException e) {
mPlusClient.connect();
} catch (NullPointerException e1) {
PvrLog.d("null pointer exception");
}
}