唤醒锁和wifilock不起作用 [英] Wakelock and wifilock not working

查看:103
本文介绍了唤醒锁和wifilock不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在此处阅读了很多有关WakeLock和WifiLock的用法的教程和文章,但仍然没有解决我的问题的方法.

I have read plenty of tutorial and posts here on SO regarding the use of WakeLock and WifiLock, but still didn't get to a solution of my issue.

我正在编写一个具有启动和启动(前景)服务的唯一效果的应用程序.该服务运行两个线程,分别是UDP广播侦听器(使用java.io)和TCP服务器(使用java.nio).在服务的onCreate中,我获得了唤醒锁和wifilock,然后将它们释放到onDestroy中.

I'm writing an app that has, when you start it, the only effect of creating and starting a (foreground) service. This service run two threads that are an UDP broadcast listener (using java.io) and a TCP server (using java.nio). In the onCreate of the service I acquire a wakelock and a wifilock, and I release them in the onDestroy.

只要手机处于唤醒状态,一切都可以正常工作,但是当显示器关闭时,UDP广播接收器将停止接收广播消息,并且在我再次打开显示器之前不会接收任何消息.实际上,这些锁根本不起作用,并且放它们也没有区别...我在哪里错了?我确定我在某处做某件事很愚蠢,但我自己找不到.

Everything works fine as far as the phone is awake, but when the display goes off the UDP broadcast receiver stops receiving broadcast messages, and will not receive any until I switch on again the display. Practically, the locks are not working at all and there is no difference in put them...where am I wrong? I'm sure I'm doing something stupid somewhere, but can't find it by myself.

这是一些代码:

这是活动的作用:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    onlyStartService = true;
}@Override
protected void onStart() {
    super.onStart();
    Intent bIntent = new Intent(this, FatLinkService.class);
    getApplicationContext().startService(bIntent);
    getApplicationContext().bindService(bIntent, flConnection, BIND_AUTO_CREATE);
} 
// service connection to bind idle service
private ServiceConnection flConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder binder) {
       linkService.MyLinkBinder flBinder = (LinkService.MylinkBinder) binder;
       flServiceInstance = flBinder.getService();
       if (onlyStartService) {
           condLog("Service bound and finishing activity...");
           finish();
       }
    }
    public void onServiceDisconnected(ComponentName className) {
        flServiceInstance = null;
    }
}; 
@Override
protected void onStop() {
    super.onStop();

    if (fatFinish) {
        Intent bIntent = new Intent(this, FatLinkService.class);
        flServiceInstance.stopServices();
        flServiceInstance.stopForeground(true);
        flServiceInstance.stopService(bIntent);
        condLog("Service stop and unbound");
        flServiceInstance = null;
    }
    getApplicationContext().unbindService(flConnection);
}

服务方式如下:

public class LinkService extends Service {
    InetAddress iaIpAddr, iaNetMask, iaBroadcast;
    private final IBinder mBinder = new MyLinkBinder();
    private linklistenBroadcast flBroadServer = null;
    private linkTCPServer flTCPServer = null;
    private linkUDPClient flBroadClient = null;
    List<String> tokens = new ArrayList<String>();
    private PowerManager.WakeLock wakeLock;
    private WifiManager.WifiLock wifiLock;

public class MylLinkBinder extends Binder {
    lLinkService getService() { return LinkService.this; }
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

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

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{        
    instantiateServices();
    // notifies presence to other fat devices
    condLog("Service notifying fat presence...");
    flBroadClient = new LinkUDPClient();
    flBroadClient.startSending(LinkProtocolConstants.BRCMD_PRESENCE + String.valueOf(LinkProtocolConstants.tcpPort), iaBroadcast, LinkProtocolConstants.brPort);
    return START_STICKY;
}

public void getLocks() {
    // acquire a WakeLock to keep the CPU running
    condLog("Acquiring power lock");
    WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL , "MyWifiLock");
    wifiLock.acquire();
    PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
    wakeLock.acquire();
}

public void stopServices() {
    if (flTCPServer != null)
        flTCPServer.stopServer();
    if (flBroadServer != null)
        flBroadServer.stopSelf();
}

private void instantiateServices() {
    populateAddresses(); // just obtain iaIpAddr  
    if (flTCPServer == null) {
        condLog("Instantiating TCP server");
        flTCPServer = new LinkTCPServer(iaIpAddr, FatLinkProtocolConstants.tcpPort);
        flTCPServer.execute();
    }
    if (flBroadServer == null) {
        condLog("Instantiating UDP broadcast server");
        Intent notifyIntent = new Intent(this, LinkMain.class); // this is the main Activity class
        notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        notifyIntent.setAction("FROM_NOTIFICATION");
        PendingIntent notifyPIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0);

        Notification fixNotification = new Notification.Builder(getApplicationContext())
                .setContentTitle("Link")
                .setSmallIcon(R.mipmap.imgLink)
                .setContentIntent(notifyPIntent)
                .build();
        startForeground(1234, fixNotification);
        flBroadServer = new LinklistenBroadcast();
        flBroadServer.start();
    }
}

private final class LinklistenBroadcast extends Thread {
    private boolean bStopSelf = false;
    DatagramSocket socket;
    public void stopSelf() {
        bStopSelf = true;
        socket.close();
    }

