Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android-如何持续提示对话框 介绍_Java_Android_Http_Android Asynctask_Android Dialog - Fatal编程技术网

Java Android-如何持续提示对话框 介绍

Java Android-如何持续提示对话框 介绍,java,android,http,android-asynctask,android-dialog,Java,Android,Http,Android Asynctask,Android Dialog,我想要完成的事情[听起来]很简单。我想用登录对话框提示用户,直到用户成功进行身份验证 我计划使用AsyncTask来处理数据和web请求,但这很快就变成了一场噩梦;很可能是因为我缺乏安卓系统的经验 然而,我知道这是可以做到的,就像我以前在其他应用程序中看到的那样 我想要完成的 问题是怎么做?我知道我想做什么: 1. Initially prompt a user to login. 2. Send authentication data. 3. If successful, continue

我想要完成的事情[听起来]很简单。我想用登录对话框提示用户,直到用户成功进行身份验证

我计划使用AsyncTask来处理数据和web请求,但这很快就变成了一场噩梦;很可能是因为我缺乏安卓系统的经验

然而,我知道这是可以做到的,就像我以前在其他应用程序中看到的那样


我想要完成的 问题是怎么做?我知道我想做什么:

1. Initially prompt a user to login.
2. Send authentication data.
3. If successful, continue the application.
4. If unsuccessful, reprompt the user until success.

到目前为止我所拥有的 到目前为止,我拥有的是AsyncTask(
LoginTask
),它将处理web请求和登录数据:

public class LoginTask extends AsyncTask<String, Void, App.STATUS>
{
    private boolean m_proceed = false;
    private String m_username, m_key;

    @Override
    protected void onPreExecute()
    {
        // Check if there is a dialog on screen. //
        m_proceed = !App.DIALOG_ONSCREEN;
    }

    @Override
    protected App.STATUS doInBackground(String ... p_args)
    {
        // Do not do this if a dialog is on screen. //
        if(!m_proceed)
            return App.STATUS.DENIED;

        // Make a web request. //
        try
        {
            URL t_url = new URL("https://mysite.com/api/login");
            HttpsURLConnection t_con = (HttpsURLConnection)t_url.openConnection();

            t_con.setRequestMethod("POST");
            t_con.setRequestProperty("User-Agent", "Mozilla/5.0");

            t_con.setDoOutput(true);
            DataOutputStream t_wr = new DataOutputStream(t_con.getOutputStream());
            t_wr.writeBytes("username="+p_args[0]+"&password="+p_args[1]);
            t_wr.flush();
            t_wr.close();

            t_con.connect();

            BufferedReader t_in = new BufferedReader(new InputStreamReader(t_con.getInputStream()));

            String t_input_line;
            StringBuffer t_response = new StringBuffer();

            while((t_input_line = t_in.readLine()) != null) 
            {
                t_response.append(t_input_line);
            }

            t_in.close();

            // If denied, return failed. If accepted, set the username and key. //
            if(t_response.toString().equals("DENIED"))
                return App.STATUS.FAILED;
            else
            {
                m_key = t_response.toString();
                m_username = p_args[0];
            }

            return App.STATUS.ACCEPTED;
        }
        catch(Exception err)
        {
            System.err.println(err.getMessage());
        }

        return App.STATUS.FAILED;
    }

    @Override
    protected void onPostExecute(App.STATUS p_status)
    {
        // Authenticate the user if the username and key are valid. //
        if(p_status == App.STATUS.ACCEPTED)
            App.acceptCredentials(m_username, m_key);

        // The dialog is no longer on the screen. //
        App.DIALOG_ONSCREEN = false;
    }
}

我需要什么帮助 我的主要问题是如何设计我的程序,以便在用户成功验证之前可以轻松地一直显示登录对话框?我曾想过使用while循环,但这样会一直显示对话框并影响性能。当异步和同步任务同时工作时,这是相当棘手的

我不是在寻找直截了当的代码,但如果您能了解一般情况,我将不胜感激

感谢您花时间阅读本文,并感谢您的帮助


解决方案
HomeActivity.java

private void promptLogin()
{
    final Context t_main_context = this;

    // Create the dialog. //
    LayoutInflater t_infl = LayoutInflater.from(this);
    final View t_login_view = t_infl.inflate(R.layout.login_dialog, null);

    final AlertDialog t_dialog = new AlertDialog.Builder(this)
            .setTitle("Login")
            .setCancelable(false)
            .setView(t_login_view)
            .setPositiveButton("Login", null)
            .create();
    t_dialog.show();

    t_dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View t_view)
        {
            String t_username = ((EditText)t_login_view.findViewById(R.id.in_username)).getText().toString(),
                    t_password = ((EditText)t_login_view.findViewById(R.id.in_password)).getText().toString();

            try
            {
                new LoginTask(t_main_context, t_dialog).execute(t_username, t_password);
            }
            catch(Exception err)
            {
                err.printStackTrace();
            }
        }
    });
}

