- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我想在我的应用中实现一个登录表单,因此我尝试使用 Android Studio 向导生成的代码来创建一个登录表单类型的新 Activity。我认为Eclipse生成的代码几乎是一样的。
不幸的是,生成的代码没有提供预期的结果:我创建了一个漂亮的简单登录表单,但无论密码是否正确,它都不会从登录表单中移出。
我还注意到没有创建“注册”表单。
看了一会,分析了代码,终于搞定了:)
请参阅下面的回复。
最佳答案
要让登录 Activity 在使用错误的用户/密码时失败,并在成功时转到主 Activity ,您需要对生成的代码进行以下更正:
AndroidManifest.xml
:
将以下代码从您的主要 Activity 移至 LoginActivity 部分:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
然后编辑 LoginActivity.java
并进行以下更改:
在 doInBackground
方法中,最后将返回值从 true
替换为 false
@Override
protected Boolean doInBackground(Void... params) {
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;
}
然后在onPostExecute
方法上,在finish();
之后添加一个新的intent:
@Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
finish();
Intent myIntent = new Intent(LoginActivity.this,MyMainActivity.class);
LoginActivity.this.startActivity(myIntent);
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
现在使用以下 user:password
凭据之一应该可以成功登录:
其他 user:password
尝试应该输入错误的密码并停留在登录页面。
我们现在将从数据库(SQLite)而不是静态变量获取登录信息。这将允许我们在设备上注册超过 1 个用户。
首先,新建一个User.java
类:
package com.clinsis.onlineresults.utils;
/**
* Created by csimon on 5/03/14.
*/
public class User {
public long userId;
public String username;
public String password;
public User(long userId, String username, String password){
this.userId=userId;
this.username=username;
this.password=password;
}
}
然后创建或更新您的 SQLite 助手(在我的例子中为 DBTools.java
)类:
package com.clinsis.onlineresults.utils;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by csimon on 12/11/13.
*/
public class DBTools extends SQLiteOpenHelper {
private final static int DB_VERSION = 10;
public DBTools(Context context) {
super(context, "myApp.db", null,DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String query = "create table logins (userId Integer primary key autoincrement, "+
" username text, password text)";
sqLiteDatabase.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
try{
System.out.println("UPGRADE DB oldVersion="+oldVersion+" - newVersion="+newVersion);
onCreate(sqLiteDatabase);
if (oldVersion<10){
String query = "create table logins (userId Integer primary key autoincrement, "+
" username text, password text)";
sqLiteDatabase.execSQL(query);
}
}
catch (Exception e){e.printStackTrace();}
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// super.onDowngrade(db, oldVersion, newVersion);
System.out.println("DOWNGRADE DB oldVersion="+oldVersion+" - newVersion="+newVersion);
}
public User insertUser (User queryValues){
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("username", queryValues.username);
values.put("password", queryValues.password);
queryValues.userId=database.insert("logins", null, values);
database.close();
return queryValues;
}
public int updateUserPassword (User queryValues){
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("username", queryValues.username);
values.put("password", queryValues.password);
queryValues.userId=database.insert("logins", null, values);
database.close();
return database.update("logins", values, "userId = ?", new String[] {String.valueOf(queryValues.userId)});
}
public User getUser (String username){
String query = "Select userId, password from logins where username ='"+username+"'";
User myUser = new User(0,username,"");
SQLiteDatabase database = this.getReadableDatabase();
Cursor cursor = database.rawQuery(query, null);
if (cursor.moveToFirst()){
do {
myUser.userId=cursor.getLong(0);
myUser.password=cursor.getString(1);
} while (cursor.moveToNext());
}
return myUser;
}
}
注意:DB_VERSION
用于检测数据库模式的升级/降级;)
然后修改LoginActivity.java如下:
添加以下导入:
import android.widget.Toast;
import com.clinsis.onlineresults.utils.DBTools;
import com.clinsis.onlineresults.utils.User;
添加一个新变量:
private User myUser;
删除 DUMMY_CREDENTIALS
变量声明。
在attemptLogin
方法中,调用UserLoginTask
时添加上下文:
mAuthTask = new UserLoginTask(email, password, this);
将内部 UserLoginTask 类替换为以下代码:
/**
* 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;
private final Context mContext;
UserLoginTask(String email, String password, Context context) {
mEmail = email;
mPassword = password;
mContext= context;
}
@Override
protected Boolean doInBackground(Void... params) {
DBTools dbTools=null;
try{
dbTools = new DBTools(mContext);
myUser = dbTools.getUser(mEmail);
if (myUser.userId>0) {
// Account exists, check password.
if (myUser.password.equals(mPassword))
return true;
else
return false;
} else {
myUser.password=mPassword;
return true;
}
} finally{
if (dbTools!=null)
dbTools.close();
}
// return false if no previous checks are true
return false;
}
@Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
if (myUser.userId>0){
finish();
Intent myIntent = new Intent(LoginActivity.this,ReportListActivity.class);
LoginActivity.this.startActivity(myIntent);
} else {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
DBTools dbTools=null;
try{
finish();
dbTools = new DBTools(mContext);
myUser=dbTools.insertUser(myUser);
Toast myToast = Toast.makeText(mContext,R.string.updatingReport, Toast.LENGTH_SHORT);
myToast.show();
Intent myIntent = new Intent(LoginActivity.this,ReportListActivity.class);
LoginActivity.this.startActivity(myIntent);
} finally{
if (dbTools!=null)
dbTools.close();
}
break;
case DialogInterface.BUTTON_NEGATIVE:
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this.mContext);
builder.setMessage(R.string.confirm_registry).setPositiveButton(R.string.yes, dialogClickListener)
.setNegativeButton(R.string.no, dialogClickListener).show();
}
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
@Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
在strings.xml
中,添加:
<string name="confirm_registry">Email not found. You want to create a new user with that email and password?</string>
<string name="yes">Yes</string>
<string name="no">No</string>
我希望我没有忘记任何事情......它对我来说很好:D
如果数据库中不存在电子邮件,它会建议注册它,否则它将检查电子邮件与密码。
玩得开心 Android :D
关于android - 示例及说明 : Android (Studio) Login Activity Template generated activity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22209046/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!