华为P10 Lite Android 8上没有电池消耗的情况下仍会出现电池消耗通知

时间:2019-02-08 08:42:28

标签: android

我的一个同事收到通知,说我帮助开发的应用程序在后台时会很快耗尽电池电量。到目前为止,她是我认识的第一个通过我们的应用程序收到此通知的人。

让我描述一下应用程序的功能/需要:当用户启动应用程序时,设备将被本地化一次。之后,用户必须按下按钮以更新其位置。每当用户切换到特定活动时,服务器都会被ping通以更新应用程序中的数据。除了使用该应用程序所需的GPS之外,没有其他权限。仅在服务器被ping通时,并且仅在主动使用该应用程序时更新位置。

这是服务器通信的代码。

/**
 * Queries for Stores in the BoundingBox defined by the given GeoCoordinates.
 * After the Async- Query was successful the Stores which are in the Resultset but currently not
 * loaded are queryed for and added to the global Adapter and an
 * ID-Filter is put in place limiting the List to the retrieved ones.
 *
 * @param topLeft     TopLeft- Coordinates for the Query
 * @param bottomRight BottomRight- Coordinates for the Query
 */
private void queryForStoresInBoundingBox(lokalfuchs.de.lokalfuchs.api.model.Location topLeft, lokalfuchs.de.lokalfuchs.api.model.Location bottomRight) {

    //query elasticsearch for all stores in the given region
    StoreService.getInstance().queryForStoresInGeoPointBoundingBox(
            topLeft, bottomRight, new ElasticsearchQueryCallback() {
                @Override
                public void querySuccesful(final List<Integer> ids) {
                    //from the list of ids which lie in the currently visible region: determine which are not currently loaded
                    final List<Integer> missingStores = StoreService.getInstance().getStoreAdapter().findMissingItemIds(ids);
                    final List<Integer> missingOffers = OfferService.getInstance().findMissingStoreIds(ids);
                    if (!missingStores.isEmpty()) {
                        //request these missing items and add them in the adapter
                        StoreService.getInstance().requestStores(null, null, missingStores.toArray(new Integer[missingStores.size()]), new StoreRequestCallback() {
                            @Override
                            public void requestSuccesful(final List<Store> stores) {
                                // !! TODO dont ask for offers without out valid offer ids you will get from elastic search!
                                OfferService.getInstance().requestOffers(null, missingOffers.toArray(new Integer[missingOffers.size()]), null, null, new OfferRequestCallback() {
                                    @Override
                                    public void requestSuccesful(final List<Offer> offers) {

                                        // TODO replace quick fix, just fetching valid offers with elastic offerIds
                                        // only continue with valid offers
                                        final List<Offer> validOffers = new ArrayList<>();

                                        SimpleDateFormat parserEndDate = new SimpleDateFormat(getResources().getString(R.string.date_pattern));
                                        Date currentDate = new Date();
                                        for (Offer offer : offers) {
                                            try {
                                                Date endDate = parserEndDate.parse(offer.getEndDate());

                                                if (endDate != null && currentDate.compareTo(endDate) < 0) {
                                                    validOffers.add(offer);
                                                    continue;
                                                }
                                            } catch (ParseException e) {
                                                e.printStackTrace();
                                            }
                                        }

                                        //add to adapter on ui-thread
                                        MapActivity.this.runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                Map<Integer, List<Integer>> allStoreOffers = OfferService.getInstance().getOffers();
                                                ItemAdapter adapter = OfferService.getInstance().getOfferAdapter();

                                                final List<Offer> handledOffers = (LocationService.getInstance().getLastLocation() != null) ? OfferService.getInstance().calculateDistancesAndRemoveExpiredOffers(
                                                        validOffers, new com.google.maps.model.LatLng(LocationService.getInstance().getLastLocation().getLatitude(), LocationService.getInstance().getLastLocation().getLongitude())) : validOffers;

                                                for (Offer o : handledOffers) {
                                                    OfferService.getInstance().getOfferAdapter().getItems().put(o.getId(), o);
                                                    List<Integer> storeOffers = allStoreOffers.get(o.getStoreId());
                                                    if (storeOffers == null) {
                                                        storeOffers = new ArrayList<>();
                                                        allStoreOffers.put(o.getStoreId(), storeOffers);
                                                    }
                                                    if (!storeOffers.contains(o.getId())) {
                                                        storeOffers.add(o.getId());
                                                        adapter.getItems().put(o.getId(), o);
                                                    }
                                                }
                                                Map<Integer, MappableItem> list = StoreService.getInstance().getStoreAdapter().getItems();

                                                for (Store store : stores)
                                                    list.put(store.getId(), store);
                                                StoreService.getInstance().getStoreAdapter().setIdFilter(new ItemIdFilter(ids));
                                            }
                                        });
                                    }

                                    @Override
                                    public void requestFailed(int errorCode) {
                                    }
                                });
                            }

                            @Override
                            public void requestFailed(int errorCode) {

                            }
                        });
                    } else {
                        //there are no missing items - add the filter immediately instead of after the query
                        StoreService.getInstance().getStoreAdapter().setIdFilter(new ItemIdFilter(ids));
                    }

                }

                @Override
                public void queryFailed() {

                }
            });
}