    @Override
    public void run() {
        condLog( "Listening broadcast thread started");
        bStopSelf = false;
        try {
        //Keep a socket open to listen to all the UDP trafic that is destinated for this port
        socket = new DatagramSocket(null);
        socket.setReuseAddress(true);
        socket.setSoTimeout(LinkGeneric.BR_SOTIMEOUT_MILS);
        socket.setBroadcast(true);
        socket.bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), FatLinkProtocolConstants.brPort));
        while (true) {
                condLog("Ready to receive broadcast packets...");
                //Receive a packet
                byte[] recvBuf = new byte[1500];

                DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
                try {
                    socket.receive(packet);
                } catch (InterruptedIOException sException) {
                    condLog(sockExcept.toString());
                    break;
                } catch (SocketException sockExcept) {
                   condLog(sockExcept.toString());
                }
                if (bStopSelf) {
                    condLog("Broadcast server stopped...");
                    break;
                }
                int len = packet.getLength();
                String datarecvd = new String(packet.getData()).trim();
                //datarecvd = datarecvd.substring(0, len);
                //Packet received
                String message = new String(packet.getData()).trim();
                condLog("<<< broadcast packet received from: " + packet.getAddress().getHostAddress() + " on port: " + packet.getPort() + ", message: " + message);
                if (packet.getAddress().equals(iaIpAddr)) {
                    condLog("Ooops, it's me! discarding packet...");
                    continue;
                }
                else
                    condLog("<<< Packet received; data size: " + len + " bytes, data: " +  datarecvd);

                //See if the packet holds the right command (message)

                // protocol decode
                // here do some tuff
        } catch (IOException ex) {
            condLog(ex.toString());
        }

        if (socket.isBound()) {
            condLog( "Closing socket");
            socket.close();
        }
        condLog( "UDP server thread end.");
        flTCPServer = null;
        flBroadServer = null;
    }

    public boolean isThreadRunning() {
        return !bStopSelf;
    };
}

// Utility functions
public boolean checkBroadcastConnection (DatagramSocket socket, int timeOutcycles) {
    int tries = 0;
    while (!socket.isConnected()) {
        tries++;
        if (tries >= timeOutcycles)
            return false;
    }
    return true;
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (wakeLock != null) {
        if (wakeLock.isHeld()) {
            wakeLock.release();                
        }
    }
    if (wifiLock != null) {
        if (wifiLock.isHeld()) {
            wifiLock.release();
        }
    }
}

}

最后,这是清单:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="xxxxxx.ink" >
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/imgLinkmascotte"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".LinkMain"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".LinkService" />
    </application>
</manifest>

  • 我已阅读,并且我怀疑问题是否相同,但实际上我尝试过的所有手机(银河Tab 7.1,银河标签10,Galaxy SIII,Galaxy Note 3 Neo,Galaxy SIII mini)都在我身上发生,而Android版本从4.0降到了4.4.

    • I have read this, and I have the doubt the problem is the same but it is actually happening to me on all the phone I have tried (galaxy Tab 7.1, galaxy tag 10, Galaxy SIII, Galaxy Note 3 Neo, Galaxy SIII mini) with android releases from 4.0 to 4.4.

      我已经尝试过在此处发布的解决方案,但是所有更改(再次...是有点令人沮丧).

      I have already tried the solution posted here, but anything changed (again...it is a bit frustrating).

      我什至尝试在所有尝试使用的电话中将待机时保持wifi选项"设置为始终",但仍然没有.

      I have even tried to set the "Keep wifi option in standby" to "Always" in all the phones I've tried, but still nothing.

      我已经研究了WakeFulIntentService类,该类应该像每个人都说的那样工作,但是我看不出代码中有什么显着不同.

      I have studied the WakeFulIntentService class, that is supposed to work as everybody is saying that it is, but I can't see any significant different in my code.

      我真的希望有人能帮助我,自上周以来我真的一直坚持下去.

      I really hope someone can help me, I'm really stuck on this since last week.

      按照waqaslam的回答,我检查了在Wifi先进设置中具有"Wifi优化"选项的设备,并且在我取消选中该选项后,它实际上就可以工作.因此,现在的问题变成了:我可以在高级菜单中未显示该选项的设备中禁用Wifi优化吗?正如我在下面的评论中所写,这似乎与android版本无关,因为我有两个配备4.4.2的设备(均为三星),并且它们均未显示该选项.

      following the waqaslam answer, I have checked on a device that has "Wifi optimisation" option in Wifi-Advaced settings, and it actually works as soon as I uncked the option. So, now, the problem become: can I disable Wifi optimisation in devices that haven't that option shown in the advanced menu? as I wrote below in my comment, this seems not to be related to android release, as I have two devices (both Samsung) with 4.4.2 and they are not showing the option.

      新的从已编辑的waqaslam答案中,我试图将多播锁定添加到我的服务中,但是再次更改了任何内容.这变得很烦人,几乎没有什么事情与android无关.

      New from the edited waqaslam answer, I have tried to add multicastlock to my service, but again anything changed. This is getting annoying, there's hardly something easy and clear to do with android.

      非常感谢你 C.

      推荐答案

      撰写该文章只是为了将帖子标记为已回答.我终于意识到,没有解决方案,或者至少没有解决方案可以在所有带有"所有android发行版(或至少来自JB)的手机上正常工作.

      Writing that just to mark the post as answered. I finally realilzed that there is no solution, or at least there is no solution working well on "all" the phones with "all" the android distribution (or at least from JB).

      考虑到以下几点,我重新解决了我的应用程序的概念,就解决了我的个人问题: -即使在空闲模式下,发送UDP广播也始终有效 -TCP服务器不受WiFi优化的影响.

      I have solved my personal issue just revisiting the concept of my app, considering that: - Sending UDP broadcast is always working even in idle mode - TCP servers are not affected by WiFi optimisation.

      谢谢大家的帮助和建议 C.

      thank you all for the help and suggestion C.

      这篇关于唤醒锁和wifilock不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