@Override
public void onCreate(Bundle p_data)
{
    // Basic crap... //
    super.onCreate(p_data);
    setContentView(R.layout.activity_home);

    // Are we authenticated? //
    if(!App.isAuthenticated())
        promptLogin();
}
private String m_username, m_key;

private Context m_context;
private AlertDialog m_dialog;
private ProgressDialog m_loading;

public LoginTask(Context p_context, AlertDialog p_dialog)
{
    m_context = p_context;
    m_dialog = p_dialog;

    m_loading = ProgressDialog.show(m_context, "", "Logging in...", true);
}

@Override
protected App.STATUS doInBackground(String ... p_args)
{
    // Make a web request. //
    try
    {
        URL t_url = new URL("https://mysite.com/api/login");
        HttpsURLConnection t_con = (HttpsURLConnection)t_url.openConnection();

        t_con.setRequestMethod("POST");
        t_con.setRequestProperty("User-Agent", "Mozilla/5.0");

        t_con.setDoOutput(true);
        DataOutputStream t_wr = new DataOutputStream(t_con.getOutputStream());
        t_wr.writeBytes("username="+p_args[0]+"&password="+p_args[1]);
        t_wr.flush();
        t_wr.close();

        t_con.connect();

        BufferedReader t_in = new BufferedReader(new InputStreamReader(t_con.getInputStream()));

        String t_input_line;
        StringBuffer t_response = new StringBuffer();

        while((t_input_line = t_in.readLine()) != null) 
        {
            t_response.append(t_input_line);
        }

        t_in.close();

        // If denied, return failed. If accepted, set the username and key. //
        if(t_response.toString().equals("DENIED"))
            return App.STATUS.FAILED;
        else
        {
            m_key = t_response.toString();
            m_username = p_args[0];
        }

        return App.STATUS.ACCEPTED;
    }
    catch(Exception err)
    {
        System.err.println(err.getMessage());
    }

    return App.STATUS.FAILED;
}

@Override
protected void onPostExecute(App.STATUS p_status)
{
    m_loading.dismiss();

    // Authenticate the user if the username and key are valid. //
    if(p_status == App.STATUS.ACCEPTED)
    {
        App.acceptCredentials(m_username, m_key);
        m_dialog.dismiss();
    }
    else
        Toast.makeText(m_context, "Login failed", Toast.LENGTH_SHORT).show();
}
LoginTask.java

private void promptLogin()
{
    final Context t_main_context = this;

    // Create the dialog. //
    LayoutInflater t_infl = LayoutInflater.from(this);
    final View t_login_view = t_infl.inflate(R.layout.login_dialog, null);

    final AlertDialog t_dialog = new AlertDialog.Builder(this)
            .setTitle("Login")
            .setCancelable(false)
            .setView(t_login_view)
            .setPositiveButton("Login", null)
            .create();
    t_dialog.show();

    t_dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View t_view)
        {
            String t_username = ((EditText)t_login_view.findViewById(R.id.in_username)).getText().toString(),
                    t_password = ((EditText)t_login_view.findViewById(R.id.in_password)).getText().toString();

            try
            {
                new LoginTask(t_main_context, t_dialog).execute(t_username, t_password);
            }
            catch(Exception err)
            {
                err.printStackTrace();
            }
        }
    });
}

@Override
public void onCreate(Bundle p_data)
{
    // Basic crap... //
    super.onCreate(p_data);
    setContentView(R.layout.activity_home);

    // Are we authenticated? //
    if(!App.isAuthenticated())
        promptLogin();
}
private String m_username, m_key;

private Context m_context;
private AlertDialog m_dialog;
private ProgressDialog m_loading;

public LoginTask(Context p_context, AlertDialog p_dialog)
{
    m_context = p_context;
    m_dialog = p_dialog;

    m_loading = ProgressDialog.show(m_context, "", "Logging in...", true);
}

@Override
protected App.STATUS doInBackground(String ... p_args)
{
    // Make a web request. //
    try
    {
        URL t_url = new URL("https://mysite.com/api/login");
        HttpsURLConnection t_con = (HttpsURLConnection)t_url.openConnection();

        t_con.setRequestMethod("POST");
        t_con.setRequestProperty("User-Agent", "Mozilla/5.0");

        t_con.setDoOutput(true);
        DataOutputStream t_wr = new DataOutputStream(t_con.getOutputStream());
        t_wr.writeBytes("username="+p_args[0]+"&password="+p_args[1]);
        t_wr.flush();
        t_wr.close();

        t_con.connect();

        BufferedReader t_in = new BufferedReader(new InputStreamReader(t_con.getInputStream()));

        String t_input_line;
        StringBuffer t_response = new StringBuffer();

        while((t_input_line = t_in.readLine()) != null) 
        {
            t_response.append(t_input_line);
        }

        t_in.close();

        // If denied, return failed. If accepted, set the username and key. //
        if(t_response.toString().equals("DENIED"))
            return App.STATUS.FAILED;
        else
        {
            m_key = t_response.toString();
            m_username = p_args[0];
        }

        return App.STATUS.ACCEPTED;
    }
    catch(Exception err)
    {
        System.err.println(err.getMessage());
    }

    return App.STATUS.FAILED;
}

