【问题标题】:Broadcast DOWNLOAD_COMPLETE is not recieved if app is not running如果应用程序未运行,则不会收到广播 DOWNLOAD COMPLETE
【发布时间】:2017-05-31 17:09:54
【问题描述】:

问题: 广播 android.intent.action.DOWNLOAD_COMPLETE 仅在应用程序正在运行或在后台接收。如果应用程序被终止,则永远不会收到广播。

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
<uses-permission android:name="android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS" />

<receiver
    android:name=".adapters.VideoListAdapter$VideoDownloadedReceiver"
    android:exported="true">

    <intent-filter>
        <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
    </intent-filter>
</receiver>

接收器类

public static class VideoDownloadedReceiver extends BroadcastReceiver implements AsyncResponse {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("YES", "in receive");
    }
}

请注意,我并非在所有设备上都面临此问题。

我遇到此问题的设备:Lenevo A600Asus Zenfone Max

运行良好的设备:Asus Zenfone 5 (cyanogenmod 13)、Android Studio Emulator (Nexus 6p marshmallow)、Samsung J7 Prime、Samsung j5、Nexus 5

【问题讨论】:

标签: android android-intent android-broadcast android-download-manager android-broadcastreceiver


【解决方案1】:

接收器似乎是一个内部类。由于应用程序已被销毁,因此您的内部接收器类也是已销毁类的一部分。

我基于这个假设,因为您的清单有

android:name=".adapters.VideoListAdapter$VideoDownloadedReceiver"

将“BroadcastReceiver”分离到自己的类中,它应该可以按预期工作。

至于在某些手机上工作,我会检查其他正在运行的应用程序以及您可能在后台运行的应用程序抑制应用程序类型,这些应用程序可能会导致强制关闭您的应用程序。

你应该有这样的东西。我查看了代码,你有嵌套的接收器,但你没有保持服务。

调用函数开始动作

private void startDownloadService() {
    Intent downloadIntent = new Intent(this, VideoDownloadReceiverService.class);

    if (!VideoDownloadReceiverService.isRunning()) {
        // My manifest has enabled="false" so i do this to turn it 'ON'
        component = new ComponentName(CounterActivity.this, VideoDownloadReceiverService.class);
        getPackageManager()
                .setComponentEnabledSetting(component,
                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                        PackageManager.DONT_KILL_APP);
        // Start the service
        startService(downloadIntent);
    }
}

在单独的文件中是服务

public class VideoDownloadReceiverService extends Service{

    private static boolean isRunning = false;

    public VideoDownloadReceiverService(){

    }

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

        // you may not need this since oyu register it in the Manifest. the fact the service is running
        // should keep your app alive and receiving and unable to be shutdown
        // but this is what i did
        IntentFilter filter = new IntentFilter();
        filter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        receiver = new VideoDownloadReceiver();
        registerReceiver(receiver, filter);

        Notification notification = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentText("Viewer Text In Notification").build();
        startForeground(MyConstants.NOTIFICATION_ID, notification);

        isRunning = true;
        return START_STICKY; // This is the line that keeps the service running no matter what
    }

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

    @Override
    public void onDestroy(){
        unregisterReceiver(receiver);
        super.onDestroy();
    }
}

在单独的文件中,这里是接收者

public class VideoDownloadReceiver extends BroadcastReceiver {
    public VideoDownloadReceiver() {

    }
    @Override
    public void onReceive(Context context, Intent intent) {
        PowerManager powerManager = (PowerManager) context.getSystemService(POWER_SERVICE);
        PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                "com.example.johnbravado.zionwork");
        wakeLock.acquire();

        Toast.makeText(context, "in service", Toast.LENGTH_SHORT).show();
        Log.i("YES", "service on receive");

        wakeLock.release();
    }
}

【讨论】:

  • 对广播接收器进行了不同的调用,但仍然没有成功。
  • 签入您的代码。如果应用程序被杀死,那么您正在调用 onStop()、onDestroy()。您是否在任何可能导致此问题的方法中停止接收器?
  • 你说得很好。你确定它正在发送一条消息。您还没有发布说 sendBrocast(intent) 的代码。也许当你的应用死掉时,不是接收者死了,而是发送者死了
  • 我没有手动发送广播。如果文件正在下载,应该自动发送广播,这就是我写在 ~Manifest~ 文件中的原因。我还没有调用过这样的方法 sendBrocast(intent)。
  • 我相信,即使您的接收器已在清单中声明,您也必须有一个未终止的应用程序才能运行。如果您强制退出应用程序,我认为与该应用程序和服务相关联的接收器也会被销毁。让它们保持活力的唯一方法是创建一个 startForeground 服务并注册接收器,而我只是对此进行了轻微测试。但这样做你将不得不永久显示通知
【解决方案2】:

如果你想在应用关闭后接收广播,那么你应该在服务中使用广播

以下内容将帮助您实施:- https://stackoverflow.com/a/16824692/4246910

【讨论】:

  • 我创建了一个服务并在其中进行了广播,但如果应用程序被杀死,它仍然不会调用 onReceive 方法。应用运行时调用的服务 onReceive 方法
【解决方案3】:

我觉得可能是自定义ROM的原因,限制了广播,CM,ASOP,原来是System.so,,,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    相关资源
    最近更新 更多