Использование RunOnUI для передачи данных из службы в действие

#android #service #google-glass

#Android #Обслуживание #google-glass

Вопрос:

Здесь нужна небольшая помощь, я пытаюсь создать сервис, который использует микрофон для прослушивания пиков звуковой частоты. Эта служба должна работать в фоновом режиме и обновлять пользовательский интерфейс информацией о частоте, когда есть пик. В настоящее время приложение запускается, а затем FC из-за того, что кажется, что у него заканчивается память. Я пробовал отлаживать и следить за потоками, но я новичок в этом и, похоже, не могу понять, что я делаю неправильно.

Вот моя активность:

 public class RTAactivity extends Activity  {

    private static final String TAG = "RtaTest";
    private Intent intent;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.rta_view);

        intent = new Intent(this, AnalyzeService.class);

    }
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            android.os.Debug.waitForDebugger();  // check logcat 
            updateUI(intent);       
        }
    };    

    @Override
    public void onResume() {
        super.onResume();       
        startService(intent);
        registerReceiver(broadcastReceiver, new IntentFilter(AnalyzeService.ANALYZE_ACTION));
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(broadcastReceiver);
        stopService(intent);        
    }   
    private void updateUI(Intent intent) {
        String freq = intent.getStringExtra("freq"); 
        String dB = intent.getStringExtra("dB");
        Log.d(TAG, freq);
        Log.d(TAG, dB);

        TextView TVfreq = (TextView) findViewById(R.id.tv_freq);    
        TextView decibels = (TextView) findViewById(R.id.tv_decibels);
        TVfreq.setText(freq);
        decibels.setText(dB);
    }
}
  

и вот сервис:

 public class AnalyzeService extends Service {
private static final String TAG = "AnalyzerService";
public static final String ANALYZE_ACTION =     "com.kjacksonmusic.glassrta.displayevent";
private final Handler handler = new Handler();
Intent intent;



@Override
public void onCreate() {
    super.onCreate();

    intent = new Intent(ANALYZE_ACTION);    
}

 @Override
    public void onStart(Intent intent, int startId) {
        handler.removeCallbacks(RunOnUI);    //sendUpdatestoUI
        handler.postDelayed(RunOnUI, 500); // 0.5 second

    }
 private Runnable RunOnUI = new Runnable() {
        public void run() {
            //android.os.Debug.waitForDebugger();  // check logcat 
            DisplayAudioInfo();     
            handler.postDelayed(this, 1000); // 1 seconds
        }
    };    

    private void DisplayAudioInfo() {
       Log.d(TAG, "entered DisplayAudioInfo");
       int frequency;
       AudioRecord recorder;
       boolean recording;                       
       int numCrossing,p;
       short audioData[];   

int bufferSize = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT)*3; //get the buffer size to use with this audio record

recorder = new AudioRecord (AudioSource.MIC,8000,AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,bufferSize); //instantiate the AudioRecorder 

recording=true; //variable to use start or stop recording
audioData = new short [bufferSize]; //short array that pcm data is put into.


while (recording) {  //loop while recording is needed
    if (recorder.getState()==android.media.AudioRecord.STATE_INITIALIZED) // check to see if the recorder has initialized yet.
    if (recorder.getRecordingState()==android.media.AudioRecord.RECORDSTATE_STOPPED)
          recorder.startRecording();  //check to see if the Recorder has stopped or is not recording, and make it record.

    else {

    recorder.read(audioData,0,bufferSize); //read the PCM audio data into the audioData array

    //Now we need to decode the PCM data using the Zero Crossings Method

      numCrossing=0; //initialize your number of zero crossings to 0

      for (p=0;p<1000;p =4) {
             if (audioData[p]>0 amp;amp; audioData[p 1]<=0) numCrossing  ;
              if (audioData[p]<0 amp;amp; audioData[p 1]>=0) numCrossing  ;
              if (audioData[p 1]>0 amp;amp; audioData[p 2]<=0) numCrossing  ;
              if (audioData[p 1]<0 amp;amp; audioData[p 2]>=0) numCrossing  ;
              if (audioData[p 2]>0 amp;amp; audioData[p 3]<=0) numCrossing  ;
              if (audioData[p 2]<0 amp;amp; audioData[p 3]>=0) numCrossing  ;
              if (audioData[p 3]>0 amp;amp; audioData[p 4]<=0) numCrossing  ;
              if (audioData[p 3]<0 amp;amp; audioData[p 4]>=0) numCrossing  ;
              }//for p

        for (p=(bufferSize/4)*4;p<bufferSize-1;p  ) {
              if (audioData[p]>0 amp;amp; audioData[p 1]<=0) numCrossing  ;
              if (audioData[p]<0 amp;amp; audioData[p 1]>=0) numCrossing  ;
              }


        frequency=numCrossing*4;
        intent.putExtra("freq", frequency);
        intent.putExtra("dB", 100);  ///place holder for now. 
        sendBroadcast(intent);  


                 }//else recorder started

    } //while recording

    if (recorder.getState()==android.media.AudioRecord.RECORDSTATE_RECORDING) recorder.stop(); //stop the recorder before ending the thread
    recorder.release(); //release the recorders resources
    recorder=null; //set the recorder to be garbage collected.
        } // run


    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {       
        handler.removeCallbacks(RunOnUI);       //sendUpdatesToUI
        super.onDestroy();
    }    

}
  

