一直在Android后台运行app

时间:2022-12-17 20:57:54

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.

我必须得到人们的轨迹(例如,从家里到工作),所以我的应用程序得到了经纬度(我有两个按钮:1)。开始得到lat和lon 2。停下车来。然而,我想要的是,android不会扼杀这个应用程序,我想让我的应用程序在用户使用facebook、twitter(例如twitter)或仅仅是用户锁定他的智能手机时运行。我的应用程序在用户使用facebook或twitter时运行良好(例如),但当我锁定智能手机时,Android会关闭这个应用程序。我曾尝试使用intentservice和服务,但当我锁定屏幕时,它们不起作用。我应该用PowerManager.WakeLock吗?我不知道它是怎么工作的,它是怎么工作的。

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)

这是我尝试服务的一个例子,我不知道我是否错了,但是当:1时它不起作用。我在应用程序(我已经开始服务)2。我点击home键(服务正在运行)3。我锁定屏幕。4所示。然后这个服务和这个应用被android杀死(这个服务还没有完成)

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

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>

一直在Android后台运行app

MainActivity

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

MyService类

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;

    }
}

3 个解决方案

#1


1  

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" />

#2


0  

As @Gudin says, it looks to me like you stop the service after 20 seconds. However, since you say this works sometimes, I'm guessing that's just some test code. I suspect your problem is in how you start the Service. Passing the Activity's context means your Service is tied to the lifecycle of that Activity. If that is destroyed, I think your Service goes with it. (Simply going through onStop() of the Activity & not onDestroy() leaves the Service intact). Try this

正如@Gudin所说,在我看来,你在20秒后就停止了这项服务。但是,既然您说这有时是有效的,我猜这只是一些测试代码。我怀疑你的问题在于你如何开始这项服务。传递活动的上下文意味着您的服务绑定到该活动的生命周期。如果你的服务被毁了,我想你的服务也会随之消失。(简单地通过onStop()活动,而不是onDestroy()将服务完整地保留下来)。试试这个

    Intent intent = new Intent(getApplicationContext(), MyService.class);

I tried duplicating your problem but couldn't so I can't say for sure this is your problem. This is a good place to start though.

我试着把你的问题重复一遍,但没办法,所以我不能肯定这就是你的问题。这是一个很好的起点。

#3


0  

I've read that some smartphones have these kind of problems, I found that Huawei, Xiaomi among others have problems with implementation Services, and guess what: My smartphone is a Huawei. The problem comes out of programs preinstalled on these devices for energy saving. Therefore, I tried to run my program on a Nexus (simulator for this one), a Sony and a Moto G, the program ran well for these 3 devices. Thanks for help.

我读到过一些智能手机有这样的问题,我发现华为、小米等公司在实现服务方面存在问题,你猜怎么着:我的智能手机是华为。问题来自于这些设备上预装的节能程序。因此,我尝试在Nexus(这款的模拟器)、索尼(Sony)和Moto G上运行我的程序,这款程序在这三款设备上运行良好。谢谢你的帮助。

#1


1  

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" />

#2


0  

As @Gudin says, it looks to me like you stop the service after 20 seconds. However, since you say this works sometimes, I'm guessing that's just some test code. I suspect your problem is in how you start the Service. Passing the Activity's context means your Service is tied to the lifecycle of that Activity. If that is destroyed, I think your Service goes with it. (Simply going through onStop() of the Activity & not onDestroy() leaves the Service intact). Try this

正如@Gudin所说,在我看来,你在20秒后就停止了这项服务。但是,既然您说这有时是有效的,我猜这只是一些测试代码。我怀疑你的问题在于你如何开始这项服务。传递活动的上下文意味着您的服务绑定到该活动的生命周期。如果你的服务被毁了,我想你的服务也会随之消失。(简单地通过onStop()活动,而不是onDestroy()将服务完整地保留下来)。试试这个

    Intent intent = new Intent(getApplicationContext(), MyService.class);

I tried duplicating your problem but couldn't so I can't say for sure this is your problem. This is a good place to start though.

我试着把你的问题重复一遍,但没办法,所以我不能肯定这就是你的问题。这是一个很好的起点。

#3


0  

I've read that some smartphones have these kind of problems, I found that Huawei, Xiaomi among others have problems with implementation Services, and guess what: My smartphone is a Huawei. The problem comes out of programs preinstalled on these devices for energy saving. Therefore, I tried to run my program on a Nexus (simulator for this one), a Sony and a Moto G, the program ran well for these 3 devices. Thanks for help.

我读到过一些智能手机有这样的问题,我发现华为、小米等公司在实现服务方面存在问题,你猜怎么着:我的智能手机是华为。问题来自于这些设备上预装的节能程序。因此,我尝试在Nexus(这款的模拟器)、索尼(Sony)和Moto G上运行我的程序,这款程序在这三款设备上运行良好。谢谢你的帮助。