2015-04-28 2 views
1

im пытается создать LoginActivity в Android. Я использую стандартный шаблон LoginActivity, предоставляемый Android Studio.Получить токен из WebSite через API

Что я хочу сделать, это дать пользователю приятную LoginActivity, и когда логин будет успешным, будет показана активность с WebView, показывающая WebSite.

Теперь у меня есть задача Asynchron, где все «волшебство», похоже, происходит.

public class UserLoginTask extends AsyncTask<Void, Void, Boolean> { 

    private final String mEmail; 
    private final String mPassword; 

    UserLoginTask(String email, String password) { 
     mEmail = email; 
     mPassword = password; 
    } 

    @Override 
    protected Boolean doInBackground(Void... params) { 
     // TODO: attempt authentication against a network service. 



     try { 
      // Simulate network access. 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
      return false; 
     } 



     for (String credential : DUMMY_CREDENTIALS) { 
      String[] pieces = credential.split(":"); 
      if (pieces[0].equals(mEmail)) { 
       // Account exists, return true if the password matches. 
       return pieces[1].equals(mPassword); 
      } 
     } 

     // TODO: register the new account here. 
     return false; 
    } 

    @Override 
    protected void onPostExecute(final Boolean success) { 
     mAuthTask = null; 
     showProgress(false); 

     if (success) { 
      finish(); 
     } else { 
      mPasswordView.setError(getString(R.string.error_incorrect_password)); 
      mPasswordView.requestFocus(); 
     } 
    } 

    @Override 
    protected void onCancelled() { 
     mAuthTask = null; 
     showProgress(false); 
    } 
} 

Здесь имя пользователя и пароль просто вычисляются значениями массива.

Моя первая проблема, все, что я изменить этой задачи, как добавление простой Toast, приводит мое приложение к сбою ...

Это мой первый раз реализует логин, но я прав, что мой Войти Алгорихм должен понимать эту задачу?

Thats my naxt Вопрос: как мне сделать запрос, используя пустой токен входа для моего r и вызывать функцию getLoginToken?

API-интерфейс с этого сайта дает мне эту RequestLink:

www.pentle.com/api.php?c=json&r={"request":"getLoginToken","validation":{"type":"token","client":"YOUR_APP","token":"","token_id":0,"user_id":0}}&username=YOUR_USERNAME&password=YOUR_PASSWORD 

Запрос будет возвращать объект JSON как это:

{ 
    "token_id":0, 
    "user_id":0, 
    "token":"THE_TOKEN" 
} 

Я попытался this решение, но оно не работало. Когда я пытаюсь использовать HttpClient, у него есть линия, проходящая через него (пробитая/вычеркнутая?). И мое приложение разбивается ...

Возможно, кто-то может пролить свет на то, как использовать задачу Asynchron, и как сделать логин возможным с помощью RequestLink.

Для меня действительно важно, что это работает!

EDIT: Благодаря @danny мой код будет выглядеть так:

package com.pentle.pentle2; 

import android.animation.Animator; 
import android.animation.AnimatorListenerAdapter; 
import android.annotation.TargetApi; 
import android.app.Activity; 
import android.app.LoaderManager.LoaderCallbacks; 
import android.content.CursorLoader; 
import android.content.Loader; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Build; 
import android.os.Bundle; 
import android.provider.ContactsContract; 
import android.text.TextUtils; 
import android.view.KeyEvent; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.inputmethod.EditorInfo; 
import android.widget.ArrayAdapter; 
import android.widget.AutoCompleteTextView; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 
import android.widget.Toast; 

import org.apache.http.client.HttpClient; 
import org.apache.http.client.ResponseHandler; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.BasicResponseHandler; 
import org.apache.http.impl.client.DefaultHttpClient; 

import java.util.ArrayList; 
import java.util.List; 


/** 
* A login screen that offers login via email/password. 
*/ 
public class LoginActivity extends Activity implements LoaderCallbacks<Cursor> { 

    public String test = ""; 

    /** 
    * A dummy authentication store containing known user names and passwords. 
    * TODO: remove after connecting to a real authentication system. 
    */ 
private static final String[] DUMMY_CREDENTIALS = new String[]{ 
     "[email protected]:hello", "[email protected]:world" 
}; 
/** 
* Keep track of the login task to ensure we can cancel it if requested. 
*/ 
private UserLoginTask mAuthTask = null; 

// UI references. 
private AutoCompleteTextView mEmailView; 
private EditText mPasswordView; 
private View mProgressView; 
private View mLoginFormView; 



@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_login); 

    // Set up the login form. 
    mEmailView = (AutoCompleteTextView) findViewById(R.id.email); 
    populateAutoComplete(); 

    mPasswordView = (EditText) findViewById(R.id.password); 
    mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() { 
     @Override 
     public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) { 
      if (id == R.id.login || id == EditorInfo.IME_NULL) { 
       attemptLogin(); 
       return true; 
      } 
      return false; 
     } 
    }); 

    Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button); 
    mEmailSignInButton.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      attemptLogin(); 
     } 
    }); 

    mLoginFormView = findViewById(R.id.login_form); 
    mProgressView = findViewById(R.id.login_progress); 
} 