ВЫВОД LOGCAT:

 06-25 21:54:20.380: I/ActivityManager(3122): START u0 {cmp=com.kjacksonmusic.glassrta/.RTAactivity} from pid 21580

06-25 21:54:20.458: W/Resources(3122): Converting to boolean: TypedValue{t=0x3/d=0x208 "res/anim/accelerate_interpolator.xml" a=1 r=0x10a0005}

06-25 21:54:20.607: I/SystemUpdateService(3573): cancelUpdate (empty URL)

06-25 21:54:20.716: I/SystemUpdateService(3573): cancelUpdate (empty URL)

06-25 21:54:20.833: I/ActivityManager(3122): Displayed 
com.kjacksonmusic.glassrta/.RTAactivity:  359ms

06-25 21:54:21.107: D/AnalyzerService(21580): entered DisplayAudioInfo

06-25 21:54:35.161: I/PowerManagerService(3122): Going to sleep due to screen timeout...

06-25 21:54:35.442: D/SurfaceFlinger(120): Screen released, type=0 flinger=0xb882c450

06-25 21:54:35.521: I/WindowManager(3122): Screen turned off...

06-25 21:54:35.614: I/HeadGestureManager(3122): Unregistering listener: 
com.google.android.glass.server.SystemServerHub$4@20ecfce0 for head gesture: NUDGE

06-25 21:54:35.614: D/HeadGestureContainer(3122): Stopping detector: com.google.android.glass.head.HeadNudgeUpDetector@20ec8be8 name=NUDGE

06-25 21:54:35.622: D/RunnableDetector(3122): run() is exiting!

06-25 21:54:35.622: I/MPL-storeload(3122): mpl state size = 5584

06-25 21:54:35.630: E/MPL-storeload(3122): calData from inv_save_mpl_states, size=2

06-25 21:54:35.630: I/MPL-storeload(3122): cal data size to write = 5584

06-25 21:54:35.630: I/MPL-storeload(3122): Bytes written = 5584

06-25 21:54:35.638: I/HeadGestureManager(3122): Registering listener: com.google.android.glass.server.SystemServerHub$4@20ecfce0 for head gesture: GLOBAL_LOOK_UP

06-25 21:54:35.638: V/GlassInputHub(3122): Cancelling all event sequences.

06-25 21:54:35.638: V/GlassInputHub(3122): Cancelling event sequence: Camera key.

06-25 21:54:35.638: V/GlassInputHub(3122): Cancelling event sequence: Power key.

06-25 21:54:35.638: V/GlassInputHub(3122): Cancelling event sequence: Viewfinder switch.

06-25 21:54:35.638: V/GlassInputHub(3122): Cancelling event sequence: Touchpad.

06-25 21:54:35.708: I/VoiceEngine[20e0026c](3363): Screen is off and current config does not allow screen off.

06-25 21:54:35.724: W/VoiceEngine[20e0026c](3363): Transition to VoiceConfig [] requested, but already in that config.

06-25 21:54:35.817: I/GlassUserEventService[20dd9364](3708): Performance stats: [object: com.google.common.logging.GlassExtensionsNano$GlassUserEventPerformanceStats {   
batteryChargeWhenFullUah_: 403000    totalKernelMs_: 62401830    totalBytesSent_: 123808401    bitField0_: 8191    boardTemperatureMilliCentigrade_: 43810    frequencyScalingGovernor_: 0    availableMemoryKb_: 49148    isLowMemory_: false    qpassedFractional_: 13445    qpassedInteger_: 16636    reportedSoc_: 95    batteryTemperatureMilliCentigrade_: 28100    batteryStateOfChargeUah_: 380000    totalMemoryKb_: 596116    unknownFieldData: null    cachedSize: -1}]

