简体   繁体   English

即使手机屏幕关闭,如何保持GPS和插座连接打开?

[英]How to keep GPS and socket connection on even when the mobile screen is off?

Problem: I have to periodically send the GPS data to a server. 问题:我必须定期将GPS数据发送到服务器。

Approach: I have used alarm manager which runs a background service. 方法:我使用了运行后台服务的警报管理器。 It acquires GPS data and sends it over the socket. 它获取GPS数据并通过套接字发送。 It works fine until the screen is on. 直到屏幕打开为止,它都可以正常工作。

Issue: However, when screen turns off, no data is received on the server. 问题:但是,当屏幕关闭时,服务器上没有接收到任何数据。 But as soon as I turn the screen on, the server receives all the data at once. 但是,一旦我打开屏幕,服务器就会立即接收所有数据。

Already tried: I have already tried wakelock but still facing the same problem. 已经尝试过:我已经尝试过唤醒锁,但是仍然面临相同的问题。

Please help me in resolving this issue. 请帮助我解决此问题。

Thanks in advance. 提前致谢。

public class service_task extends Service {

    public static int PORT = 6789;
    public static String IP = "192.168.20.16";
    public PowerManager.WakeLock wl;

    @SuppressLint({"MissingPermission", "InvalidWakeLockTag"})
    @Override
    public void onCreate() {
        PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::service_task");
        wl.setReferenceCounted(true);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }


    private class ServerThread extends Thread implements LocationListener {

        public LocationManager locationManager = null;
        public String msg = "default";
        public String id = "default";
        private Location mLocation = null;
        public Socket socket = null;
        public int serviceid;
        public LocationListener LL;


        public ServerThread(LocationManager locationManager, String id, int serviceid) {
            super("UploaderService-Uploader");
            this.locationManager = locationManager;
            this.id=id;
            this.serviceid=serviceid;
            LL=this;
        }

        @SuppressLint("MissingPermission")
        public void run() {

            wl.acquire();
            Looper.prepare();
            Log.d("func", "Looper");
            this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
            Handler handler=new Handler(Looper.myLooper());
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    Log.d("func", "no GPS data found");
                    locationManager.removeUpdates(LL);
                    Looper.myLooper().quit();
                }
            };
            handler.postDelayed(runnable, 30000);
            Looper.loop();

            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
            String cal = sdf.format(calendar.getTime());

            if (mLocation!=null) {
                msg = id + "    time:" + cal + "    GPS data:" + mLocation;
            }else{
                msg = id + "    time:" + cal + "    No GPS data";
            }
            Log.d("D", msg);
            socket = null;
            SocketAddress address = new InetSocketAddress(IP, PORT);
            socket = new Socket();
            try {
                Log.d("D", "server connected");
                socket.connect(address, 3000);
            } catch (IOException e) {
                Log.d("D","server not connected");
                e.printStackTrace();
            }
            try {
                socket.setSoTimeout(3000);
            } catch (SocketException e) {
                Log.d("socket timeout","server took too long to respond");
                //e.printStackTrace();
            }

            OutputStream out = null;
            try {
                out = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            PrintWriter output = new PrintWriter(out);
            output.print(msg);
            output.flush();
            output.close();
            try {
                socket.close();
                Log.d("D", "server disconnected for "+id);
            } catch (IOException e) {
                e.printStackTrace();
            }
            Log.d("D", "Stopped for "+id);

            wl.release();
            stopSelf(serviceid);
        }

        @Override
        public void onLocationChanged(Location location) {
            Log.d("func", "location changed");
            mLocation = location;
            this.locationManager.removeUpdates(this);
            Looper.myLooper().quit();
        }

        @Override
        public void onStatusChanged(String s, int i, Bundle bundle) {

        }

        @Override
        public void onProviderEnabled(String s) {

        }

        @Override
        public void onProviderDisabled(String s) {

        }

    }

    @SuppressLint("MissingPermission")
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Date currentTime = Calendar.getInstance().getTime();
        IP= intent.getStringExtra("IP");
        PORT= Integer.parseInt(intent.getStringExtra("port"));
        String id= intent.getStringExtra("ID");
        Log.d("func", currentTime+" Started for "+id);
        LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

        ServerThread thread = new ServerThread(locationManager, id, startId);
        thread.start();
        return START_STICKY;
    }
}

When mobile screen is off and if there are no wakelocks pending in device, device CPU will be off, and If device goes to doze mode, there will be further restrictions in device. 当移动屏幕关闭并且设备中没有等待挂起的唤醒锁时,设备CPU将关闭,并且如果设备进入打ze模式,则设备将受到进一步的限制。 And with the Android latest versions there are restrictions on App background behavior and location updates. 而且,随着Android最新版本的发布,应用程序背景行为和位置更新受到限制。 And in the code, you are using deprecated version of Location updates approach. 并且在代码中,您正在使用不推荐使用的位置更新方法。 So the behavior you reported is expected. 因此,您报告的行为是预期的。

There is a google code labs tutorial on location updates, suggesting the correct approach to be followed to receive location updates consistently, please follow that https://codelabs.developers.google.com/codelabs/background-location-updates-android-o 有一个有关位置更新的google代码实验室教程,建议遵循正确的方法来持续接收位置更新,请遵循https://codelabs.developers.google.com/codelabs/background-location-updates-android-o

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM