• 卡一为主卡时,google play下载应用,下载过程中卡二接听来电,挂断电话后google play不会续传


        此问题是一个恢复网络后,下载管理没有自动恢复下载的问题。 手机在来电过程中是会断掉数据网络的,

    但是在挂断电话之后会恢复,刚开始以为这个问题是应用没有收到 数据网络连接 恢复的广播去重新启动下载服务造成,

    因为对比机器 三星 是正常的, 所以很天真地以为增加一个 接收广播 android.intent.action.ANY_DATA_STATE ,然后启动下载服务就可以了。

    但是在调试的过程中发现并不行, 因为下载管理的 receiver 配置的export 属性是false:

    当export 属性为 false 时, 当前broadcast Receiver 只能收到同一个应用或者拥有同一 user ID 应用发出广播。这个应该是原生处于安全考虑,不能随意改动。

     调试时发现 android.intent.action.PHONE_STATE 广播虽然同样报警告错误:
     Permission Denial: broadcasting Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } from android (pid=1786, uid=1001) is not exported from uid 10009 due to receiver com.android.providers.downloads/com.oppo.providers.downloads.OppoDownloadReceiver
     
        Line 14997: 0711 20:10:05.599  1197  1498 V ActivityManager: Broadcast: Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } ordered=false userid=-1
    Line 14999: 07-11 20:10:05.599  1197  1498 V ActivityManager: broadcastIntentLocked callingPid: 2226 callingUid=1001
     
     
    $ adb shell ps | grep 1197
    system    1197  432   2383876 144428 ffffffff 94ed9010 S system_server
     
    80080800@P80080800 /cygdrive/z/git_project/server_150/app/OppoDownLoadProvider/bin
    $ adb shell ps | grep 2226
    radio     2226  432   2154872 65992 ffffffff 94ed9010 S com.android.phone
    最终此路不通~~~~  
     
     
          后来想了想原生既然没有增加监听这个 数据网络状态变化的 广播, 那应该是有其他的方式来恢复下载,并且三星应该也不会去修改原生的,所以继续分析源码,后面发现果不其然, 下载管理中有一个闹钟唤醒机制, 当在某些条件下不能正常下载时, 会设置一个闹钟,在一段时间后重试,重新启动服务。
    ACTION_RETRY android.intent.action.DOWNLOAD_WAKEUP
     
    和系统一起分析log :

    ActivityManager: Broadcast intent Intent { act=android.intent.action.DOWNLOAD_WAKEUP flg=0x14 cmp=com.android.providers.downloads/.DownloadReceiver (has extras) } on background queue

    Line 91967: V/BroadcastQueue( 1183): Delivering to component ComponentInfo{com.android.providers.downloads/com.oppo.providers.downloads.OppoDownloadReceiver}: BroadcastRecord{1a52090b u0 android.intent.action.DOWNLOAD_WAKEUP}
    从系统查看到没有发送广播出去的原因为,该广播没有注册receiver进行接收,对比查看receiver 在manifest中名字和代码中指定名字不对应。发送的OPPO重写的类名,但是manifest中注册的还是原生的DownloadReceiver类名。
     
     
    至此真相浮出水面,水落石出~~~
     
     
    原生的闹钟定时精妙算法要分享一下:
    /**
    * Returns the time when a download should be restarted.
    */
    public long restartTime(long now) {
    if (mNumFailed == 0) {
    return now;
    }
    if (mRetryAfter > 0) {
    return mLastMod + mRetryAfter;
    }
    return mLastMod +
    Constants.RETRY_FIRST_DELAY *
    (1000 + mFuzz) * (1 << (mNumFailed - 1));
    }


    推迟基数定位 30 秒,加一个随机时间 也在30秒之类, 失败次数越多,相应时间翻倍处理。


    ------------------------------------------------------------------
        原因:
    原生有一个闹钟机制,当无网络时会定一个时间值,然后等时间到了之后发送广播,由广播接收器接受重新启动下载服务,时间值是由基准加随机数计算出来的,如果之前没有下载失败的话,时间值在30秒到一分钟之内,如果之前有失败,则会增长时间值。
    但是由于OPPO ROM重写了下载管理广播接收器,在manifest中声明的receiver其名字和代码中延时发送广播指定的receiver名称没有保持一致,导致接受不到广播,无法重新启动下载。
     
     
        修改方法:
    将广播接收器receiver的名称改为和manifest中一致
     
     
  • 相关阅读:
    POJ Area of Simple Polygons 扫描线
    POJ2828 Buy Tickets 线段树
    cf578c Weakness and Poorness 三分
    poj3737 UmBasketella 真正的三分
    POJ1061 青蛙的约会 exgcd
    POJ3090 Visible Lattice Points 欧拉函数
    P2860 [USACO06JAN]冗余路径Redundant Paths
    [JSOI2008]球形空间产生器
    [APIO2010]特别行动队
    [ZJOI2007]仓库建设
  • 原文地址:https://www.cnblogs.com/yangwubo/p/8686705.html
Copyright © 2020-2023  润新知