I have an app that utilises both the camera and a BLE MIDI device. Because it uses a camera it employs a wakelock to keep the screen active when the activity is running.
I also added some logcat messages on the activity's onPause, onResume and onUserLeaveHint methods. The result is the following:
07-15 21:55:15.422 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-15 21:55:15.540 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [wakelock release]
07-15 21:55:15.541 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-15 21:55:15.597 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-15 21:56:16.701 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-15 21:56:16.931 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [wakelock release]
07-15 21:56:16.933 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-15 21:56:17.017 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-15 21:57:18.118 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-15 21:57:18.245 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [wakelock release]
07-15 21:57:18.246 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-15 21:57:18.307 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-15 21:58:55.196 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-15 21:58:55.331 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [wakelock release]
07-15 21:58:55.332 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-15 21:58:55.388 31551-31551/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
For reasons I don't understand, something is causing my activity to pause every minute and then immediately resume.
Although onUseLeaveHint is called prior to onPause the phone is not being touched during this period, it is by itself on my desk with the screen on.
The above is problematic because I have BLE resources and am recording a MIDI file. If I were to close and re-open the MIDI device this often I am concerned it would lead to timing issues in the recording.
Is this normal? If not, any ideas why this is happening?
Here's my Activity:
package uk.co.mxklabs.pianoeye;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import uk.co.mxklabs.androidlib.music.midi.IMidiEventListener;
import uk.co.mxklabs.androidlib.music.midi.SimpleMidiEventAdapter;
public class CameraActivity extends Activity
implements SharedPreferences.OnSharedPreferenceChangeListener
{
private static final String TAG = "mxklogcat";
private PowerManager.WakeLock m_wakeLock;
private SimpleMidiEventAdapter m_midiAdapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
//getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (null == savedInstanceState)
{
getFragmentManager().beginTransaction()
.replace(R.id.container, Camera2VideoFragment.newInstance())
.commit();
}
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
m_wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG);
m_midiAdapter = new SimpleMidiEventAdapter(this.getApplicationContext(), "");
//m_midiAdapter.addMidiEventListener(mSurfaceView);
m_midiAdapter.addMidiEventListener(new IMidiEventListener()
{
@Override
public void noteOn(int channel, int midiNote, int velocity)
{
Log.v(TAG, "Note " + Integer.toString(midiNote) + " on, velocity " + Integer.toString(velocity) + "!");
}
@Override
public void noteOff(int channel, int midiNote, int velocity)
{
Log.v(TAG, "Note " + Integer.toString(midiNote) + " off!");
}
});
}
@Override
public void onResume()
{
Log.v(TAG, "CameraActivity [onResume]");
super.onResume();
m_midiAdapter.onResume();
Log.v(TAG, "WakeLock [wakelock acquire]");
m_wakeLock.acquire();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
//processVideoOverlayTransparencyValue(prefs);
processMidiDevice(prefs);
}
@Override
protected void onUserLeaveHint()
{
Log.v(TAG, "CameraActivity [onUserLeaveHint]");
super.onUserLeaveHint();
}
@Override
public void onPause()
{
Log.v(TAG, "CameraActivity [wakelock release]");
m_wakeLock.release();
Log.v(TAG, "CameraActivity [onPause]");
m_midiAdapter.onPause();
super.onPause();
// TODO: Make consistent pause/onPause.
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState)
{
Log.v(TAG, "CameraActivity [onCreate]");
super.onCreate(savedInstanceState, persistentState);
}
@Override
protected void onStart()
{
Log.v(TAG, "CameraActivity [onStart]");
super.onStart();
}
@Override
protected void onRestart()
{
Log.v(TAG, "CameraActivity [onRestart]");
super.onRestart();
}
@Override
protected void onStop()
{
Log.v(TAG, "CameraActivity [onStop]");
super.onStop();
}
@Override
protected void onDestroy()
{
Log.v(TAG, "CameraActivity [onDestroy]");
super.onDestroy();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
if (key == "pref_bluetooth_midi_select_device")
{
processMidiDevice(sharedPreferences);
}
Log.v(TAG, "Preference \"" + key + "\" changed");
}
public void processMidiDevice(SharedPreferences sharedPreferences)
{
final String MIDI_DEVICE_ID = sharedPreferences.getString("pref_bluetooth_midi_select_device", "");
m_midiAdapter.changeMidiDeviceId(MIDI_DEVICE_ID);
}
public void handleSettingsButtonClick(View v)
{
Log.v(TAG, "setting_button clicked");
Intent intent = new Intent(this, SettingsActivity.class);
//myIntent.putExtra("key", value); //Optional parameters
this.startActivity(intent);
}
}
Here's my Manifest:
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.co.mxklabs.pianospy"
android:versionCode="1"
android:versionName="1.0">
<!-- Min/target SDK versions (<uses-sdk>) managed by build.gradle -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application android:allowBackup="true"
android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:theme="@style/Theme.AppCompat.Light">
<activity android:name=".CameraActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:label="@string/title_activity_settings"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="uk.co.mxklabs.pianoeye.MainActivity" />
</activity>
</application>
</manifest>
I don't expect my activity to pause and immediately resume every minute or so.
EDIT: I tried alternatives to wakelock (e.g. FLAG_KEEP_SCREEN_ON) and it behaves the same:
07-16 19:53:26.799 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-16 19:53:26.934 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-16 19:53:26.997 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-16 19:54:28.111 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-16 19:54:28.224 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-16 19:54:28.291 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-16 19:55:29.369 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-16 19:55:29.491 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause]
07-16 19:55:29.560 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
07-16 19:56:30.647 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onUserLeaveHint]
07-16 19:56:30.771 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onPause
07-16 19:56:30.847 15583-15583/uk.co.mxklabs.pianoeye V/mxklogcat: CameraActivity [onResume]
EDIT: Here's a minimal example that exhibits the same behaviour and uses FLAG_KEEP_SCREEN_ON:
package uk.co.mxklabs.testapp.myapplication;
import android.os.PersistableBundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
public class MainActivity extends AppCompatActivity
{
private static final String TAG = "mxklogcat";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@Override
public void onResume()
{
Log.v(TAG, "MainActivity [onResume]");
super.onResume();
}
@Override
protected void onUserLeaveHint()
{
Log.v(TAG, "MainActivity [onUserLeaveHint]");
super.onUserLeaveHint();
}
@Override
public void onPause()
{
Log.v(TAG, "MainActivity [onPause]");
super.onPause();
}
}
SOLVED: I noticed this problem didn't happen on another phone and figured it might be another app causing this problem. I uninstalled pretty well half the apps on my phone and this problem went away.