Как отправить сведения об обнаруженной информации маяка на сервер в фоновом режиме? - PullRequest
0 голосов
/ 04 октября 2018

Я занимаюсь разработкой приложения, которое требует Обнаружить доступные маяки рядом с вашим регионом, и сведения об обнаруженных маяках необходимо отправить на мой сервер с помощью вызова API.Я получаю информацию о маяке, но я не могу отправить информацию на мой сервер, поскольку фон приложения обнаружил маяк.

Вот детали маяков;

    private class ScanProcessor extends AsyncTask<ScanData, Void, Void> {

        @Override
        protected Void doInBackground(ScanData... params) {
            ScanData scanData = params[0];

           IBeacon iBeacon = IBeacon.fromScanData(scanData.scanRecord, scanData.rssi);
           if (iBeacon != null) {
               lastIBeaconDetectionTime = new Date();
               trackedBeacons.add(iBeacon);
               Log.d(TAG, "iBeacon detected :"+iBeacon.getProximityUuid()+" Major: "+iBeacon.getMajor()+" Minor: "+iBeacon.getMinor()+" accuracy: "+iBeacon.getAccuracy()+" proximity: "+iBeacon.getProximity());

               List<Region> matchedRegions = matchingRegions(iBeacon, monitoredRegionState.keySet());
               Iterator<Region> matchedRegionIterator = matchedRegions.iterator();
               while (matchedRegionIterator.hasNext()) {
                   Region region = matchedRegionIterator.next();
                   MonitorState state = monitoredRegionState.get(region);
//                 if (state.markInside()) {
//                        state.getCallback().call(IBeaconService.this, "monitoringData", new MonitoringData(state.isInside(), region));
//                 }
               }

               Log.d(TAG, "looking for ranging region matches for this ibeacon");
               matchedRegions = matchingRegions(iBeacon, rangedRegionState.keySet());
               matchedRegionIterator = matchedRegions.iterator();
               while (matchedRegionIterator.hasNext()) {
                   Region region = matchedRegionIterator.next();
                   Log.d(TAG, "matches ranging region: "+region);
                   RangeState rangeState = rangedRegionState.get(region);
                   rangeState.addIBeacon(iBeacon);                 
               }

           }
           //I see a device: 00:02:72:C5:EC:33 with scan data: 02 01 1A 1A FF 4C 00 02 15 84 2A F9 C4 08 F5 11 E3 92 82 F2 3C 91 AE C0 5E D0 00 00 69 C5 0000000000000000000000000000000000000000000000000000000000000000
           //
           // 9: proximityUuid (16 bytes) 84 2A F9 C4 08 F5 11 E3 92 82 F2 3C 91 AE C0 5E
           // 25: major (2 bytes unsigned int)
           // 27: minor (2 bytes unsigned int)
           // 29: tx power (1 byte signed int)          
            return null;
        }      

        @Override
        protected void onPostExecute(Void result) {
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }   

Помогите мне, как отправить сведения о маяках на мой сервер, когда я обнаружил маяки в фоне приложения.

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Хотя вы не показали ни одного кода, который пытается отправить данные на сервер, поскольку вы успешно использовали AsyncTask для обработки данных маяка, вы также можете использовать другой AsyncTask для отправки данных на сервер - принципал такой же.

Пример:

public class AsyncCaller extends AsyncTask<Void, Void, Void> {

    public RestResponseHandler mResponseHandler;
    public String mUrl;
    public String mOperation;
    public String mRequestBody;
    public Map<String,String> mRequestHeaders;
    Map<String,List<String>> mResponseHeaders;
    int mResponseCode;
    String mResponseBody;
    Exception mException;


    public AsyncCaller prepareCall(String url, String operation, String requestBody, Map<String,String> headers, RestResponseHandler responseHandler) {
        mResponseHandler = responseHandler;
        mOperation = operation;
        mRequestBody = requestBody;
        mUrl = url;
        mRequestHeaders = mRequestHeaders;
        return this;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mRequestActive = true;
    }

    @Override
    protected Void doInBackground(Void... params) {
        Log.d(TAG, "start doInBackground");

        mException = null;
        try {
            sendRequest();
        }
        catch (Exception e) {
            Log.e(TAG, "Cannot send request", e);
            mException = new Exception("Cannot send request", e);
        }
        Log.d(TAG, "finish doInBackground");
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        Log.d(TAG, "start onPostExecute");
        super.onPostExecute(result);
        mRequestActive = false;
        if (mResponseHandler != null) {
            if (mException != null) {
                mResponseHandler.onFail(mException);
            }
            else {
                mResponseHandler.onResponse(mResponseCode, mResponseHeaders, mResponseBody );
            }
        }
        Log.d(TAG, "finish onPostExecute");
    }

    public void sendRequest() throws Exception {
        StringBuilder responseBuilder = new StringBuilder();
        HttpURLConnection conn = null;
        URL url = new URL(mUrl);
        mResponseCode = -1;
        mResponseBody = null;
        mResponseHeaders = null;
        Log.d(TAG, "calling service at " + mUrl);
        conn = (HttpURLConnection) url.openConnection();
        for (String headerKey : mRequestHeaders.keySet()) {
            conn.addRequestProperty(headerKey, mRequestHeaders.get(headerKey));
        }
        conn.setRequestMethod(mOperation.toUpperCase());
        if (mRequestBody != null) {
            OutputStream out = conn.getOutputStream();
            try {
                Writer writer = new OutputStreamWriter(out, "UTF-8");
                Log.d(TAG, "posting: " + mRequestBody);
                writer.write(mRequestBody);
                writer.close();
            } finally {
                if (out != null) {
                    out.close();
                }
            }
        }
        mResponseCode = conn.getResponseCode();
        mResponseHeaders = conn.getHeaderFields();


        Log.d(TAG, "response code is " + conn.getResponseCode());
        BufferedReader in = null;
        try {
            if (mResponseCode >= 200 && mResponseCode <= 299) {
                in = new BufferedReader(
                        new InputStreamReader(
                                conn.getInputStream())
                );

            }
            else {
                in = new BufferedReader(
                        new InputStreamReader(
                                conn.getErrorStream()
                        )
                );

            }
            String inputLine;
            while ((inputLine = in.readLine()) != null)
                responseBuilder.append(inputLine);
            in.close();
            Log.d(TAG, "response is " + responseBuilder.toString());
            mResponseBody = responseBuilder.toString();
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }
}

public interface RestResponseHandler {
    public void onFail(Exception e);
    public void onResponse(int httpStatus, Map<String,List<String>> headers, String body);
}

Затем вы можете вызвать его с помощью:

    mAsyncCsller = new AsyncCaller();
    mAsyncCaller.mUrl = "https://myserver.ner/path";
    mAsyncCaller.mOperation = "POST";
    mAsyncCaller.mRequestBody = "{\uuid\":\""+beacon.getId1()+"\"}";
    mAsyncCaller.mRequestHeaders = new HashMap<String,String>();
    mAsyncCaller.mResponseHandler = null;
    mAsyncCaller.execute(null, null, null);

Будьте осторожны, чтобы не посылать данные на сервер слишком часто.Вызов сервера может занять одну секунду или более, и маяки могут обнаруживаться чаще, чем это.Если вы отправляете данные слишком часто, у вас закончатся потоки и вы перегружаете свой сервер.Рассмотрите возможность пакетной обработки вызовов, чтобы на сервер отправлялось, скажем, каждые 60 секунд несколько обнаружений маяков.

0 голосов
/ 04 октября 2018

Прежде всего, AsyncTask нужен поток пользовательского интерфейса для работы, вы можете использовать любые другие потоки API: HandlerThread , пользовательский обработчик , ExecutorService или простонормальная нить.Вы можете прочитать более подробную информацию из здесь и здесь .

Еще один FYI, чтобы обнаружить маяк из фона Я надеюсь, что вы не используете нормальное обслуживание, это может привести к вампроблемы на устройствах Oreo и выше.Пожалуйста, используйте foregroundService вместо этого.Читайте об услугах здесь и причинах этого от здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...