I've got a class
class myView extends SurfaceView
How can i get the rotation of the screen from there?
You can instantiate an OrientationEventListener. Just make sure to disable it when you are not using it because the SensorManager will drain the battery.
public class OELActivity extends Activity{
OrientationEventListener mOrientationEventListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mOrientationEventListener = (new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
#Override
public void onOrientationChanged(int aangle) {
//Do your thing here. angle is in degrees
}});
}
#Override
public void onResume() {
if (myOrientationEventListener.canDetectOrientation()){
myOrientationEventListener.enable();
} else {
//handle the fact that you can't detect the orientation
}
}
#Override
protected void onPause() {
super.onPause();
mOrientationEventListener.disable();
}
}
Related
So I’ve got this Activity with a doSomething() method. This method must be called when the user leaves the Activity and resumes after a while. This code works fine. The problem is: When the user rotates the phone (orientation change), the method is also called. I don’t want the method to be called on Orientation Change. Here’s my Activity code
public class MainActivity extends AppCompatActivity
{
private static boolean callMethod=true;
#Override
protected void onResume() {
super.onResume();
if(callMethod)
doSomething();
}
#Override
protected void onPause() {
super.onPause();
callMethod=true;
}
private void doSomething()
{
Log.i(“doSomething()”,”Did something.”);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(callMethod)
doSomething();
}
}
Thanks in advance!
From API 13 you can use configChanges in manifest.
Add the following to the manifest. This prevents recreation of the activity on screen rotation:
<activity android:name=".Activity_name"
android:configChanges="orientation|keyboardHidden">
One note is after this, you should handle screen orientation change yourself. you should override the following function in your activity for that:
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
setContentView(R.layout.layout_landscape);
}
else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
setContentView(R.layout.layout);
}
}
I see in your comment that you added the isChangingConfigurations() flag, which should do the trick, but you should persist that state rather than making it a static variable. Otherwise, if your process is killed when your app goes to the background you'll lose that state.
public class MainActivity extends AppCompatActivity {
private static final String KEY_CALL_METHOD = "key_call_method";
private boolean callMethod = true;
#Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.activity_main);
if (savedState != null) {
callMethod = savedState.getBoolean(KEY_CALL_METHOD);
}
}
#Override
protected void onResume() {
super.onResume();
if (callMethod) {
doSomething();
}
}
#Override
protected void onPause() {
super.onPause();
if (!isChangingConfigurations()) {
callMethod = true;
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_CALL_METHOD, callMethod);
}
private void doSomething() {
Log.i("doSomething()", "Did something.");
}
}
I have two activities(MainActivity,Sample) which extend to a custom activity(BaseActivity) i have created. I have created a handler which runs a runnable every 5 seconds in BaseActivity. In BaseActivity i have overridden onpause and onresume methods to start and stop handler whenever needed. When i remove the callbacks of handler in onPause of BaseActivity, the handler stops but won't stop in onpause of MainActivity. Below is the code.
public class BaseActivity extends Activity{
public int mInterval = 5000;
public Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("Oncreate baseactivity");
mHandler = new Handler();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
Log.d("MyApp", "every 5 secs");
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
#Override
protected void onPause() {
super.onPause();
System.out.println("OnPause baseactivity");
//stopRepeatingTask();
}
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
#Override
protected void onResume() {
super.onResume();
System.out.println("Onresume baseactivity");
startRepeatingTask();
}
}
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void newpage(View v){
startActivity(new Intent(this,Sample.class));
}
#Override
protected void onPause() {
super.onPause();
System.out.println("onpause mainactivity");
stopRepeatingTask();
}
}
public class Sample extends BaseActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.txt);
tv.setText("sample activity");
}
}
The Onpause of both BaseActivity and mainActivity are called but the handler still runs if the app is closed. I hope am clear.
I think to start thread we should use start() method,
and write onPause method of MainActivity in BaseActivity Itself and remove in MainActivity(i mean stopRepeating Task).
I hope it works.
I have searched around and looked for a way to detect the watch dimming. I want to write some code to change a custom watch faces color when the screen dims. How can I do this?
I'm using this abstract Activity to detect the watch dimming (implementing DisplayManager.DisplayListener).
public abstract class WatchFaceActivity extends Activity implements DisplayManager.DisplayListener {
private DisplayManager displayManager;
public abstract void onScreenDim();
public abstract void onScreenAwake();
public void onWatchFaceRemoved() {
}
public void onScreenOff() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
displayManager.registerDisplayListener(this, null);
}
#Override
protected void onDestroy() {
super.onDestroy();
displayManager.unregisterDisplayListener(this);
}
#Override
public void onDisplayRemoved(int displayId) {
onWatchFaceRemoved();
}
#Override
public void onDisplayAdded(int displayId) {
}
#Override
public void onDisplayChanged(int displayId) {
switch (displayManager.getDisplay(displayId).getState()) {
case Display.STATE_DOZING:
onScreenDim();
break;
case Display.STATE_OFF:
onScreenOff();
break;
default:
onScreenAwake();
break;
}
}}
More infos here: http://www.binpress.com/tutorial/how-to-create-a-custom-android-wear-watch-face/120
I am trying to create a proximity sensor in an application that is already working fine. I am able to run ok the sensor, but when I do it, it disables the OnClickListener of the buttons of the application and I really don't understand why.
This is my MainActivity.class
public class MainActivity extends Activity implements OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button option1 = (Button) findViewById(R.id.option1);
Button option2 = (Button) findViewById(R.id.option2);
option1.setOnClickListener(this);
option2.setOnClickListener(this);
}
#Override
protected void onResume() {
super.onResume();
Intent intent = new Intent();
intent.setClass(getBaseContext(),ProximitySensor.class);
startActivity(intent);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.option1:
// Option1
break;
case R.id.option2:
// Option1
break;
default:
break;
}
}
}
And here the ProximitySensor.class that is working OK
public class ProximitySensor extends Activity implements SensorEventListener{
private SensorManager sm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sm= (SensorManager)getSystemService(Context.SENSOR_SERVICE);
}
#Override
protected void onStart(){
super.onStart();
Sensor proximitySensor= sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);
if (proximitySensor == null){
Toast.makeText(ProximitySensor.this,"No Proximity Sensor Found! ",Toast.LENGTH_LONG).show();
}
}
#Override
protected void onResume() {
super.onResume();
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_PROXIMITY),SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onStop() {
super.onStop();
sm.unregisterListener(this);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType()==Sensor.TYPE_PROXIMITY){
if(event.values[0] == 0){
Toast.makeText(ProximitySensor.this,"You are close",Toast.LENGTH_LONG).show();
}
}
}
}
I think that I might be calling wrong the sensor, could anyone give me a hand?
Many thanks!
You need to register onClick listeners in ProximitySensor activity just like you did on your main activity.
You are currently starting a new activity, setting its layout the same as your main activity. But when you do that, the onClickListeners you set up on your main activity no longer works, because it is a new activity and a new layout.
I have got a problem
When hitting the home button, my game thread class gets paused. But when re-entering the app and the onResume() method gets called, it should resume the game thread... everythin i get is a force close.
Here is my MainActivity:
public class MainActivity extends Activity {
private RelativeLayout relativeLayout;
private GameView gameView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameView = new GameView(this, this);
setContentView(R.layout.activity_main);
relativeLayout = (RelativeLayout)findViewById(R.id.mainView);
relativeLayout.addView(gameView);
}
#Override
protected void onPause() {
super.onPause();
gameView.pause();
}
#Override
protected void onResume() {
super.onResume();
if(gameView.getGameThread() != null) {
if(gameView.getGameThread().isRunning == false) {
gameView.resume();
}
}
}
}
gameView is following class, a surfaceView getting rendered by GameThread:
public class GameView extends SurfaceView{
private GameThread gameThread;
public GameView(Context context, Activity activity) {
super(context);
gameThread = new GameThread(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
gameThread.setRunning(true);
gameThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
});
}
public GameThread getGameThread() {
return gameThread;
}
public void update() {
}
public void pause() {
gameThread.pause();
}
public void resume() {
gameThread.resumeThread();
}
}
This is the GameThread class:
public class GameThread extends Thread{
private GameView view;
public boolean isRunning = false;
public GameThread(GameView view) {
this.view = view;
}
public void setRunning(boolean setRunning) {
isRunning = setRunning;
}
public void stopThread() {
isRunning = false;
}
public void run() {
while(isRunning) {
Canvas c = null;
view.update();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.draw(c);
}
}finally {
if(c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
}
}
public void startThread() {
isRunning = true;
}
public void pause() {
isRunning = false;
}
public void resumeThread() {
isRunning = true;
}
}
I removed the irrelevant parts of the code.
When re-entering the app the android.view.Choreographer class opens
Any ideas?
Actually you're not pausing your thread (to be strict, there's no such thing as pausing a thread). You're ending your thread.
When you call pause() you set the isRunning flag to false, that makes the thread exit the loop and the thread ends. When you set your 'isRunning' to true again, the thread won't restart.
Actually you can't reuse threads in java, you have to create a new one, because once the thread loop ends, it's dead.