2013-03-19 178 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(); 
//... 

現在我介紹了一個通知,這不得不讓用戶知道狀態是記錄本身的東西,因爲如果你去家裏或打後退按鈕,它必須保持記錄。因此,如果您點擊通知,則可以將回覆到應用

這就是我掙扎的地方,如果我點擊通知,我會回到應用程序,但一切都設置爲初始狀態(定時器回到00:00:00,我可以再次點擊記錄按鈕而不是暫停按鈕)我當然應該完成是當然它保持記錄,我可以看到正在進行的計時器+停止按鈕。注意:計時器現在不是服務..任何想法我應該如何處理?

編輯

假設我關閉應用程序下來,服務仍在運行。重新打開我們可以做的應用程序(因此活動在服務最初是從所謂的):

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; 
    } 

所以我部分有涉及,但是,現在從服務傳遞給該活動的變量都沒有了。似乎我的活動中的Handler在重新打開該Activity後沒有選擇它們?

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); 

     }; 
    }; 

//編輯

片段:

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); 
    } 



} 

// SERVICE

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

更新了我的問題,得到了一個解決方案,但從服務傳遞的變量是重新打開活動後沒有拿起.. – 2013-03-19 11:22:48

+1

「一切都設置爲初始狀態」,什麼是在你的onPause和onResume ? – StarPinkER 2013-03-19 13:13:10

+0

我有一個片段着手的,其中該命令來自何方,來自活性,並且在該片段我只有一個的onPause:@覆蓋 \t公共無效的onPause(){ \t \t super.onPause(); (mRecorder!= null){ \t \t \t mRecorder.release();如果(mRecorder!= null){ \t \t if \t \t \t mRecorder = null; \t \t} – 2013-03-19 13:31:38

回答

1

首先,你並不需要檢查,如果你的Service通過運行一些ActivityManager方法。如果您在onResume()中撥打startService() && bindService(),則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); 
} 

現在,讓我們說你的服務已經在運行,你想獲得它的正確的價值觀。在你ServiceConnection()onServiceConnected()方法,你可以調用一個方法,像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有足夠的記憶。您必須有一段代碼,您可以在其中調用myService.stopService(),否則,該服務將運行很長時間。

+0

謝謝@tolgap!我今天晚上會潛入,並會回到你身邊! – 2013-03-20 09:13:45

+0

您好@tolgap,我試圖修復我的錯誤與您的建議(我編輯我的問題與我有),但我不斷收到錯誤:IllegalStateException在(RecordService.java:106)只要我想開始錄製。我不知道我的代碼的一般結構是否正確,你可能有一個想法?謝謝! – 2013-03-24 18:05:20

+0

@MatthiasVanb服務的全部要點是它在後臺進程上運行。你不需要爲所有事情啓動新的Runnables。其次,您可以在應用程序運行後立即啓動服務,並使用Fragment中Service的getter和setter開始記錄並獲取其數據。 – tolgap 2013-03-24 19:46:07