我的应用程序出现问题我正在写作。应用程序应记录网络的数据 - lac,cell 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);
当然,OnDestroy()
以stopForeground(true);
结尾
在服务被销毁时,我在某个阶段向文件添加了一条消息,但它只发生了一次 - 当我结束服务时,所以我确信它没有被操作系统杀死。
有没有办法用前台服务来实现这个,或者我应该尝试不同的方法吗?
我已经在两个不同的设备上试过了 - 带有Android 2.2的LG P500和带有android 4.1的三星S3 mini。他们两个都有相同的行为。
谢谢!
答案 0 :(得分:1)
您可能需要从PowerManager
获取PARTIAL_WAKE_LOC唤醒锁定级别:确保CPU正在运行;屏幕和键盘背光将被允许熄灭。
如果用户按下电源按钮,屏幕将关闭,但CPU将保持打开状态,直到所有部分唤醒锁定都被释放。
onStartCommand中的PseudoCode ......
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也会睡觉;)