【问题标题】:Service doesn't work when app is closed, although earlier did应用程序关闭时服务不起作用,尽管之前有
【发布时间】:2021-03-05 19:48:45
【问题描述】:

这是NotificationService.class的当前代码:

package com.mypack.appname;

import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.webkit.WebView;

import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;

public class NotificationService extends Service {

Timer timer;
TimerTask timerTask;
String TAG = "Timers";
int Your_X_SECS = 5;


@Override
public IBinder onBind(Intent arg0) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.e(TAG, "onStartCommand");
    super.onStartCommand(intent, flags, startId);

    startTimer();

    return START_STICKY;
}


@Override
public void onCreate() {
    Log.e(TAG, "onCreate");


}

@Override
public void onDestroy() {
    Log.e(TAG, "onDestroy");
    stoptimertask();
    super.onDestroy();


}

//we are going to use a handler to be able to run in our TimerTask
final Handler handler = new Handler();
public android.content.Context ant;

public void startTimer() {
    //set a new Timer
    timer = new Timer();
    ant = this;

    //initialize the TimerTask's job
    timerTask = new TimerTask() {
        public void run() {

            //use a handler to run a toast that shows the current timestamp
            handler.post(new Runnable() {
                public void run() {

                    //TODO CALL NOTIFICATION FUNC

                    new GetUrlContentTask().execute("some url here");
                }
            });
        }
    };

    //schedule the timer, after the first 5000ms the TimerTask will run every 10000ms
    timer.schedule(timerTask, 5000, Your_X_SECS * 1000); //
    //timer.schedule(timerTask, 5000,1000); //
}

public void stoptimertask() {
    //stop the timer, if it's not already null
    if (timer != null) {
        timer.cancel();
        timer = null;
    }
}

private class GetUrlContentTask extends AsyncTask<String, Integer, String> {
    protected String doInBackground(String... urls) {
        try {
            URL url = new URL(urls[0]);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.connect();
            BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String content = "", line;
            while ((line = rd.readLine()) != null) {
                content += line + "\n";
            }

            if(Objects.equals(content,"{\"nocomments\":true"))
                return content;

            JSONObject o = new JSONObject(content);
            String m_id = o.getString("id");
            JSONArray a = o.getJSONArray("comments");
            int le = a.length();

            SharedPreferences settings = getApplicationContext().getSharedPreferences("prefnameaga", 0);
            int lele = settings.getInt(m_id, 0);

            if(lele != le)
            {
                SharedPreferences.Editor editor = settings.edit();
                editor.putInt(m_id, le);
                editor.apply();

                JSONObject la = a.getJSONObject(le-1);
                String data = la.getString("data");

                Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);

                NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), "IMACHANNE");
                builder.setSmallIcon(R.drawable.ic_launcher_foreground);
                builder.setContentTitle("New comment for the post");
                builder.setContentText(data);
                builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
                builder.setAutoCancel(true);
                builder.setContentIntent(pendingIntent);

                NotificationManagerCompat ntf = NotificationManagerCompat.from(getApplicationContext());
                ntf.notify(1, builder.build());
            }



  
            return content;
        }
        catch(Exception ex)
        {
            return "error";
        }
    }

    protected void onProgressUpdate(Integer... progress) {
    }

    protected void onPostExecute(String result) {
        // this is executed on the main thread after the process is over
        // update your UI here
        // displayMessage(result);

    }
}

}

之前,在void Run() 中有代码只显示“hello world”通知。在MainActivity 中,我写了在调用onStop() 时启动服务。当用户切换到另一个应用程序(不是关闭当前)时,通知已经到达,但是当用户关闭应用程序时,通知没有到达。我修复了在清单中将 android:stopWithTask="false" 添加到 service 的问题。

现在我添加了一些新功能,代码如您在上面看到的那样。出于某种原因,现在我再次面临这个问题:当应用程序切换时,通知显示绝对正确:http请求成功发出,一切都很好。但是当应用关闭时 - 什么都没有发生。

我犯了什么错误,如何解决?

【问题讨论】:

    标签: android sharedpreferences android-service


    【解决方案1】:

    This answer 通过一些修改帮助我解决了我的问题(但我仍然不知道为什么它更早起作用):在我的通知服务类中,我从 onCreateonDestroy 中删除了所有部分服务重启,因为我只需要在应用程序关闭或终止时运行服务。

    【讨论】:

    • 可能有两个原因 1. 您使用的设备低于 VERSION_CODES.O 并且,2. 也许,在 android-studio 的新更新中,很多东西已被弃用(并非在所有设备上都适用设备)。
    • @Istiak,不幸的是,我在同一台设备上使用 Android 8.1 进行测试,似乎我的 Android Studio 也没有更新
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 2018-05-05
    • 2018-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    相关资源
    最近更新 更多