Ranjit
Ranjit

Reputation: 5150

Android:Android Service forces application to run slow

I have googled many times and also tried for solutions here by asking this kind of questions. but no helps yet. so I think may be there is some problems in my code.

The main motto of my application is to track gps location in each minute and send to server. and also do some server transactions.So I think to start a background service and doing all gps and server stuffs in service through asynctask.The application is running but it performs so slow...

Here I started my service in my mainactivity:

    private void startworks() {
    Calendar cal = Calendar.getInstance();
    Intent intent = new Intent(this, NewService.class);
    PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
    alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
            45 * 1000, pintent);
}

    @Override
    protected void onStart() {
    super.onStart();
    startworks();
}

And about my service..I provide here the total one..

public class NewService extends Service {
String servicestring;
String lastId = "";
String holdLastId = "";
private static final String NotificationUrl = "some url";
private static final double LATITUDE = 12.9056742;
private static final double LONGITUDE = 77.6512342;

public static final int MSG_INCREMENT = 1;
public static final int MSG_COUNTER = 2;

private final IBinder mBinder = new ServiceBinder();

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    toggleGPSOn();
    sendnotification();

    WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);

    if (!wm.isWifiEnabled()) {
        wm.setWifiEnabled(true);
    } else {
        // wm.setWifiEnabled(false);
    }
    // ************************Fetch InTime*******************************
    AsyncTime getDate = new AsyncTime();

    String returnedDateTime = "";
    try {
        returnedDateTime = getDate.execute().get();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    if (returnedDateTime.equals("2013-09-18 14:11:01.000")) {
        Toast.makeText(this, "It exits", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(this, "It doesn't exits", Toast.LENGTH_SHORT).show();
    }
    // *****************************----****************************************
    FetchCordinates async = new FetchCordinates();
    async.execute();

    return START_STICKY;
}

public class ServiceBinder extends Binder {
    NewService getService() {
        return NewService.this;
    }
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

public void setAlarmReminder(Calendar c) {
    new AlarmReminderTask(this, c).run();
}

private void toggleGPSOn() {
    String provider = Settings.Secure.getString(getContentResolver(),
            Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

    if (!provider.contains("gps")) {
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings",
                "com.android.settings.widget.SettingsAppWidgetProvider");

        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3"));
        sendBroadcast(poke);
    }
}

public class FetchCordinates extends AsyncTask<String, Integer, String> {

    public double lati = 0.0;
    public double longi = 0.0;
    String serverLatitude = "";
    String serverLongitude = "";
    String dateString;

    public LocationManager mLocationManager;
    public MyLocationListener mVeggsterLocationListener;

    @Override
    protected void onPreExecute() {
        Criteria myCriteria = new Criteria();
        myCriteria.setAccuracy(Criteria.ACCURACY_MEDIUM);
        myCriteria.setPowerRequirement(Criteria.POWER_LOW);

        mVeggsterLocationListener = new MyLocationListener();
        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        String myProvider = mLocationManager.getBestProvider(myCriteria,
                true);
        mLocationManager.requestLocationUpdates(myProvider, 500, 5,
                mVeggsterLocationListener);
    }

    private double distance(double lat1, double lon1, double lat2,
            double lon2) {
        double theta = lon1 - lon2;
        double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
                + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
                * Math.cos(deg2rad(theta));
        dist = Math.acos(dist);
        dist = rad2deg(dist);
        dist = dist * 60 * 1.1515;
        return (dist);
    }

    private double deg2rad(double deg) {
        return (deg * Math.PI / 180.0);
    }

    private double rad2deg(double rad) {
        return (rad * 180.0 / Math.PI);
    }

    public double round(double unrounded) {
        BigDecimal bd = new BigDecimal(unrounded * 1.609344f);
        BigDecimal rounded = bd.setScale(1, BigDecimal.ROUND_CEILING);
        Log.d("Distance Is:", "Currentlly you are " + rounded.doubleValue()
                * 1000 + " meters " + "distance from Last Distance");
        return rounded.doubleValue() * 1000;
    }

    @Override
    protected String doInBackground(String... params) {

        while (this.lati == 0.0) {

        }
        return null;
    }

    public class MyLocationListener implements LocationListener {

        @Override
        public void onLocationChanged(Location location) {

            try {

                SimpleDateFormat fmt = new SimpleDateFormat(
                        "dd-MM-yyyy-HH:mm:ss");
                Date date = new Date();
                dateString = fmt.format(date);
                Log.d("DateString", dateString);

                lati = location.getLatitude();
                longi = location.getLongitude();

            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onProviderDisabled(String provider) {
            Log.i("OnProviderDisabled", "OnProviderDisabled");
        }

        @Override
        public void onProviderEnabled(String provider) {
            Log.i("onProviderEnabled", "onProviderEnabled");
        }

        @Override
        public void onStatusChanged(String provider, int status,
                Bundle extras) {
            Log.i("onStatusChanged", "onStatusChanged");

        }

    }

    @Override
    protected void onCancelled() {

        mLocationManager.removeUpdates(mVeggsterLocationListener);
    }

    @Override
    protected void onPostExecute(String result) {
        Log.d("Post Execute", "Executed");
        super.onPostExecute(result);
        float[] arr = new float[30];

        if (round(distance(LATITUDE, LONGITUDE, lati, longi)) < 500) {
            Log.d("OnPostExecute", "In");
            sendServiceActiveBroadcast(true);
            Thread swipeInThread = new Thread() {

                @Override
                public void run() {
                    super.run();
                    try {
                        HttpClient client = new DefaultHttpClient();
                        HttpPost post = new HttpPost(
                                "url...");
                        HttpResponse responses = client.execute(post);
                        int status = responses.getStatusLine()
                                .getStatusCode();
                        Log.d("Status", String.valueOf(status));

                    } catch (ClientProtocolException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            };
            swipeInThread.start();

        } else if (round(distance(LATITUDE, LONGITUDE, lati, longi)) > 500
                && round(distance(LATITUDE, LONGITUDE, lati, longi)) < 600) {
            Log.d("OnPostExecute", "Out");
            sendServiceActiveBroadcast(false);

        } else {

        }
    }

    private final void sendServiceActiveBroadcast(final boolean pActivate) {
        final Intent _intent = new Intent();
        _intent.setAction(BROADCAST_ACTION);
        _intent.putExtra("isactive", pActivate);

        NewService.this.sendBroadcast(_intent);
    }

}

class AsyncTime extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... v) {
        String getDateTime = "";

        try {
            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(
                    "url..");
            HttpResponse responses = client.execute(get);
            int status = responses.getStatusLine().getStatusCode();
            Log.d("Status For Get", String.valueOf(status));
            BufferedReader bf = new BufferedReader(new InputStreamReader(
                    responses.getEntity().getContent()));
            String datas = "";
            while ((datas = bf.readLine()) != null) {
                Log.d("data", datas);
                try {
                    JSONObject jsonStuffs = new JSONObject(datas);
                    getDateTime = jsonStuffs.getString("inTime");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return getDateTime;
    }

}

I know I have shared a huge code here. but its most important for me to share this.

any kind of suggestions and helps are mostly appreciable..

Thank You

Upvotes: 2

Views: 2035

Answers (3)

justHooman
justHooman

Reputation: 3054

I thinks problem lie in this code returnedDateTime = getDate.execute().get();

Arrcodring to this get method

get method maybe wait for your doinBackground works to complete, which will lead to wait on MainThread and make your app slow;

Hope this help.

Upvotes: 2

Leonidos
Leonidos

Reputation: 10518

First, you extend Service, it means that all your service code runs in main thread (toggleGPSOn, sendnotification...). You can extend IntentService than onStartCommand will be executed in separate thread. You don't even need AsyncTaks in this case.

Second, AsyncTask isn't as simple as it seems. On new androids it is a single threaded queue. So your service's tasks will block app tasks sometimes.

Finally, if you really have a heavy service and you can't fit all in one process, you can run service in separate process and use IPC to communicate between service and main app.

Upvotes: 1

Neto Marin
Neto Marin

Reputation: 674

The correct way to do this is using listeners, so you can receive updates and then, send them to the server. Also, you should thing a strategy to the communication to you wont drain the battery.

Please, take a look at the Location Strategies guide, and you will undestand better how to reach what you want.

Upvotes: 1

Related Questions