2013-03-19 2 views
5

Одна из функций приложения, которое я создаю, имела функцию записи. Я делаю это, начиная объект MediaRecorder в службе:Обслуживание работает в фоновом режиме?

Intent intent = new Intent(v.getContext(), RecordService.class); 
Messenger messenger = new Messenger(handler); 
intent.putExtra("COUNT", basic); 
intent.putExtra("MESSENGER", messenger); 

v.getContext().startService(intent); 

//service 

//... 
mRecorder = new MediaRecorder(); 
//... 

Теперь я представил уведомление, которая должна была дать пользователю понять, что статус самой записи, потому что если вы идете домой или ударить BackButton , он должен вести запись. Поэтому, если вы нажмете уведомление, вы перейдете обратно в приложение.

Вот где я боюсь, если я нажму уведомление, я вернусь к приложению, но все установлено в исходное состояние (Таймер вернулся 00:00:00, и я снова могу нажать кнопку записи вместо кнопки паузы) Что мне нужно выполнить, конечно, что он продолжает запись и что я могу видеть текущую кнопку таймера + стоп. note: Таймер сейчас не является сервисом. Любые идеи, как я должен справиться с этим?

EDIT

Предположим, я закрыл приложение вниз, служба по-прежнему работает. Переоформление приложения (и, следовательно, активности, где служба была первоначально вызывается из) мы можем сделать с:

private boolean isMyServiceRunning() { 
     ActivityManager manager = (ActivityManager) myContext.getSystemService(Context.ACTIVITY_SERVICE); 
     for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 
      if (MyService.class.getName().equals(service.service.getClassName())) { 
       return true; 
      } 
     } 
     return false; 
    } 

Так что отчасти есть, что покрыто, но, переменные, передаваемые от этой службы к этой деятельности в настоящее время нет. Кажется, что мой обработчик в моей деятельности не собирает их после открытия этой активности?

private Handler handler = new Handler() { 
     public void handleMessage(Message message) { 

      //.. 
      Bundle bundle = message.getData(); 
      fileName = bundle.getString("FILENAME"); 
      tvFileName.setText(fileName); 


      Log.e("Filename", "transfered: " + fileName); 

     }; 
    }; 

// EDIT

Фрагмент:

public class LayoutOne extends Fragment implements OnClickListener { 

    //vars 
    @Override 
    public void onPause() { 
     super.onPause(); 
     if (mRecorder != null) { 
      mRecorder.release(); 
      mRecorder = null; 
     } 

     if (mPlayer != null) { 
      mPlayer.release(); 
      mPlayer = null; 
     } 
    } 

    private Handler handler = new Handler() { 
     public void handleMessage(Message message) { 

      int i = message.arg1; 
      Bundle bundle = message.getData(); 
      fileName = bundle.getString("FILENAME"); 
      tvFileName.setText(fileName); 

      Log.e("Handler", "Succesfully transfered: " + (Integer.toString(i))); 
      Log.e("Filename", "Succesfully transfered: " + fileName); 
     }; 
    }; 

    @Override 
    public void onClick(View v) { 

     switch (v.getId()) { 
     case R.id.bRecord: 

      if (mStartRecording) { 
       mStartRecording = false; 
       Intent intent = new Intent(v.getContext(), RecordService.class); 

       Messenger messenger = new Messenger(handler); 
       intent.putExtra("MESSENGER", messenger); 
       v.getContext().startService(intent); 


      } else { 
       mRecordButton.setText("Record"); 
       Intent stopIntent = new Intent(v.getContext(), 
         RecordService.class); 

       try { 
        v.getContext().stopService(stopIntent); 
       } catch (Exception e) { 
        e.printStackTrace(); 

       } 
       mStartRecording = true; 
      } 

      break; 

     case R.id.bStop: 
      Intent stopIntent = new Intent(v.getContext(), RecordService.class); 
      v.getContext().stopService(stopIntent); 
      break; 

     } 
    } 