@Override
protected void onPostExecute(App.STATUS p_status)
{
    m_loading.dismiss();

    // Authenticate the user if the username and key are valid. //
    if(p_status == App.STATUS.ACCEPTED)
    {
        App.acceptCredentials(m_username, m_key);
        m_dialog.dismiss();
    }
    else
        Toast.makeText(m_context, "Login failed", Toast.LENGTH_SHORT).show();
}
因此,我在
HomeActivity.java
中的
PrompLogin()
中所做的是,我覆盖了ClickListener上的按钮,这样对话框将不会关闭,除非通过
t\u dialog.dismise()关闭。然后,我将web请求发送到
LoginTask
,并将对话框作为参数传递,这样对话框只会在我取消对话框之前关闭

我仅在接受凭据时才关闭该对话框,如您在
onPostExecute()
中所见

这样,对话框将一直显示在屏幕上,直到用户成功登录为止,这就是我一直在寻找的行为


谢谢大家的帮助

您必须创建一个活动来处理您的登录,另一个活动是您的主要活动。如果登录失败,则什么也不会发生,如果登录成功,则启动第二个活动。不需要复杂的设置。
您还可以查看Volley库,它使http连接非常容易。

1。最初提示用户登录。

在此处不断提示对话框,并使用
setCancelable(false)
,这样用户就不会取消登录过程。然后在按钮上创建一个
视图。OnclickListner
,用户必须单击该按钮才能将数据发送到服务器。让我们说一下
Login
按钮

AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Delete entry")
        .setMessage("Are you sure you want to delete this entry?")
        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) { 
                // send data here with AsyncTask
            }
         })
        .setIcon(R.drawable.ic_my_icon);
    builder.setCancelable(false);
builder.show();
protected void onPostExecute(Boolean result) {

    if(result) {
        // he is now authenticated, dismiss dialog and continue in your app
        dialog.dismiss();
    } else {
        // nothing to do, until he succeed
    }    
}
2。发送身份验证数据。

在这里使用您的
AsyncTask
,在
doInBackgroud()
方法中执行发送任务,并返回一些
onPostExecute()
以了解身份验证是否成功。如果成功,则关闭对话框;如果失败,则保留对话框,等待用户再次单击
登录
按钮

AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Delete entry")
        .setMessage("Are you sure you want to delete this entry?")
        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) { 
                // send data here with AsyncTask
            }
         })
        .setIcon(R.drawable.ic_my_icon);
    builder.setCancelable(false);
builder.show();
protected void onPostExecute(Boolean result) {

    if(result) {
        // he is now authenticated, dismiss dialog and continue in your app
        dialog.dismiss();
    } else {
        // nothing to do, until he succeed
    }    
}
3。如果成功,请继续应用程序。

使用
disclose()
方法关闭此处的对话框

4。如果失败,请重新提示用户直到成功。

在验证过程成功之前,不要执行任何操作,让对话框显示出来。您还可以向用户显示一些内容(祝酒词、图片等),告诉他尚未登录


希望你明白。

谢谢!我将尝试实现这一点,并向您通报情况。
继续提示此处的对话框
等等,我是否应该使用while循环?阅读
4。如果不成功,请重新提示用户直到成功
部分。您只需要显示一次对话框。然后让用户输入登录信息,如果正确,关闭对话框,否则显示!!我接受这是正确的答案,因为它给了我一些见解,但完整的解决方案列在OP中。感谢您的回答!我想我可以使用我的Http连接方法,它已经工作了:)至于你告诉我如何设置我的活动来处理登录,我知道这将是最简单的,但我想做一些看起来很流畅的事情。要登录的整个活动?我个人认为这很笨拙。再说一次,如果我不能让整个对话顺利进行,我会退回到对话中去。@Ken即使有些东西能正常工作,但并不意味着这是最好的方式。使用现成的框架(如Volley)将帮助您更易于阅读和编写,而不是使用您自己编写的代码,但这当然是一个品味问题。您为什么要使用
对话框
?它在你的应用程序中添加了什么,而一个简单的登录屏幕并没有添加什么?我认为你试图添加一个
对话框作为登录名,这让事情变得更难了。@Darwind我很欣赏你的见解,但我不认为事情很难,我就不应该这样做。我是说你不应该这样做,因为它很难,因为它不难。我只是觉得你让事情变得更难了。当你已经有了可以使用的活动时,使用
对话框作为登录屏幕是没有意义的。虽然对话框在网站上很有用,但我相信你不应该在移动应用程序中使用它们。