private void populateAutoComplete() { 
    getLoaderManager().initLoader(0, null, this); 
} 


/** 
* Attempts to sign in or register the account specified by the login form. 
* If there are form errors (invalid email, missing fields, etc.), the 
* errors are presented and no actual login attempt is made. 
*/ 
public void attemptLogin() { 
    if (mAuthTask != null) { 
     return; 
    } 

    // Reset errors. 
    mEmailView.setError(null); 
    mPasswordView.setError(null); 

    // Store values at the time of the login attempt. 
    String email = mEmailView.getText().toString(); 
    String password = mPasswordView.getText().toString(); 

    boolean cancel = false; 
    View focusView = null; 


    // Check for a valid password, if the user entered one. 
    if (TextUtils.isEmpty(password)) { 
     mPasswordView.setError(getString(R.string.error_invalid_password)); 
     focusView = mPasswordView; 
     cancel = true; 
    } 

    // Check for empty Username 
    if (TextUtils.isEmpty(email)) { 
     mEmailView.setError(getString(R.string.error_field_required)); 
     focusView = mEmailView; 
     cancel = true; 
    } 

    if (cancel) { 
     // There was an error; don't attempt login and focus the first 
     // form field with an error. 
     focusView.requestFocus(); 
    } else { 
     // Show a progress spinner, and kick off a background task to 
     // perform the user login attempt. 
     showProgress(true); 
     mAuthTask = new UserLoginTask(email, password); 
     mAuthTask.execute((Void) null); 
    } 
} 

private boolean isEmailValid(String email) { 
    //TODO: Replace this with your own logic 
    return email.contains("@"); 
} 

private boolean isPasswordValid(String password) { 
    //TODO: Replace this with your own logic 
    return password.length() > 4; 
} 

/** 
* Shows the progress UI and hides the login form. 
*/ 
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) 
public void showProgress(final boolean show) { 
    // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow 
    // for very easy animations. If available, use these APIs to fade-in 
    // the progress spinner. 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { 
     int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); 

     mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 
     mLoginFormView.animate().setDuration(shortAnimTime).alpha(
       show ? 0 : 1).setListener(new AnimatorListenerAdapter() { 
      @Override 
      public void onAnimationEnd(Animator animation) { 
       mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 
      } 
     }); 

     mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); 
     mProgressView.animate().setDuration(shortAnimTime).alpha(
       show ? 1 : 0).setListener(new AnimatorListenerAdapter() { 
      @Override 
      public void onAnimationEnd(Animator animation) { 
       mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); 
      } 
     }); 
    } else { 
     // The ViewPropertyAnimator APIs are not available, so simply show 
     // and hide the relevant UI components. 
     mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); 
     mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 
    } 
} 

@Override 
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { 
    return new CursorLoader(this, 
      // Retrieve data rows for the device user's 'profile' contact. 
      Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI, 
        ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION, 

      // Select only email addresses. 
      ContactsContract.Contacts.Data.MIMETYPE + 
        " = ?", new String[]{ContactsContract.CommonDataKinds.Email 
      .CONTENT_ITEM_TYPE}, 

      // Show primary email addresses first. Note that there won't be 
      // a primary email address if the user hasn't specified one. 
      ContactsContract.Contacts.Data.IS_PRIMARY + " DESC"); 
} 

@Override 
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) { 
    List<String> emails = new ArrayList<String>(); 
    cursor.moveToFirst(); 
    while (!cursor.isAfterLast()) { 
     emails.add(cursor.getString(ProfileQuery.ADDRESS)); 
     cursor.moveToNext(); 
    } 

    addEmailsToAutoComplete(emails); 
} 

@Override 
public void onLoaderReset(Loader<Cursor> cursorLoader) { 

} 

private interface ProfileQuery { 
    String[] PROJECTION = { 
      ContactsContract.CommonDataKinds.Email.ADDRESS, 
      ContactsContract.CommonDataKinds.Email.IS_PRIMARY, 
    }; 

    int ADDRESS = 0; 
    int IS_PRIMARY = 1; 
} 


private void addEmailsToAutoComplete(List<String> emailAddressCollection) { 
    //Create adapter to tell the AutoCompleteTextView what to show in its dropdown list. 
    ArrayAdapter<String> adapter = 
      new ArrayAdapter<String>(LoginActivity.this, 
        android.R.layout.simple_dropdown_item_1line, emailAddressCollection); 

    mEmailView.setAdapter(adapter); 
} 

