android - 停止运行的前台服务

标签 android android-service

我在编写的应用程序中遇到问题。该应用程序应将网络数据 - lac、小区 ID 和接收功率记录到一个文件中,只要其中一个发生变化。要在应用程序未聚焦或设备休眠时继续录制,我使用了前台服务。屏幕一熄灭,我的服务就停止录制。屏幕亮起时会继续录制。

这是我的代码: 用于调用服务 -

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 以及 samsung S3 mini 和 android 4.1。他们都有相同的行为。

谢谢!

最佳答案

您可能需要从 PowerManager 中获取 PARTIAL_WAKE_LOC

Wake lock level: Ensures that the CPU is running; the screen and keyboard backlight will be allowed to go off.

If the user presses the power button, then the screen will be turned off but the CPU will be kept on until all partial wake locks have been released.

你的 onStartCommand 中的伪代码......

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 中(或当您完成前台操作时)执行:

 wl.release();

可能发生的情况是设备的 CPU 也将休眠 ;)

关于android - 停止运行的前台服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22440662/

相关文章:

java - Android 中使用 PhoneGap 的异步任务

android - 视差和引脚折叠模式在折叠工具栏布局中不起作用

安卓 : Stopping a Bonjour service left running after the parent process quit abrubtly

android - 在 Android 中实现与多个设备的蓝牙连接的最佳方法是什么?

android - 如何知道一天在android中何时开始?

android - 通过Android后台服务Kotlin轮询在线打印机队列

android - 无法使用来自 sdcard 的 webview 以 html 格式播放视频

android - 发布有排行榜但没有成就的 Android 应用程序

android - Listview的onclick如何调用另一个activity?

java - 将音频录制为 Android 服务并使用计时器停止它。录音时长不一,服务似乎没有停止