    public static Fragment newInstance(Context context) { 
     LayoutOne f = new LayoutOne(); 
     return f; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 
     root = (ViewGroup) inflater.inflate(R.layout.layout_one, null); 
     myContext = container.getContext(); 

     //buttons 

     mgr = (NotificationManager) myContext.getSystemService(Context.NOTIFICATION_SERVICE); 
     return root; 
    } 



    public void notifyMe(View v) { 
     Notification note = new Notification(R.drawable.ic_launcher, 
       getString(R.string.notificationbar), System.currentTimeMillis()); 
     PendingIntent i = PendingIntent.getActivity(myContext, 0, new Intent(
       myContext, ViewPagerStyle1Activity.class), 0); 

     note.setLatestEventInfo(myContext, getString(R.string.app_name), 
       getString(R.string.notification), i); 
     note.number = ++count; 
     note.vibrate = new long[] { 500L, 200L, 200L, 500L }; 
     note.flags |= Notification.FLAG_AUTO_CANCEL; 

     mgr.notify(NOTIFY_ME_ID, note); 
    } 

    public void clearNotification(View v) { 
     mgr.cancel(NOTIFY_ME_ID); 
    } 

    // /SHARED PREFERENCES SETTINGS/// 
//… 

    private void initiatePopupWindow() { 
     //.. 
    } 



    @Override 
    public void onResume() { 
     super.onResume(); 
     Intent intent = new Intent(myContext, RecordService.class); 
     myContext.startService(intent); 
     myContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); 
    } 

    private ServiceConnection mServiceConnection = new ServiceConnection() { 
     @Override 
     public void onServiceConnected(ComponentName name, IBinder service) { 
      // TODO Auto-generated method stub 
      LocalBinder binder = (LocalBinder) service; 
       myService = binder.getService(); 
       //myService.setBound(true); 
       initializeUI(); 

     } 

     @Override 
     public void onServiceDisconnected(ComponentName name) { 
      // TODO Auto-generated method stub 

     } 
    }; 

    protected void initializeUI() { 
     //.. 

     } 

    } 

    @Override 
    public void onDestroy() { 
     // TODO Auto-generated method stub 
     myContext.unbindService(mServiceConnection); 
    } 

    @Override 
    public void onStop() { 
     // TODO Auto-generated method stub 
     myContext.unbindService(mServiceConnection); 
    } 



} 

// СЕРВИС

public class RecordService extends Service { 

    //vars 

    public class LocalBinder extends Binder { 
      RecordService getService() { 
       return RecordService.this; 
      } 
     } 

    @Override 
    public void onCreate() { 
     Log.i("Oncreate", "Service onCreate"); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Bundle extras = intent.getExtras(); 
     if (extras != null) { 

      messenger = (Messenger) extras.get("MESSENGER"); 
      count = Integer.toString(extras.getInt("COUNT")); 
      try { 
       Message message = new Message(); 
       int arg = 0; 
       message.arg1 = arg; 

       mFileNamePass=”test”; 
       Bundle bundle = new Bundle(); 
       bundle.putString("FILENAME", mFileNamePass); 
       message.setData(bundle); 
       messenger.send(message); 
      } catch (android.os.RemoteException e1) { 
       Log.w(getClass().getName(), "Exception sending message", e1); 
      } 
     } 
     else { 
      Log.i("Extras","Didn't find extras"); 
     } 

     Runnable r = new Runnable() { 

      @Override 
      public void run() { 
       checkIfFolderExists(); 
       String dateFull = calculateDate(); 
       mFileName = Environment.getExternalStorageDirectory() 
         .getAbsolutePath(); 
       mFileName += "test.3gp"; 

       mRecorder = new MediaRecorder(); 
       mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
       mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
       mRecorder.setOutputFile(mFileName); 
       mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 

       try { 
        mRecorder.prepare(); 
       } catch (IOException e) { 
        Log.e(LOG_TAG, "prepare() failed"); 
       } 

       mRecorder.start(); 
       Log.i("Service", "Service running"); 

      } 
     }; 

     Thread t = new Thread(r); 
     t.start(); 
     return RecordService.START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 

     Runnable stopRecord = new Runnable() { 

      @Override 
      public void run() { 
       mRecorder.stop(); 
       mRecorder.release(); 
       mRecorder = null; 

      } 

     }; 
     Thread stopRecordThread = new Thread(stopRecord); 
     stopRecordThread.start(); 
     Log.i("Service", "Service stopped"); 
     super.onDestroy(); 
    } 

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



} 
+0

