5

Hello i am trying to implement a log in screen showing a progress dialog and allowing the phone to rotate.

I want to ask what is the best way to do that (IntentService, AsyncTask,Service) and allowing the phone to rotate?

I read a lot answers saying different things using an empty fragment with AsyncTask etc.

g.y
  • 59
  • 1
  • 2
    Can you explain what you want to do? – Gurjit Singh Sep 21 '16 at 20:46
  • @Singh i want to login with the server showing a progressdialog and allow the phone to rotate without killing the login action – g.y Sep 21 '16 at 20:48
  • Technically there is a solution using each of the three Android building blocks. I may recommend IntentService as least tied to the life cycle of the activity... but then connecting it via broadcasts is trickier than utilizing an AsyncTask. It really would be best for a SO question to attempt one of these methods and the community can assist from there. – FishStix Sep 21 '16 at 21:27

4 Answers4

1

You can do something like that in manifest to allow rotation:

<application
        android:allowBackup="true"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activities.MainActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"/>

Then you can catch the rotation with this snipet inside your activity:

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.v(this.getClass().getName(), "onConfigurationChanged()");
    }

To do an asynctask with progress dialog, this snipet should give you a ligth:

private ProgressDialog pDialog;

private class MyAsync extends AsyncTask<String, Void, String> {
    Activity context;

    public MyAsync (Activity context) {
        this.context = context;
    }

    @Override
    protected void onPreExecute(){ 
        super.onPreExecute();
        pdia = new ProgressDialog(context);
        pdia.setMessage("Loading...");
        pdia.show();    
    }
    @Override
    protected String doInBackground(String... urls) {
        ...
        //do your login scheme
        ...
        //context.methods()
        return "ok";
    }
    @Override
    protected void onPostExecute(String result) {
        pDialog.dismiss();
        if(result!=null && result.equals("ok")){
            //login was successfully done
        } else {
            //login has failed
        }
    }
}

And to use this asynctask you shoud call:

new MyAsync(this).execute(null, null , null);

By the way this is your activity/fragment.

TroniPM
  • 329
  • 3
  • 13
0

Try adding this attribute android:configChanges="orientation" to your Activity element in the AndroidManifest.xml file. show a ProgressDialog in the onPreExecute method of an AsyncTask object and canceling the ProgressDialog in the onPostExecute method. doInBackground method is running When change the orientation.

MIkka Marmik
  • 1,101
  • 11
  • 29
0

Refer to http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html for a detailed answer.

Basically, you can use fragment with setRetainInstance set to true inside your LoginActivity so that it doesn't get destroyed when activity is recreated during orientation change.

Sample Code :

public class AsyncFragment extends Fragment {

    private LoginTask mTask;
    private AsyncTaskListener mListener;
    private static final String TAG = "AsyncFragment";
    private boolean isTaskRunning = false;
    private ProgressDialog mProgressDialog;
    FrameLayout mLayout;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        mTask = new LoginTask();
        mTask.execute();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mLayout = new FrameLayout(getActivity());
        mLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        if(isTaskRunning) {
            mProgressDialog = new ProgressDialog(getActivity());
            mProgressDialog.show();
        }
        return mLayout;
    }

    @Override
    public void onDestroyView() {
        if(mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
        super.onDestroyView();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            mListener = (AsyncTaskListener) context;
        } catch (ClassCastException e) {
            Log.d(TAG, "Class not instance of AsyncTaskListener");
        }
    }

    @Override
    public void onDetach() {
        mListener = null;
        super.onDetach();
    }

    private class LoginTask extends AsyncTask<Void,Integer,Void> {

        @Override
        protected Void doInBackground(Void... params) {
            if(mListener != null) {
                mListener.onBackground();
            }
            SystemClock.sleep(10000);
            return null;
        }

        @Override
        protected void onPreExecute() {
            isTaskRunning = true;
            mProgressDialog = new ProgressDialog(getActivity());
            mProgressDialog.show();
            if(mListener != null) {
                mListener.onPreExecute();
            }
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            if(mListener != null) {
                mListener.onPostExecute();
            }
            isTaskRunning = false;
            if(mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            if(mListener != null) {
                mListener.onProgressUpdate(values[0]);
            }
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
            if(mListener != null) {
                mListener.onCancelled();
            }
        }
    }

    //Listener to notify for async task callbacks
    public interface AsyncTaskListener{
        void onPreExecute();
        void onPostExecute();
        void onCancelled();
        void onBackground();
        void onProgressUpdate(int progress);
    }
}

LoginActivity

public class MainActivity extends AppCompatActivity implements AsyncFragment.AsyncTaskListener{

    private static final String FRAGMENT_TAG = "asyncFragment";
    private static final String TAG = "MainActivity";

    private AsyncFragment mAsyncFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FragmentManager fm = getSupportFragmentManager();
        mAsyncFragment = (AsyncFragment) fm.findFragmentByTag(FRAGMENT_TAG);
        if (mAsyncFragment == null) { //fragment was retained during orientation change
            mAsyncFragment = new AsyncFragment();
            fm.beginTransaction().add(mAsyncFragment, FRAGMENT_TAG).commit();
        }

    }

    @Override
    public void onPreExecute() {
        Log.d(TAG, "onPreExecute: ");
    }

    @Override
    public void onPostExecute() {
        Log.d(TAG, "onPostExecute: "); 
    }

    @Override
    public void onCancelled() {
        Log.d(TAG, "onCancelled: ");    
    }

    @Override
    public void onBackground() {
        Log.d(TAG, "onBackground: ");
    }

    @Override
    public void onProgressUpdate(int progress) {
        Log.d(TAG, "onProgressUpdate: ");
    }
abhishesh
  • 3,246
  • 18
  • 20
-1

Have you tried this?

<activity
    android:name=".MainActivity"
    android:configChanges="orientation|screenSize">
</activity>

This way the activity will not be recreated. but you can detect the screen orientation using onConfigurationChanged()

ZeroOne
  • 8,996
  • 4
  • 27
  • 45