public void queryForStoresInGeoPointBoundingBox(@NonNull Location top_left, @NonNull Location bottom_right, final @NonNull ElasticsearchQueryCallback callback) {

    //if the coordinates are not correctly ordered reoder them
    if (top_left.getLat() < bottom_right.getLat()) {
        Double temp = top_left.getLat();
        top_left.setLat(bottom_right.getLat());
        bottom_right.setLat(temp);
    }
    if (top_left.getLon() > bottom_right.getLon()) {
        Double temp = top_left.getLon();
        top_left.setLon(bottom_right.getLon());
        bottom_right.setLon(temp);
    }

    this.elasticSearchInterface.elasticSearchStoreIdsGeopointRequest(new ElasticSearchInterface.SearchQuery(top_left, bottom_right, false), LokalFuchs.DEFAULT_SIZE).enqueue(new Callback<ElasticSearchInterface.SearchResult>() {
        @Override
        public void onResponse(Call<ElasticSearchInterface.SearchResult> call, Response<ElasticSearchInterface.SearchResult> response) {
            //check for response-code 200
            if (response.code() == 200) {
                //prepare resultlist
                List<Integer> storeIds = new ArrayList<>();

                //and iterate over all hits extracting the ids
                for (ElasticSearchInterface.SearchResult.Hits hit : response.body().hits.hits) {
                    if (hit.fields.id.length > 0)
                        storeIds.add(hit.fields.id[0]);
                }
                callback.querySuccesful(storeIds);
            } else {
                callback.queryFailed();
            }
        }

        @Override
        public void onFailure(Call<ElasticSearchInterface.SearchResult> call, Throwable t) {
            callback.queryFailed();
        }
    });

}

我忘了提到数据加载需要很长时间,可能需要4秒钟以上。

这是本地化的代码。

/**
 * asking for localisation permission
 * <p>
 * if ok:
 * start location updates 
 * if not set isRequesting to false
 *
 * @param activity Activity
 */
public boolean requestLocation(Activity activity) {

    if (AppService.getInstance().checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, activity, R.string.missing_gps_permission, null)) {
        this.isRequesting = true;
             this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        return true;
    } else {
        return false;
    }
}

 /**
 * register Callback for change of position
 *
 * @param locationChangedCallback Callback für for position change
 */
public void registerCallback(LocationChangedCallback locationChangedCallback) {
    if (!this.locationChangedCallbacks.contains(locationChangedCallback)) {
        this.locationChangedCallbacks.add(locationChangedCallback);
    }
}

@Override
public void onMapReady(GoogleMap googleMap) {
[...]
    //register for location-changes and request the location once
    Location location = LocationService.getInstance().getLastLocation();

    //if we have a location use it
    if (location == null) {
        this.googleMap.moveCamera(CameraUpdateFactory.zoomTo(15));
        this.googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(52.520008, 13.404954)));
        LocationService.getInstance().registerCallback(this);
        LocationService.getInstance().requestLocation(this);
    } else {
        LatLng position = new LatLng(location.getLatitude(), location.getLongitude());
        this.markMyPosition(position);
        this.googleMap.moveCamera(CameraUpdateFactory.zoomTo(15));
        this.googleMap.moveCamera(CameraUpdateFactory.newLatLng(position));
    }
[...]
}

我检查了她手机上的电池电量消耗详细信息,即使该应用程序处于活动状态且GPS仅使用了不到10秒钟,CPU也没有太多工作要做。该应用程序在过去30天内下载了20 mb。仍然,她在15分钟左右后仍收到通知,并且她必须关闭它才能摆脱通知。到目前为止,她在任何其他应用程序上都没有这个问题,也没有其他人报告过这个问题。

有人知道这个问题可能是什么,或者我能做些什么找出导致这个问题的原因?

0 个答案:

没有答案