#java #android #android-service
#java #Android #android-сервис
Вопрос:
Я недавно (пару дней назад) начал работать на JAVA, поэтому я почти уверен, что совершаю некоторые основные ошибки.
Я создал действие, которое с помощью кнопки запускает службу, которая записывает аудио. В нем я добавил таймер, который останавливает запись и завершает работу службы через stopself(). Надеюсь, это правильный способ закрыть его.
Но, когда я запускаю приложение, оно генерирует более одного аудиофайла за период записи (я установил его на 90 МИНУТ), И они обрезаются необоснованным образом (некоторые из них составляют 30 минут, некоторые 20 минут и т. Д.). и иногда служба, похоже, не останавливается.
Мой класс обслуживания:
@SuppressLint("SimpleDateFormat")
public class myservice extends Service {
private MediaRecorder myRecorder;
private String outputFile = null;
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
// super.onCreate(); (not sure about this one)
SimpleDateFormat s = new SimpleDateFormat("ddMMyyyy_hhmmss");
String format = s.format(new Date());
outputFile = Environment.getExternalStorageDirectory().
getAbsolutePath() "/" format ".3gpp";
myRecorder = new MediaRecorder();
myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myRecorder.setOutputFile(outputFile);
try {
myRecorder.prepare();
myRecorder.start();
} catch (IllegalStateException e) {
// start:it is called before prepare()
// prepare: it is called after start() or before setOutputFormat()
e.printStackTrace();
} catch (IOException e) {
// prepare() fails
e.printStackTrace();
}
Timer myTimer;
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
try {
myRecorder.stop();
myRecorder.reset();
myRecorder.release();
myRecorder = null;
stopSelf();
//onDestroy(); I added this one to test it out. not sure.
} catch (IllegalStateException e) {
// it is called before start()
e.printStackTrace();
} catch (RuntimeException e) {
// no valid audio/video data has been received
e.printStackTrace();
}
}
}, 60000 * 90); //90 minutes timer to stop the recording after 90 minutes
}
public int onStartCommand(Intent intent, int flags, int startId) {
//onCreate();
// return 1;
return START_STICKY; //not sure about this one
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
//what about this one ?
// @Override
// public void onDestroy() {
// myRecorder.stop();
// myRecorder.reset();
// myRecorder.release();
//}
}
Моя основная деятельность:
public class MainActivity extends Activity {
private Button startBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startBtn = (Button)findViewById(R.id.start);
startBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent svc=new Intent(getBaseContext(), myservice.class);
startService(svc);
finish(); //because I want to close the UI after service started
}
});
}
}
Перед использованием служб Android я написал приложение с использованием потоков. Это сработало, но таймер работал только в течение коротких периодов, 10 минут или меньше). Запись звука остановилась в какой-то момент (обычно 30 минут или намного меньше), и эта продолжительность не была фиксированной (хотя таймер был установлен на 90 минут). До сих пор не знаю почему, но я предположил, что ОС Android отключает поток из-за нехватки ресурсов.
Помощь была бы очень признательна.
Ответ №1:
Поскольку я решил это, я публикую свое решение, если кто-то сталкивается с подобными проблемами. По-видимому, службы (когда они неактивны [без взаимодействия] около 30 минут) также могут быть закрыты ОС Android. Что мне было нужно, так это служба переднего плана. Пример из официальной документации:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);