Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
349 views
in Technique[技术] by (71.8m points)

java - Keep app running in background on Android all the time

I have to get people's trajectory (from home to job, for example), so my app gets latitude and longitude (I have two buttons: 1. Start to get lat and lon 2. Stop to get lat and lon). However, I want that android does not kill the app, I want to keep my application running while the user use facebook, twitter (for example) or simply the user locks his smartphone. My app works fine when user use the app while using facebook or twitter (for example), but when I lock my smartphone, Android kill the app. I have tried to use intentservice and service, but they do not work when I lock the screen. Should I use PowerManager.WakeLock? I do not exactly know how it works and what it does.

This is an example that I made to try services, I don't know if I am wrong, but it does not work when: 1. I am in the app (I have started the service) 2. I tap home button (while service is running) 3. I lock screen. 4. Then the service and the app are killed by android (and the service did not finished to do its stuff)

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javosoft.intentservice">

    <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>
        <service android:name=".MyService"
            android:exported="false"></service>

    </application>

</manifest>

activity_main

<?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.javosoft.intentservice.MainActivity">

    <Button
        android:text="start Service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="63dp"
        android:id="@+id/button"
        android:onClick="startService"/>

    <Button
        android:text="Stop Service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignLeft="@+id/button"
        android:layout_alignStart="@+id/button"
        android:layout_marginBottom="68dp"
        android:id="@+id/button2"
        android:onClick="stopService" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:hint="textito :D"
        android:ems="10"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/editText" />
</RelativeLayout>

Layout

MainActivity

package com.javosoft.intentservice;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, MyService.class);
                startService(intent);
            }
        });

    }

    public void stopService (View view){
        Intent intent = new Intent(this, MyService.class);
        stopService(intent);
    }
}

MyService class

package com.javosoft.intentservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

public class MyService extends Service {

    final class MyThreadClass implements Runnable{

        int service_id;
        MyThreadClass(int service_id){
            this.service_id = service_id;
        }

        @Override
        public void run() {

            synchronized (this){
                int count = 0;
                while (count < 10){
                    Log.i("servicio", "while: " + String.valueOf(count));
                    try {
                        wait(2000);
                        count++;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            stopSelf(service_id);

        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "El servició ha empezado D:", Toast.LENGTH_SHORT).show();
        Log.i("servicio", "El servició ha empezado D:");


        Log.i("servicio", "onStartCommand arriba");

        Thread thread = new Thread(new MyThreadClass(startId));
        thread.start();

        Log.i("servicio", "onStartCommand abajo");
        return START_STICKY;
        //return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        //super.onDestroy();
        Toast.makeText(this, "El servicio ha padarado ._.", Toast.LENGTH_SHORT).show();
        Log.i("servicio", "El servicio ha padarado ._.");
    }

    //@Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return null;

    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Try our this

public class ForegroundService extends Service {
    private static final String LOG_TAG = "ForegroundService";

    @Override
    public void onCreate() {
        super.onCreate();
    }

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

        // Your logical code here

        return START_STICKY;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {

        //When remove app from background then start it again
        startService(new Intent(this, ForegroundService.class));

        super.onTaskRemoved(rootIntent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(LOG_TAG, "In onDestroy");
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Used only in case of bound services.
        return null;
    }
}

On Start button click:

Intent startIntent = new Intent(MainActivity.this, ForegroundService.class);
    startService(startIntent);

In Manifest

<service
            android:name=".ForegroundService"
            android:enabled="true"
            android:stopWithTask="false" />

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...