Обновлен мой вопрос, получил решение, но переменные, переданные из Сервиса, после повторного открытия Activity не подобраны. –

+1

«все установлено в исходное состояние», что находится в ваших onPause и onResume ? – StarPinkER

+0

У меня есть фрагмент, инициированный, из которого вызывается команда, и в этом фрагменте у меня есть только onPause: @Override \t public void onPause() { \t super.onPause(); \t \t if (mRecorder! = Null) { \t \t \t mRecorder.release(); \t \t \t mRecorder = null; \t \t} –

ответ

1

Прежде всего, вам не нужно, чтобы проверить, если ваш Service запущен, некоторые ActivityManager способ. Если вы звоните startService() && bindService() в свой onResume(), Android достаточно умен, чтобы просто привязываться к Service, если он уже запущен, а если нет, он создаст Service, пройдя через соответствующий документированный жизненный цикл, а затем привязается к нему.

Что вы можете сделать здесь это:

@Override 
public void onResume() { 
    super.onResume(); 
    Intent intent = new Intent(this, YourService.class); 
    startService(intent); 
    bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); 
} 

Теперь, позволяет сказать, что ваша служба уже работает, и вы хотите получить его собственные значения. В onServiceConnected() методе вашего ServiceConnection(), вы можете вызвать метод как initializeUI(), когда связывание сделано:

private ServiceConnection mServiceConnection = new ServiceConnection() { 
    public void onServiceConnected(ComponentName className, IBinder service) { 
     LocalBinder binder = (LocalBinder) service; 
     myService = binder.getService(); 
     myService.setBound(true); 
     initializeUI(); 
    } 

    public void onServiceDisconnected(ComponentName className) { 
    } 
}; 

А теперь у вас есть myService переменную, которая указывает на ваш Service объект, который вы можете позвонить getters на, как myService.getTimer() и myService.isRecording().

public void initializeUI() { 
    timerTextview.setText(myService.getTime()); 
    someOtherUiElement.setText(myService.getSomething()); 
    if(myService.isRecording()) 
     recordButton.setImageResource(R.drawable.pause); 
} //etc... 

Кстати, я не знаю, если вы также изо всех сил держать свою службу, работающую при выходе из приложения Если вы делаете, используя startService(intent) будет держать ваш Service работать до тех пор, как Android имеет достаточно памяти. У вас MUST есть фрагмент кода, в котором вы можете позвонить по номеру myService.stopService(), в противном случае Служба будет работать очень долго.

+0

Спасибо @tolgap! Сегодня вечером я погружусь в него и вернусь к вам! –

+0

Привет @tolgap, я пытался исправить свои ошибки с вашими предложениями (я отредактировал свой вопрос тем, что у меня есть), но я все время получаю ошибку: IllegalStateException at (RecordService.java:106), как только я хочу начать запись. Я не знаю, правильна ли общая структура моего кода, возможно, у вас есть идея? Благодаря! –

+0

@MatthiasVanb Весь смысл Сервиса в том, что он работает на фоновом процессе. Вам не нужно запускать новые Runnables для всего. Во-вторых, вы можете запустить Сервис, как только ваше приложение запустится, и использовать геттеры и сеттеры Сервиса, из вашего фрагмента, чтобы начать запись и получение своих данных. – tolgap

Смежные вопросы