java—一个封闭的应用程序如何接收定期广播?

34gzjxbg  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(285)

我有一个android 9设备,我正在开发一个应用程序,根据当前日期和时间显示内容。我希望它定期检查是否有新的内容,并告知用户。此外,我想这也工作时,用户关闭应用程序。例如,我的电子邮件应用程序在关闭时也会显示有关新电子邮件的通知。
我的方法是接收普通广播( Intent.ACTION_USER_PRESENT 以及 Intent.ACTION_SCREEN_ON ),在接收时运行计时器,然后定期检查新内容。我知道用户必须为此启动我的应用程序一次(如果应用程序至少启动一次,广播接收器就不能在ics中工作)。如果用户使用多任务按钮并向上滑动我的活动以关闭它,那么这种方法是不成功的。
即使用户已关闭我的应用程序/活动,我如何接收广播。
这里有很多帖子,都问同样的问题,但大多数似乎都过时了!我试过很多次,但都没成功!因此,我为api 28设置了一个示例应用程序,我想再次提出这个问题,但这次是用一个已定义的示例。那么应该很容易检查提议的解决方案是否真的有效!
在androidstudio中创建一个空活动 File -> New -> New Project... -> Empty Activity -> Language: Java, SDK: API 28 .
添加一个类 MyBroadcastReceiver 包括以下内容:

  1. package org.test.myapplication;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.widget.Toast;
  6. public class MyBroadcastReceiver extends BroadcastReceiver
  7. {
  8. @Override
  9. public void onReceive(Context context, Intent intent)
  10. {
  11. Toast.makeText(context, "Hurray! I have received the broadcast!", Toast.LENGTH_LONG).show();
  12. }
  13. }

修改类 MainActivity 具有以下内容:

  1. package org.test.myapplication;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Intent;
  4. import android.content.IntentFilter;
  5. import android.os.Bundle;
  6. import android.util.Log;
  7. import androidx.appcompat.app.AppCompatActivity;
  8. public class MainActivity extends AppCompatActivity
  9. {
  10. private static BroadcastReceiver broadcastReceiver = null;
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState)
  13. {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.activity_main);
  16. if (null == broadcastReceiver)
  17. {
  18. // Register broadcast receiver (only a running application my do that)
  19. IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT);
  20. filter.addAction(Intent.ACTION_SCREEN_ON);
  21. Log.i("MainActivity", "Registered broadcast receiver.");
  22. broadcastReceiver = new MyBroadcastReceiver();
  23. registerReceiver(broadcastReceiver, filter);
  24. }
  25. }
  26. }

在安装和运行活动时,每当我注销和再次登录时,都会看到toast。但当我把活动刷上去结束后,我就再也看不到祝酒词了。我怎样才能改变这一点?

h4cxqtbf

h4cxqtbf1#

如对接受答案的评论所述,使用 WorkManager 是解决我问题的简单方法。作为一个补充,我想在这里展示我的代码给任何对同一主题感兴趣的人。
班级 MyWorker :

  1. package org.test.myapplication;
  2. import android.content.Context;
  3. import android.os.Handler;
  4. import android.os.Looper;
  5. import android.widget.Toast;
  6. import androidx.annotation.NonNull;
  7. import androidx.work.Worker;
  8. import androidx.work.WorkerParameters;
  9. public class MyWorker extends Worker
  10. {
  11. public MyWorker(@NonNull Context context, @NonNull WorkerParameters params)
  12. {
  13. super(context, params);
  14. }
  15. @Override
  16. public Result doWork()
  17. {
  18. Handler handler = new Handler(Looper.getMainLooper());
  19. handler.postDelayed(new Runnable()
  20. {
  21. @Override
  22. public void run()
  23. {
  24. // Run your task here
  25. Toast.makeText(getApplicationContext(), "Testing", Toast.LENGTH_SHORT).show();
  26. }
  27. }, 1000);
  28. // Indicate whether the work finished successfully with the Result
  29. return Result.success();
  30. }
  31. }

班级 MainActivity :

  1. package org.test.myapplication;
  2. import android.os.Bundle;
  3. import androidx.appcompat.app.AppCompatActivity;
  4. import androidx.work.PeriodicWorkRequest;
  5. import androidx.work.WorkManager;
  6. import androidx.work.WorkRequest;
  7. import java.util.concurrent.TimeUnit;
  8. public class MainActivity extends AppCompatActivity
  9. {
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState)
  12. {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.activity_main);
  15. WorkRequest workRequest =
  16. new PeriodicWorkRequest.Builder(MyWorker.class, 15, TimeUnit.MINUTES).build();
  17. WorkManager.getInstance(this).enqueue(workRequest);
  18. }
  19. }
展开查看全部
disho6za

disho6za2#

但当我把活动刷上去结束后,我就再也看不到祝酒词了。
当然。充其量,您的接收器将在进程运行时接收广播。您的进程将因许多原因而终止,包括您所描述的手动用户操作。
我怎样才能改变这一点?
对于较旧的android设备,您可以通过 <receiver> 元素。对于android8.0及更高版本上的大多数隐式广播来说,这是行不通的,比如你提到的两个。
例如,我的电子邮件应用程序在关闭时也会显示有关新电子邮件的通知。
服务器可能正在使用firebase云消息(fcm)向应用程序发出新消息的警报。或者,应用程序可以使用 WorkManager 或者类似的东西。请记住,打瞌睡模式、应用程序待机以及各种特定于制造商的黑客攻击使得应用程序很难在后台可靠地执行周期性工作,因为这样的工作不利于电池寿命。

相关问题