/** 
* Represents an asynchronous login/registration task used to authenticate 
* the user. 
*/ 
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> { 

    private final String mEmail; 
    private final String mPassword; 


    UserLoginTask(String email, String password) { 
     mEmail = email; 
     mPassword = password; 
     test = "1"; 
    } 

    @Override 
    protected Boolean doInBackground(Void... params) { 
     // TODO: attempt authentication against a network service. 
    String response; 
    HttpClient Client = new DefaultHttpClient(); 
    ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
     try 
     { 
      test = "2"; 
      HttpPost postMethod = new HttpPost("www.pentle.com/api.php?c=json&r={request:getLoginToken,validation:type:token,client:Pentle_Android,token:,token_id:0,user_id:0}}&username="+mEmail+"&password=" + mPassword); 
      //_email and _password are String values from TextView: 
      test = "3"; 
      //postMethod.setEntity(new StringEntity("&username="+mEmail+"&password=" + mPassword)); 
      test = "4"; 
      postMethod.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
      //here is the reponse, you can check it: 
      response = Client.execute(postMethod, responseHandler); 

     } 

     catch(Exception ex) 
     { 
      //Login to server failed... 
      ex.printStackTrace(); 
     } 



     /*try { 
      // Simulate network access. 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
      return false; 
     } 

     for (String credential : DUMMY_CREDENTIALS) { 
      String[] pieces = credential.split(":"); 
      if (pieces[0].equals(mEmail)) { 
       // Account exists, return true if the password matches. 
       return pieces[1].equals(mPassword); 
      } 
     }*/ 

     // TODO: register the new account here. 
     return false; 
    } 

    @Override 
    protected void onPostExecute(final Boolean success) { 
     mAuthTask = null; 
     showProgress(false); 

     Toast.makeText(getApplicationContext(), test, Toast.LENGTH_SHORT).show(); 

     if (success) { 
      finish(); 
     } else { 
      mPasswordView.setError(getString(R.string.error_incorrect_password)); 
      mPasswordView.requestFocus(); 
     } 
    } 

    @Override 
    protected void onCancelled() { 
     mAuthTask = null; 
     showProgress(false); 
    } 
    } 
} 

Позже он должен вернуться, если не был пользователь foud, пользователь найден, но ВН неправильно, или если Войти был успешный. В случае успешной работы будет отображаться активность с помощью WebView shoul.

Прямо сейчас он не работает HttpPost postMethod = new HttpPost("www.pentle.com/api.php?c=json&r={request:getLoginToken,validation:type:token,client:Pentle_Android,token:,token_id:0,user_id:0}}&username="+mEmail+"&password=" + mPassword);. Это связано с тем, что я пытаюсь запустить его в фоновом режиме? Строка test представлена ​​в Тосте в PostExecute, чтобы увидеть, где ist останавливается.

Я использовал API-запрос правильно?

+0

Вы пробовали некоторые библиотеки, такие как залп? дайте ему шанс: https://developer.android.com/training/volley/index.html – Tofasio

+0

Вы хотите увидеть мой код с токеном, но реализованный с другим Thread not AsynTask? –

+0

@ Tofasio: Я еще не пробовал другие библиотеки, но, возможно, попробует, спасибо! @ danny: Конечно! Все, что помогает! В течение некоторого времени я рассматриваю возможность сделать свою собственную LoginActivity полностью с нуля и не использовать ее. Но при нажатии Login-Butten он дает мне этот хороший Progress: D –

ответ

0

@Denis Pramme

Пожалуйста, попробуйте этот код и дайте мне знать:

public class LoginActivity extends Activity 
{ 
..... 

private void SignInMethod() 
{ 
new Thread(new Runnable() 
    { 
     public void run() 
     { 
     try 
      { 
     HttpPost postMethod = new HttpPost("*URL TO YOUR API SERVER*" + "Authenticate"); 
     //_email and _password are String values from TextView: 
     postMethod.setEntity(new StringEntity("grant_type=password&username=" + _email + "&password=" + _password)); 
     postMethod.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
     //here is the reponse, you can check it: 
     response = httpClient.execute(postMethod, resonseHandler); 
      } 

      catch(Exception ex) 
      { 
      //Login to server failed... 
      ex.printStackTrace(); 
      } 
     } 
    }).start(); 
} 

} 
+0

Thanks! Отредактировано мое сообщение! Это не работает, может, я сделал что-то не так? –

0

@DennisPramme, хорошо, пожалуйста, измените строку:

String response = httpClient.execute(postMethod, resonseHandler); 

К этой линии: (это будет показать статус, возвращенный с сервера):

HttpResponse responseFromServer = httpClient.execute(postMethod); 
int status = responseFromServer.getStatusLine().getStatusCode(); 
+0

Это ошибка на стороне сервера, поэтому вы получите сообщение об ошибке пустое. –

Смежные вопросы