06-25 21:54:36.028: W/ActivityManager(3122): Activity pause timeout for ActivityRecord{20ede224 u0 com.kjacksonmusic.glassrta/.RTAactivity t1}

06-25 21:54:39.560: I/GCM(3573): GCM message com.google.glass.home 0:1403747679192023%0#71a16bb9f9fd7ecd

06-25 21:54:39.622: D/ConnectivityService(3122): reportNetworkCondition(1, 100)

06-25 21:54:39.630: D/ConnectivityService(3122): handleInetConditionChange: net=1, condition=100,mActiveDefaultNetwork=1

06-25 21:54:39.630: D/ConnectivityService(3122): handleInetConditionChange: starting a change hold

06-25 21:54:39.669: V/GCMBroadcastReceiver(3321): onReceive: 
com.google.android.c2dm.intent.RECEIVE

06-25 21:54:39.669: V/GCMBroadcastReceiver(3321): GCM IntentService class: com.google.glass.home.GCMIntentService

06-25 21:54:39.669: V/GCMBaseIntentService(3321): Acquiring wakelock

06-25 21:54:39.677: V/GCMBaseIntentService(3321): Intent service name: GCMIntentService-229668747847-712

06-25 21:54:39.685: I/GCMIntentService(3321): Received message: Bundle[{p=timeline_sync, from=229668747847, collapse_key=do_not_collapse}]

06-25 21:54:39.763: V/GCMBaseIntentService(3321): Releasing wakelock

06-25 21:54:39.778: I/SyncHelper(3321): Requesting sync 

[authority=com.google.glass.sync.timeline, syncSource=GCM,
extras=Bundle[{ignore_backoff=true}]].

06-25 21:54:39.872: I/TimelineSyncAdapter(3377): Entering onPerformSync [authority= com.google.glass.sync.timeline, extras=Bundle[{sync_priority=0, ignore_backoff=true}]].

06-25 21:54:39.911: I/DownloadSyncHelper(3377): Fetching unsynced items from server.

06-25 21:54:39.950: I/DownloadSyncHelper(3377): Requesting sync 
[window=TimelineSyncWindow{startTime=1403747642036001, continuationToken=null}].

06-25 21:54:39.989: I/TimelineItemDatabaseHelper(3377): Getting unsynced items with sync protocols: 0, 1

06-25 21:54:40.067: W/GLSUser(3573): GoogleAccountDataService.getToken()

06-25 21:54:40.130: D/ConnectivityService(3122): handleInetConditionHoldEnd: net=1, condition=100, published condition=100

06-25 21:54:40.130: D/ConnectivityService(3122): sendStickyBroadcast: action=android.net.conn.INET_CONDITION_ACTION

06-25 21:54:40.317: I/EyeGestureService(3122): Retrieving persistent state of detection for gesture DON.

06-25 21:54:40.325: I/DownloadSyncHelper(3377): Received items from server [count=1].

06-25 21:54:40.380: I/TimelineProvider(3377): Overwrote timeline item 8a3d2908-437e-47b7-
b985-5c07a99f3e32 because existing modified time (1403742250447) < new modified time (1403747648937)

06-25 21:54:40.505: I/SyncStats(3377): Download api:582969681302 [numFiles=1, totalBytes=2kB, totalDuration=375ms].

06-25 21:54:40.528: W/ActivityManager(3122): Sleep timeout!  Sleeping now.

06-25 21:54:40.911: I/MainTimelineView(3321): New timeline database content loaded; updating views.

06-25 21:54:40.942: I/MainTimelineView(3321): New timeline database content loaded; updating views.

06-25 21:54:46.028: W/ActivityManager(3122): Activity stop timeout for ActivityRecord{20ede224 u0 com.kjacksonmusic.glassrta/.RTAactivity t1}
  

Комментарии:

1. Если возможно, уменьшите размер буфера с 1024 до 2048. Невозможно загрузить большие данные в буфер.

2. Спасибо, журнал опубликован, дайте мне знать, нужно ли вам больше, чем это?

3. Anil я попытался использовать ваши предложения с частотой дискретизации, и он возвращается в logcat: 06-25 22:32:29.052: E / AndroidRuntime(21794): java.lang. Исключение IllegalArgumentException: 2048 Гц не поддерживается частота дискретизации.

4. Я добавлю, что при запуске службы Activity отображается правильно, текстовые представления просто не обновляют то, что когда-либо, а затем перестают отвечать на запросы, и activity, похоже, уничтожается.