• 05-11-2018, 18:50:28
    #1
    Kimlik doğrulama veya yönetimden onay bekliyor.
    Merhabalar Arkadaşlar,

    Anlık konum takibi ile ilgili firebase ile realtime olarak çalışan bir ufak uygulama yazmaya çalışıyorum. Uygulamanın çalışmasında herhangi bir problem yok fakat başlattığım servisi durduramıyorum ve arkaplanda anlık olarak yine firebase'e veri göndermeye devam ediyor.

    Servis kısmının kodlarını aşağıda paylaşıyorum.

    Çok farklı yöntemler denedim fakat bir türlü yapamadım Mobil konusunda da biraz yeniyim muhtemelen gözümden kaçan birkaç yer var

    public class TrackerService extends Service {
        User user;
        private static final String TAG = TrackerService.class.getSimpleName();
        LocationRequest request;
        @Override
        public IBinder onBind(Intent intent) {return null;}
    
        @Override
        public void onCreate() {
            super.onCreate();
            buildNotification();
            loginToFirebase();
            user = SharedPrefManager.getInstance(this).getUser();
    
        }
    
    
        private void buildNotification() {
            String stop = "stop";
            registerReceiver(stopReceiver, new IntentFilter(stop));
            PendingIntent broadcastIntent = PendingIntent.getBroadcast(
                    this, 0, new Intent(stop), PendingIntent.FLAG_UPDATE_CURRENT);
            // Create the persistent notification
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                    .setContentTitle(getString(R.string.app_name))
                    .setContentText(getString(R.string.notification_text))
                    .setOngoing(true)
                    .setContentIntent(broadcastIntent)
                    .setSmallIcon(R.drawable.ic_logo);
            startForeground(1, builder.build());
        }
    
        protected BroadcastReceiver stopReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.d(TAG, "received stop broadcast");
                // Stop the service when the notification is tapped
                unregisterReceiver(stopReceiver);
                stopSelf();
            }
        };
    
        private void loginToFirebase() {
            // Authenticate with Firebase, and request location updates
            String email = getString(R.string.firebase_email);
            String password = getString(R.string.firebase_password);
            FirebaseAuth.getInstance().signInWithEmailAndPassword(
                    email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>(){
                @Override
                public void onComplete(Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "firebase auth success");
                        requestLocationUpdates();
                    } else {
                        Log.d(TAG, "firebase auth failed");
                    }
                }
            });
        }
    
        private void requestLocationUpdates() {
            request = new LocationRequest();
            request.setInterval(1000);
            request.setFastestInterval(5000);
            request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
            final String path = getString(R.string.firebase_path) + "/" + user.getId();
    
    
            int permission = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);
            if (permission == PackageManager.PERMISSION_GRANTED) {
                // Request location updates and when an update is
                // received, store the location in Firebase
                client.requestLocationUpdates(request, new LocationCallback() {
                    @Override
                    public void onLocationResult(LocationResult locationResult) {
                        DatabaseReference ref = FirebaseDatabase.getInstance().getReference(path);
    
                        Location location = locationResult.getLastLocation();
                        if (location != null) {
                            Map<String, Object> myList = new HashMap<>();
    
    
                            myList.put("UserName", user.getAd()+" "+user.getSoyad());
                            myList.put("accuracy", location.getAccuracy());
                            myList.put("altitude", location.getAltitude());
                            myList.put("bearing", location.getBearing());
                            myList.put("elapsedRealtimeNanos", location.getElapsedRealtimeNanos());
                            myList.put("fromMockProvider", location.isFromMockProvider());
                            myList.put("latitude", location.getLatitude());
                            myList.put("longitude", location.getLongitude());
                            myList.put("provider", location.getProvider());
                            myList.put("speed", location.getSpeed());
                            myList.put("time", location.getTime());
    
                            ref.setValue(myList);
                        }
                    }
                }, null);
            }
        }
    }
    Servisi Activity'de şu şekilde kullanıyorum.
                startService(new Intent(getApplicationContext(), TrackerService.class));
                stopService(new Intent(getApplicationContext(), TrackerService.class));

    Start etmede problem yok stop etmede Servis tarafında onDestroy kullanmama rağmen arkada çalışan intenti sonlandıramıyorum.

    Edit:
    requestLocationUpdates kısmında çalışan request ile ilgili olduğunu tahmin etmekteyim.


    Yardımlarınızı bekliyorum
  • 05-11-2018, 20:08:31
    #2
    İyi akşamlar. Servisinizde onDestroy implementini göremedim. onDestroy anında, FusedLocationProviderClient sınıfının removeLocationUpdates() metodunu kullanmanızın işe yarayacağını düşünüyorum. Set ettiğiniz LocationCallbacki bi callback değişkenine alıp onDestroy anında remove edin. Ayrıca bu servisiniz maalesef android 8 de çalışmaz. Eğer hedefinizde android O var ise biraz daha araştırma yapmanızı öneririrm. Teşekkürler
  • 05-11-2018, 20:14:16
    #3
    stopService(Intent intent) metodunu kullanabilirsiniz. Activity'lerde yer alan onDestroy, onResume gibi bir metoddur.
  • 05-11-2018, 21:43:49
    #4
    Merhabalar,

    Stopservice, ondestroy ve removeLocationUpdates metotlarını kullandım herhangi bir hata almıyorum. onDestroyun da çalıştığını teyit ettim fakat update işlemi devam ediyordu. Callback ile ilgili olan kısmı deneyip yazacağım.
  • 05-11-2018, 23:31:38
    #5
    Zaten gördüğüm kadarıyla servisini STICKY başlatmıyorsun, yani bu durumda, bu sürekli update etme durumu yazdığın tracker servisiyle değil tamamen lokasyon listener servisinin kendi davranışıyla alakalı olabilir. App'i destroy ettikten sonra Developer options'tan running servislere bakabilirsin. Hangi servisin çalıştığını anlamak için
  • 06-11-2018, 01:01:20
    #6
    Üyeliği durduruldu
    Intent serviceIntent=new Intent(getApplicationContext(), TrackerService.class);

    startService(serviceIntent);
    stopService(serviceIntent);

    Bu şekilde dener misiniz?
  • 06-11-2018, 09:46:26
    #7
    TayfunCesur35 adlı üyeden alıntı: mesajı görüntüle
    Zaten gördüğüm kadarıyla servisini STICKY başlatmıyorsun, yani bu durumda, bu sürekli update etme durumu yazdığın tracker servisiyle değil tamamen lokasyon listener servisinin kendi davranışıyla alakalı olabilir. App'i destroy ettikten sonra Developer options'tan running servislere bakabilirsin. Hangi servisin çalıştığını anlamak için

    Evet hocam LocationRequest ile işlemi gerçekleştiriyor.

    BondArcher adlı üyeden alıntı: mesajı görüntüle
    Intent serviceIntent=new Intent(getApplicationContext(), TrackerService.class);

    startService(serviceIntent);
    stopService(serviceIntent);

    Bu şekilde dener misiniz?

    Bu şekilde de denedim daha önce fakat yine istediğim sonucu elde edemedim.

    Yukarıda belirtildiği gibi bütün döngü requestLocationUpdates içinde client.requestLocationUpdates kısmında dönüyor ve buda removelocationupdates durdurulamıyor.
  • 06-11-2018, 17:42:33
    #8
    Kimlik doğrulama veya yönetimden onay bekliyor.
    Merhabalar,
    extends service classta, doğru kullanım için 4 farklı metod ile çalışmanız gereklidir. Bunlar onCreate, onStartCommand, onDestroy, ve onBind 'dır. Eğer ki servicenizde çalışacak komutları onStartCommand metoduna eklerseniz startService ile servicenizi başlatabilirsiniz. onStartCommand metodunu return START_STICKY; değeri ile döndürmeniz gereklidir. Ardına onDestroyu tanımlayıp stopService ile serviceinizi durdurabilirsiniz. Bu şekilde servicei tanımladığınızda sorununuzu çözebileceğinizi düşünüyorum. Bide ekstra olarak onCreate metodu servicei bu şekilde tanımladığınızda boş kalacağından içerisine super.onCreate(); yazmalısınız. İyi çalışmalar dilerim.
  • 06-11-2018, 18:13:36
    #9
    Arkadaşlar yardımlarınız için teşekkür ederim.

    LocationCallback'i Callback değişkenine alarak çözüm sağladım daha önce de aynı şekilde denemiştim fakat Notification kısmını kaldırdıktan sonra problem olmadı ve sağlıklı şekilde çalışıyor.


    public class TrackerService extends Service {
        User user;
        MainActivity main;
        private static final String TAG = TrackerService.class.getSimpleName();
        LocationRequest request;
        PendingIntent broadcastIntent;
        LocationCallback first;
        FusedLocationProviderClient client;
        float lastlng;
        float lastltd;
        float mesafe;
        @Override
        public IBinder onBind(Intent intent) {return null;}
    
        @Override
        public void onCreate() {
            super.onCreate();
            loginToFirebase();
            user = SharedPrefManager.getInstance(this).getUser();
    
        }
        @Override
        public void onDestroy(){
            client.removeLocationUpdates(first);
            final String path = getString(R.string.firebase_path) + "/" + user.getId();
            DatabaseReference ref = FirebaseDatabase.getInstance().getReference(path);
            ref.child("status").setValue(0);
        }
    
        public static float distFrom(float lat1, float lng1, float lat2, float lng2) {
            double earthRadius = 6371000; //meters
            double dLat = Math.toRadians(lat2-lat1);
            double dLng = Math.toRadians(lng2-lng1);
            double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                    Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                            Math.sin(dLng/2) * Math.sin(dLng/2);
            double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
            float dist = (float) (earthRadius * c);
    
            return dist;
        }
    
    
    
    
    
        private void loginToFirebase() {
            // Authenticate with Firebase, and request location updates
            String email = getString(R.string.firebase_email);
            String password = getString(R.string.firebase_password);
            FirebaseAuth.getInstance().signInWithEmailAndPassword(
                    email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>(){
                @Override
                public void onComplete(Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "firebase auth success");
                        requestLocationUpdates();
                    } else {
                        Log.d(TAG, "firebase auth failed");
                    }
                }
            });
        }
    
        private void requestLocationUpdates() {
            request = new LocationRequest();
            request.setInterval(1000);
            request.setFastestInterval(2500);
            request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            client = LocationServices.getFusedLocationProviderClient(this);
            final String path = getString(R.string.firebase_path) + "/" + user.getId();
            first = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    DatabaseReference ref = FirebaseDatabase.getInstance().getReference(path);
    
                    Location location = locationResult.getLastLocation();
                    if (location != null) {
                        Map<String, Object> myList = new HashMap<>();
    
    
                        myList.put("UserName", user.getAd()+" "+user.getSoyad());
                        myList.put("accuracy", location.getAccuracy());
                        myList.put("altitude", location.getAltitude());
                        myList.put("bearing", location.getBearing());
                        myList.put("elapsedRealtimeNanos", location.getElapsedRealtimeNanos());
                        myList.put("fromMockProvider", location.isFromMockProvider());
                        myList.put("latitude", location.getLatitude());
                        myList.put("longitude", location.getLongitude());
                        myList.put("provider", location.getProvider());
                        myList.put("speed", location.getSpeed());
                        myList.put("time", location.getTime());
                        myList.put("status", 1);
    
    
    
                        ref.setValue(myList);
    
                        if((double) lastltd > 0 && (double) lastlng > 0) {
                            mesafe = distFrom(lastltd,lastlng,(float)location.getLatitude(), (float)location.getLongitude());
    
                            Log.d(TAG,"Mesafa + "+distFrom(lastltd,lastlng,(float)location.getLatitude(), (float)location.getLongitude()));
                            if(mesafe > 10) {
                                SendData(Double.toString(location.getLongitude()), Double.toString(location.getLatitude()), "" + user.getId(), user.getAuth());
                            }
                        }else{
                            SendData(Double.toString(location.getLongitude()), Double.toString(location.getLatitude()), "" + user.getId(), user.getAuth());
                        }
    
    
    
    
    
    
    
                        lastlng = (float)location.getLongitude();
                        lastltd = (float)location.getLatitude();
    
    
                    }
                }
            };
    
            int permission = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);
            if (permission == PackageManager.PERMISSION_GRANTED) {
                // Request location updates and when an update is
                // received, store the location in Firebase
                client.requestLocationUpdates(request,first, null);
    
            }
        }
    
        public void SendData(final String longtitude, final String latitude, final String user_id, final String auth){
            RequestQueue queue = Volley.newRequestQueue(this);
    
            StringRequest stringRequest = new StringRequest(Request.Method.POST, URLs.URL_POST,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            try {
                                JSONObject Obj = new JSONObject(response);
                                if(Obj.getInt("error_code") == 1) {
                                    SharedPrefManager.getInstance(getApplicationContext()).logout();
                                }
                            } catch (JSONException e) {
                                Log.e(TAG, "unexpected JSON exception", e);
                            }
    
                            Log.e(TAG, "Gelen yanıt: "+ response.toString());
                            Log.e(TAG, "Gönderilen"+ user_id+" - "+auth);
                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e(TAG,"Çalışmıyor!"+ error);
                }
            })
            {
                @Override
                protected Map<String,String> getParams(){
                    SimpleDateFormat fmt = new SimpleDateFormat("MM-dd-yyyy HH:mm");
                    Date currentTime = Calendar.getInstance().getTime();
                    fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String dateString = fmt.format(currentTime);
                    Map<String,String> params = new HashMap<String, String>();
                    params.put("long",longtitude);
                    params.put("lati",latitude);
                    params.put("date",dateString);
                    params.put("id",user_id);
                    params.put("auth",auth);
                    return params;
                }
                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String,String> params = new HashMap<String, String>();
                    params.put("Content-Type","application/x-www-form-urlencoded");
                    return params;
                }
            };
            queue.add(stringRequest);
        }
    }