简体   繁体   English

Android 前台服务没有通知 - 如何?

[英]Android Foreground service without notification - how to?

I have created foreground service for notifications in my application.我在我的应用程序中为通知创建了前台服务。 It's working fine, the problem is to start the foreground service we need foreground notification which tell that your application is running like this .它工作正常,问题是启动我们需要前台通知的前台服务,它告诉您的应用程序正在像这样运行。 I don't want this notification.我不想要这个通知。 How I can remove that notification without killing the service.如何在不终止服务的情况下删除该通知。

This is how I'm starting the foreground service.这就是我启动前台服务的方式。

@Override
public void onCreate() {
    super.onCreate();
    stopForeground(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel serviceChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_DEFAULT);
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(serviceChannel);
    }
    Intent stopSelf = new Intent(this, Notification_Service.class);
    stopSelf.setAction("ACTION_STOP_SERVICE");
    PendingIntent pStopSelf = PendingIntent
            .getService(this, 0, stopSelf
                    , PendingIntent.FLAG_CANCEL_CURRENT);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Service.NOTIFICATION_SERVICE);
    NotificationCompat.Action action =
            new NotificationCompat.Action.Builder(
                    0, "Close", pStopSelf
            ).build();
    Notification notification = notificationBuilder
            .setSmallIcon(R.drawable.ic_launcher_background)
            .setContentTitle("Ask Question")
            .setContentText("Ask Question is running")
            .addAction(action)
            .setPriority(Notification.PRIORITY_MIN)
            .build();
    notificationManager.notify(1, notification);
    startForeground(1, notification);
    notificationManager.cancel(1);
    SharedPreferences settings = getSharedPreferences("Session", MODE_PRIVATE);
    id = settings.getString("id", null);
    apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
    handler.postDelayed(new Runnable() {
        public void run() {
            startMyOwnForeground();
            handler.postDelayed(this, delay);
        }
    }, delay);
}

private void startMyOwnForeground() {
    Log.e("", "service running");
    get_notification();
}

Retrofit call to get notification: Retrofit 致电获取通知:

  private void get_notification() {
        Call<ArrayList> call = apiInterface.getnotification(ApiClient.pin, id);
        call.enqueue(new Callback<ArrayList>() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onResponse(Call<ArrayList> call, Response<ArrayList> response) {
                if (response.body() != null) {
                    for (int i = 0; i < response.body().size(); i = i + 1) {
                        ArrayList<String> getdata = (ArrayList<String>) response.body().get(i);
                        String[] data = getdata.toArray(new String[0]);
                        if (data[5].equals("0")) {
                            switch (data[4]) {
                                case "comment":
                                    send_comment_notification(data[1], data[2], data[3], data[0]);
                                    break;
                                case "question":
                                    send_question_notification(data[3], data[0], data[1]);
                                    break;
                                case "answer":
                                    send_answer_notification(data[3], data[0], data[1]);
                                    break;
                            }
                        }
                    }
                }
            }

            @Override
            public void onFailure(Call<ArrayList> call, Throwable t) {

            }
        });
    }

It seems you are trying to show notifications using a "pull" approach instead of a "push" approach.您似乎正在尝试使用“拉”方法而不是“推”方法来显示通知。 For showing notifications which are triggered by some backend system you should normally use push notifications.为了显示由某些后端系统触发的通知,您通常应该使用推送通知。

Only if you have no control over the backend system you could think about pulling regular updates from the server.只有当您无法控制后端系统时,您才能考虑从服务器中提取定期更新。 But even then it probably would make sense to create your own backend (see also BFF pattern ) which pulls the updates and then sends push notifications to your app instead of each app pulling from the server.但即便如此,创建自己的后端(另请参阅BFF 模式)可能会有意义,该后端会拉取更新,然后将推送通知发送到您的应用程序,而不是从服务器拉取每个应用程序。

As already suggested in the comments you should use FCM to push notifications from your server to your app.正如评论中已经建议的那样,您应该使用 FCM 将通知从您的服务器推送到您的应用程序。 Check out the FCM docs for a good overview.查看FCM 文档以获得良好的概述。 The Android system and the Firebase SDK will do the heavy lifting for you and your app does not need to run in the background or foreground to receive notifications. Android 系统和 Firebase SDK 将为您完成繁重的工作,您的应用程序无需在后台或前台运行即可接收通知。

If you still want to pull in regular time intervals from a server, you should either use the WorkManager API or even use sync adapters to implement a background sync mechanism.如果您仍想从服务器中获取定期时间间隔,您应该使用WorkManager API 甚至使用同步适配器来实现后台同步机制。 Then you can use the NotificationBuilder to create a "local" notifiction.然后您可以使用NotificationBuilder创建“本地”通知。

Here is the implementation of Karsten Planz这是Karsten Planz的实施

You should either use the WorkManager API to implement a background sync mechanism.您应该使用 WorkManager API 来实现后台同步机制。 Then you can use the NotificationBuilder to create a "local" notifiction.然后您可以使用 NotificationBuilder 创建“本地”通知。

Start the Task in your main activity by this:通过以下方式在您的主要活动中启动任务:

  WorkRequest uploadWorkRequest =
                new OneTimeWorkRequest.Builder(NotificationWorker.class)
                        .build();
        WorkManager
                .getInstance(MainActivity.this)
                .enqueue(uploadWorkRequest);

Now Create a class NotificationWorker and extends Worker .现在创建一个 class NotificationWorker并扩展Worker Place your startMyOwnForeground in doWork by returning Result.retry() , this will make a recursive function.通过返回Result.retry()startMyOwnForeground放入doWork ,这将生成递归 function。

public class NotificationWorker extends Worker {

    Context  context;
  
    public NotificationWorker(
            @NonNull Context context,
            @NonNull WorkerParameters params) {
        super(context, params);
        this.context=context;
    }

    @Override
    public Result doWork() {
        startMyOwnForeground();
        return Result.retry();
    }
    private void startMyOwnForeground() {
        Log.e("", "service running");
        get_notification();
    }

    private void get_notification() {
        Call<ArrayList> call = apiInterface.getnotification(ApiClient.pin, id);
        call.enqueue(new Callback<ArrayList>() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onResponse(Call<ArrayList> call, Response<ArrayList> response) {
                if (response.body() != null) {
                    for (int i = 0; i < response.body().size(); i = i + 1) {
                        ArrayList<String> getdata = (ArrayList<String>) response.body().get(i);
                        String[] data = getdata.toArray(new String[0]);
                        if (data[5].equals("0")) {
                            switch (data[4]) {
                                case "comment":
                                    send_comment_notification(data[1], data[2], data[3], data[0]);
                                    break;
                                case "question":
                                    send_question_notification(data[3], data[0], data[1]);
                                    break;
                                case "answer":
                                    send_answer_notification(data[3], data[0], data[1]);
                                    break;
                            }
                        }
                    }
                }
            }

            @Override
            public void onFailure(Call<ArrayList> call, Throwable t) {

            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM