Используйте android sharedpreference в AsyncTask

#android #android-asynctask #sharedpreferences

#Android #android-asynctask #sharedpreferences

Вопрос:

Я годами разрабатываю веб-страницы с php и MySQL, но я новичок в разработке проектов для Android. Я искал и прочитал все предыдущие вопросы, которые я нашел по этому вопросу, но не нашел ответа, который подходит для моего проекта. В настоящее время, когда я запускаю приложение, все, что я получаю, это ошибки и отсутствие загрузки. Я публикую полный код для своей основной деятельности и спрашиваю, может ли кто-нибудь объяснить, что я сделал не так. Данные в sharedpreferences для идентификатора пользователя представляют собой целое число, а дата / сеанс — числовую строку, а адрес электронной почты / eaddress — строку

 package com.example.logintest;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class MainActivity extends AppCompatActivity {


String IgidPreference = "IgidPreference";
String UserId = "userId";
String Date = "session";

//OR SHOULD THE DECLEARATION BE??
//public static final String UserId = "userId";


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    new VerifyLogin().execute();

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(MainActivity.this, Login.class);
            startActivity(intent);
        }
    });
}

public class VerifyLogin extends AsyncTask<String, Void, String> {

    Context ctx;
    SharedPreferences pref;

    protected void onPreExecute() {
    }

    @Override
    protected String doInBackground(String... arg0) {

        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);


        if ((pref.contains(UserId)) amp;amp; (pref.contains(Date))) {
        }
        String eaddress = arg0[0];
        String today = arg0[1];

        String link;
        String data;
        BufferedReader bufferedReader;
        String resu<


        try {
            data = "?Email="   URLEncoder.encode(eaddress, "UTF-8");
            data  = "amp;Date="   URLEncoder.encode(today, "UTF-8");
            link = "http://domain.com/verifylogin.php"   data;
            URL url = new URL(link);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();

            bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
            result = bufferedReader.readLine();
            return resu<

        } catch (Exception e) {
            return new String("Exception: "   e.getMessage());
        }
    }
    @Override
    protected void onPostExecute(String result) {
        String jsonStr = resu<

        if (jsonStr != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr);
                String userId = jsonObj.getString("user_id");
                String session = jsonObj.getString("session");
                String error_type = jsonObj.getString("error");
                String error_msg = jsonObj.getString("error_msg");

                if (error_type.equals("FALSE")) {
                    pref = context.getSharedPreferences(IgidPreference, Context.MODE_PRIVATE);
                    SharedPreferences.Editor editor = pref.edit();
                    editor.putString(UserId, userId);
                    editor.putString(Date, session);
                    editor.apply();

                    Intent intent = new Intent(MainActivity.this, Account.class);
                    startActivity(intent);

                } else if (error_type.equals("TRUE")) {
                    Toast.makeText(context, error_msg, Toast.LENGTH_SHORT).show();

                } else {
                    Toast.makeText(context, error_msg, Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
                Toast.makeText(context, "Error parsing JSON data.", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(context, "Couldn't get any JSON data.", Toast.LENGTH_SHORT).show();
        }

    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
    }
}
  

Комментарии:

1. Если у вас есть ошибки, опубликуйте их также. Также используйте Log.e(TAG, "error", e) для исключений. И константы должны быть определены как public static final String USER_ID = "userId";

2. Было бы полезно, если бы вы также публиковали свои ошибки

3. Я получаю слишком много данных для обработки ошибки, которая появляется в logcat

Ответ №1:

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

Вот что я нашел для решения исходной проблемы. Я помещаю комментарии внутри кода, чтобы помочь всем, кто хочет использовать код для своего следующего проекта.

     public class LoginActivity extends Activity { //Standard Activity code

Button BtnLaunchSigninActivity; //Button to click 
private EditText etLoginUserName, etLoginPassword; // data to submit

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


    etLoginUserName = (EditText) findViewById(R.id.etLoginUserName);
    etLoginPassword = (EditText) findViewById(R.id.etLoginPassword);

    BtnLaunchSigninActivity = (Button) findViewById(R.id.btnLoginSignin);


    BtnLaunchSigninActivity.setOnClickListener(onClickListener);
    }

private View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.btnLoginSignin) {
                    signin(v);
                }
            }
    };



public void signin(View v) {
    String userName = etLoginUserName.getText().toString();
    String passWord = etLoginPassword.getText().toString();

    Toast.makeText(this, "Signing In...", Toast.LENGTH_SHORT).show();
    new SignIn(this).execute(userName, passWord); // Send data to AsyncTask
}

private class SignIn extends AsyncTask<String, Void, String> {

    private Context context;  // context is for the SignIn()

    SignIn(Context context) {
        this.context = context;
    }

    protected void onPreExecute() {
    }

    @Override
    protected String doInBackground(String... arg0) {
        String userName = arg0[0];
        String passWord = arg0[1];

        String link;
        String data;
        BufferedReader bufferedReader;
        String resu<

        try {
            data = "?username="   URLEncoder.encode(userName, "UTF-8");
            data  = "amp;password="   URLEncoder.encode(passWord, "UTF-8");

            link = "url/login.php"   data;
            URL url = new URL(link);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();


            bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
            result = bufferedReader.readLine();
            return resu< // My php returns jsonobjects

        } catch (Exception e) {
            return new String("Exception: "   e.getMessage());
        }
    }


    @Override
    protected void onPostExecute(String result) {

        String jsonStr = resu< //turn object into string
        if (jsonStr != null) {
            try {

                JSONObject jsonObj = new JSONObject(jsonStr);
                String status = jsonObj.getString("status");
                String userid = jsonObj.getString("uid");
                String hash = jsonObj.getString("security");

                Log.d("tag", jsonObj.toString(4));

                if (status.equals("Good")) {
                    Toast.makeText(context, "Sign In successful.", Toast.LENGTH_SHORT).show();

//YOU HAVE TO USE JSONSTR TO GET USERID AND SECHASH FOR UPDATING SHARED PREFERENCES
//DUE TO ANY POSSIBLE DELAYS OF PROCESSING doInBackground() SEND JSON TO NEXT ACTIVITY TO SET PREFERENCES
//ADD THE STRING TO THE INTENT BELOW, THEN PROCESS THE DATA FOR SETTING SHAREDPREFERENCES IN THE NEXT ACTIVITY

                    Log.d("UserID",userid);
                    Log.d("SecHash", hash);

                    Intent intent = new Intent(LoginActivity.this, HomeActivity.class);
                    Bundle extras = new Bundle();
                    extras.putString("USERID",jsonObj.getString("uid"));
                    extras.putString("SECHASH",jsonObj.getString("security"));
                    extras.putString("USERID","userid");
                    extras.putString("SECHASH","hash");
                    intent.putExtras(extras);
                    startActivity(intent);

                } else if (status.equals("Wrong")) {
                    Toast.makeText(context, "Username/Password is incorrect, could not be verified. Sign In failed.", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(context, "Couldn't connect to remote database.", Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
                Toast.makeText(context, "Error parsing JSON data.", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(context, "Couldn't get any JSON data.", Toast.LENGTH_SHORT).show();
        }
    }
}
  

}

В следующем действии получите дополнения из намерения и добавьте их в SharedPreferences. Это все, что нужно для этого.

Спасибо всем за их помощь раньше. Я надеюсь, что это поможет другим, кто столкнется с такой же проблемой в будущем.

Ответ №2:

В doInBackground() вы определяете переменную locale, но используете переменную members

 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
if ((pref.contains(UserId)) amp;amp; (pref.contains(Date))) {
}
  

Поскольку вы назначаете только pref in onPostExecute() , вы будете получать NullPointerExceptions каждый раз. Также ctx имеет значение null и context даже не объявлено. Поэтому убедитесь, что вы pref определили как можно раньше.

 public class VerifyLogin extends AsyncTask<String, Void, String> {

    private final SharedPreferences pref;

    VerifyLogin() {
        pref = getSharedPreferences(IgidPreference, Context.MODE_PRIVATE);
    }

    [...]
}
  

Но, в конце концов, вы вообще не должны реализовывать это так. Вы потеряете свою активность здесь!

Комментарии:

1. Еще раз спасибо за помощь, тинн. Теперь я немного лучше понимаю, почему это не работает. Я опубликую завершенный код, как только исправлю все ошибки, чтобы другие могли его использовать.

2. Не забудьте сделать это как ответ, а не как обновление вопроса