Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 停止运行的前台服务_Android_Android Service - Fatal编程技术网

Android 停止运行的前台服务

Android 停止运行的前台服务,android,android-service,Android,Android Service,我正在编写的应用程序有问题。该应用程序应该记录网络的数据-lac、小区Id和接收功率到一个文件中,只要其中一个发生变化。为了在应用程序未聚焦或设备睡眠时继续录制,我使用了foregound服务。屏幕一关闭,我的服务就停止录制。屏幕打开时,录制将恢复 这是我的密码: 谢谢你打电话来- i = new Intent(this, WriteToFileService.class); startService(i); private PhoneStateListener MyServiceListen

我正在编写的应用程序有问题。该应用程序应该记录网络的数据-lac、小区Id和接收功率到一个文件中,只要其中一个发生变化。为了在应用程序未聚焦或设备睡眠时继续录制,我使用了foregound服务。屏幕一关闭,我的服务就停止录制。屏幕打开时,录制将恢复

这是我的密码: 谢谢你打电话来-

i = new Intent(this, WriteToFileService.class);
startService(i);
private PhoneStateListener MyServiceListener;
private TelephonyManager tm;
private int lac ,cellId, signal;
private String phoneState;
private File outFile;
private final static int myID = 10;
//PowerManager.WakeLock wl;

@Override
public int onStartCommand(Intent senderIntent, int flags, int startId) {
    Intent localIntent = new Intent(this, MainActivity.class);
    localIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendIntent = PendingIntent.getActivity(this, 0, localIntent, 0);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setTicker("Starting to record data").setContentTitle("NetInfo").setContentText("Recording data").setWhen(System.currentTimeMillis())
            .setAutoCancel(false).setOngoing(true).setContentIntent(pendIntent).setSmallIcon(R.drawable.hexagon);   //.setPriority(Notification.PRIORITY_HIGH)
    Notification notification = builder.build();
    notification.flags |= Notification.FLAG_NO_CLEAR;       
    startForeground(myID, notification);
    //PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    //wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
    //wl.acquire();

    outFile = new File(getApplicationContext().getFilesDir(), senderIntent.getStringExtra("name"));
    tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    MyServiceListener = new PhoneStateListener() {
        @Override
        public void onCellLocationChanged(CellLocation location){
            super.onCellLocationChanged(location);
            if ((tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_HSDPA) || (tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS)) {
                GsmCellLocation MyLocation = (GsmCellLocation)tm.getCellLocation();
                lac = MyLocation.getLac();
                cellId = MyLocation.getCid();
            }
            if (tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_CDMA) {
                CdmaCellLocation MyLocation = (CdmaCellLocation)tm.getCellLocation();
                lac = 0;
                cellId = MyLocation.getBaseStationId();
            }
            WriteDataToFile(lac, cellId, signal, phoneState);
        }

        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            super.onSignalStrengthsChanged(signalStrength);
            signal = 2 * signalStrength.getGsmSignalStrength() - 113;   
            WriteDataToFile(lac, cellId, signal, phoneState);
        }

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:
                phoneState = "Idle";
                break;
            case TelephonyManager.CALL_STATE_RINGING:
                phoneState = "Ringing";
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                phoneState = "On-going call";
                break;
            default:
                phoneState = "";
                break;
            }
            WriteDataToFile(lac, cellId, signal, phoneState);
        }
    };
    tm.listen(MyServiceListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS | PhoneStateListener.LISTEN_CELL_LOCATION | PhoneStateListener.LISTEN_CALL_STATE);
    return Service.START_STICKY;
  }

private void WriteDataToFile(int lac, int cellId, int signal, String phoneState)
{

    try {
        FileWriter fw = new FileWriter(outFile.getAbsolutePath(), true);
        BufferedWriter bw = new BufferedWriter(fw);         
        bw.append(new SimpleDateFormat("ddMMyyyy_HHmmss").format(Calendar.getInstance().getTime()) + " ");
        bw.append(String.valueOf(lac) + " ");
        bw.append(String.valueOf(cellId) + " ");
        bw.append(String.valueOf(signal) + " ");
        bw.append(phoneState + "\n");           
        bw.close();
    } catch (IOException e) {
        Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
    }
}

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onDestroy() {
    Toast.makeText(getApplicationContext(), "stopped recording", Toast.LENGTH_LONG).show();
    tm.listen(MyServiceListener, PhoneStateListener.LISTEN_NONE);
    //wl.release();
    stopForeground(true);
来自服务的代码-

i = new Intent(this, WriteToFileService.class);
startService(i);
private PhoneStateListener MyServiceListener;
private TelephonyManager tm;
private int lac ,cellId, signal;
private String phoneState;
private File outFile;
private final static int myID = 10;
//PowerManager.WakeLock wl;

@Override
public int onStartCommand(Intent senderIntent, int flags, int startId) {
    Intent localIntent = new Intent(this, MainActivity.class);
    localIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendIntent = PendingIntent.getActivity(this, 0, localIntent, 0);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setTicker("Starting to record data").setContentTitle("NetInfo").setContentText("Recording data").setWhen(System.currentTimeMillis())
            .setAutoCancel(false).setOngoing(true).setContentIntent(pendIntent).setSmallIcon(R.drawable.hexagon);   //.setPriority(Notification.PRIORITY_HIGH)
    Notification notification = builder.build();
    notification.flags |= Notification.FLAG_NO_CLEAR;       
    startForeground(myID, notification);
    //PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    //wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
    //wl.acquire();

    outFile = new File(getApplicationContext().getFilesDir(), senderIntent.getStringExtra("name"));
    tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    MyServiceListener = new PhoneStateListener() {
        @Override
        public void onCellLocationChanged(CellLocation location){
            super.onCellLocationChanged(location);
            if ((tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_HSDPA) || (tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS)) {
                GsmCellLocation MyLocation = (GsmCellLocation)tm.getCellLocation();
                lac = MyLocation.getLac();
                cellId = MyLocation.getCid();
            }
            if (tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_CDMA) {
                CdmaCellLocation MyLocation = (CdmaCellLocation)tm.getCellLocation();
                lac = 0;
                cellId = MyLocation.getBaseStationId();
            }
            WriteDataToFile(lac, cellId, signal, phoneState);
        }

        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            super.onSignalStrengthsChanged(signalStrength);
            signal = 2 * signalStrength.getGsmSignalStrength() - 113;   
            WriteDataToFile(lac, cellId, signal, phoneState);
        }

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:
                phoneState = "Idle";
                break;
            case TelephonyManager.CALL_STATE_RINGING:
                phoneState = "Ringing";
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                phoneState = "On-going call";
                break;
            default:
                phoneState = "";
                break;
            }
            WriteDataToFile(lac, cellId, signal, phoneState);
        }
    };
    tm.listen(MyServiceListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS | PhoneStateListener.LISTEN_CELL_LOCATION | PhoneStateListener.LISTEN_CALL_STATE);
    return Service.START_STICKY;
  }

private void WriteDataToFile(int lac, int cellId, int signal, String phoneState)
{

    try {
        FileWriter fw = new FileWriter(outFile.getAbsolutePath(), true);
        BufferedWriter bw = new BufferedWriter(fw);         
        bw.append(new SimpleDateFormat("ddMMyyyy_HHmmss").format(Calendar.getInstance().getTime()) + " ");
        bw.append(String.valueOf(lac) + " ");
        bw.append(String.valueOf(cellId) + " ");
        bw.append(String.valueOf(signal) + " ");
        bw.append(phoneState + "\n");           
        bw.close();
    } catch (IOException e) {
        Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
    }
}

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onDestroy() {
    Toast.makeText(getApplicationContext(), "stopped recording", Toast.LENGTH_LONG).show();
    tm.listen(MyServiceListener, PhoneStateListener.LISTEN_NONE);
    //wl.release();
    stopForeground(true);
当然,
OnDestroy()
stopForeground(true)结尾
在某个阶段,当服务被销毁时,我在文件中添加了一条消息,但它只发生了一次——当我结束服务时,所以我确信它没有被操作系统杀死。
有没有办法用前台服务实现这一点,或者我应该尝试另一种方法

我已经在两种不同的设备上试用过了——LG P500和android 2.2,三星S3 mini和android 4.1。他们两人都有同样的行为


谢谢

您可能需要从

唤醒锁定级别:确保CPU正在运行;屏幕和键盘背光将允许熄灭

如果用户按下电源按钮,则屏幕将关闭,但CPU将保持打开,直到所有部分唤醒锁释放

OnStart命令中的伪代码

startForeground(myID, notification);
...

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOC, "My Tag");
wl.acquire();
return Service.START_STICKY;
在您的服务onDestroy中(或当您完成前台操作时),执行以下操作:


可能发生的情况是设备的CPU也将进入睡眠状态;)

谢谢,我试试看。我只是想,由于设备即使在睡眠时也会监听网络事件,因此我的服务将不断获得更新。不,它仍然会在设备睡眠时停止录制,并在设备醒来时恢复。我只在我的LG上测试过。明天我将在S3 mini上测试它,但我有点怀疑。好吧,在这种情况下,你可能想告诉我们你在做什么/什么/谁,因为我认为问题不在于你的服务本身。@MartinMarconcini这个问题出现在一些设备上,而不是所有设备上。例如,在三星j5 api24中,NeigeOS可以正常工作。但不是在
荣誉8-24
中。感谢分享链接,我将对此进行研究。@Mehran请记住,文档中说明了特定的供应商实施(换句话说,每个供应商可能会修改某些行为…)。这是一个坏主意(我责怪谷歌),但请记住这一点。并非所有设备都是平等创建的:/