我的应用程序中有两个活动,一个是注册,另一个是一个人在创建帐户后将使用的活动。我要显示注册启动器活动,直到该人注册。我的代码:
private static boolean doesDatabaseExist(ContextWrapper context,
String dbName) {
File dbFile = context.getDatabasePath(dbName);
return true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (doesDatabaseExist == true) {
setContentView (R.layout.activity_sign_up) ; }
else {setContentView (R.layout.activity_name1); }}
这是正确的做法吗?
答案 0 :(得分:1)
可能不是最好的方法,它会使你的活动代码非常混乱。
您有两种选择 1 - 使用片段 - 使用两个片段而不是两个活动。当您的启动器活动加载时,您可以检查您的数据库是否存在,并从那里以编程方式加载包含所有视图代码的正确片段。
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (doesDatabaseExist()){
Name1Fragment fragment = new Name1Fragment ();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}else{
SignUpFragment fragment = new SignUpFragment ();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
http://developer.android.com/guide/components/fragments.html
2 - 使用启动画面 - 如果要将代码保存在单独的活动中而不是将其移动到片段,可以将主启动器设置为加载启动画面,然后检查数据库是否存在以及是否存在该值你可以启动正确的活动。
if (doesDatabaseExist()){
Intent intent = new Intent(this, Name1Activity.class);
startActivity(intent);
}else{
Intent intent = new Intent(this, SignUpActivity.class);
startActivity(intent);
}
http://developer.android.com/training/basics/firstapp/starting-activity.html
答案 1 :(得分:0)
从本质上讲,你有正确的想法......但这不是'正确'的实施。
'正确'的方法是使用一些看起来不是你的东西。
1)内容提供者(这是'包装'你的数据库并创建一个'简单'(定义良好)的界面来与你的数据库交互。(好'简单'......使用,编写它 - 可以是痛苦...直到你学会如何轻松制作它们,我的提示是在开始之前创建一个Schema文件,其中包含底层数据库的所有结构+我们使用过的ContentProvider Here is a sample Schema以前在我们的一些Coursera Android Concurrency / Mobile / Web Specialization课程中。))
2)Android的内置帐户管理支持。
使用ContentProvider和以下组件的要点是多用途的...您正在遵循最佳实践...您已经明确定义了“关注点分离”...您是一个“好邻居”应用程序允许用户在不希望应用程序同步时禁用应用程序同步...(保存电池/带宽/内存(从您的应用程序不运行服务24/7到其他方式同步))你没有实际上必须编写'sycning'机制或定时器或类似的东西......(你必须为你的同步过程编写自定义'逻辑'......这超出了这个问题的范围......)< / p>
当您只使用内置的SyncAdaptor /帐户机制时...您可以轻松检查用户在打开“主要活动”时是否拥有“帐户”,然后指示他们创建新帐户/在继续之前登录现有帐户。 (下面的代码实际上并没有像OAuth / Google / Facebook / StackOverflow等那样使用'基于网络的帐户'。但是如果你没有带有身份验证设置的网络服务器......这可能是一个很好的早期测试衡量直到你这样做,仍然允许你使用帐户机制/等。一旦你这样做,你显然必须改变它们以使用正确的信息。)
(为什么这种方法更好,有很多原因,我有点撇开它们,节省时间/空间......但我认为你会得到它的一般'要点'。)< / p>
2.1)扩展服务
的AccountAuthenticatorService2.2)扩展 AccountAuthenticatorActivity
的活动以下是两个'示例'文件,可以帮助您编写自己的版本。此代码已有多年历史,但仍应与您的需求“接近”。我在这段代码中使用了一些“技巧”(比如:ApplicationConstants),我不打算分享,因为它们不是最佳实践。但是这些文件的大致轮廓应该可以让你达到70%~80%+。
如果您在编写ContentProvider方面需要帮助,我个人的建议是购买/借用/获取Professional Android 2 Application Development 2nd Edition的副本,价格为~5.50美元。这是为Android 2.0编写的本书的旧版本,但是你要做的事情的核心部分从那以后没有改变,它大大降低了新版本的价格。这本书是我个人用来学习这些材料的书,我认为它是教你如何从头开始创建DB和ContentProvider的最佳工作之一。如果您不想购买图书,可以随时下载the Downloadable Code from this book。它有很多(在Chapter_7.txt中)内容提供者的不同部分的示例。但是,它没有解释每个人做了什么...所以它不会像两者一样有用。
package edu.vuum.mocca.authentication;
import edu.vuum.mocca.main.ApplicationConstants;
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager;
import android.accounts.NetworkErrorException;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
/**
* Skeleton example for how a functional SyncAdaptor's
* AccountAuthenticatorService would be implemented.
*
* @author Michael A. Walker
*
*/
public class AccountAuthenticatorService extends Service {
private static final String TAG = AccountAuthenticatorService.class
.getCanonicalName();
private static AccountAuthenticatorImpl sAccountAuthenticator = null;
private static String ACCOUNT_NAME;
private static String ACCOUNT_TYPE;
public AccountAuthenticatorService() {
super();
ACCOUNT_NAME = ApplicationConstants
.getValue(ApplicationConstants.ACCOUNT_NAME);
ACCOUNT_TYPE = ApplicationConstants
.getValue(ApplicationConstants.ACCOUNT_TYPE);
}
public static Account GetDefaultSyncAccount() {
final String accountName = ACCOUNT_NAME;
return new Account(accountName, ACCOUNT_TYPE);
}
/*
* (non-Javadoc)
*
* @see android.app.Service#onBind(android.content.Intent)
*/
@Override
public IBinder onBind(Intent intent) {
IBinder ret = null;
if (intent.getAction().equals(
android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT))
ret = getAuthenticator().getIBinder();
return ret;
}
/**
* Creates Singleton AccountAuthenticator Implementation.
* @return
*/
private AccountAuthenticatorImpl getAuthenticator() {
if (sAccountAuthenticator == null)
sAccountAuthenticator = new AccountAuthenticatorImpl(this);
return sAccountAuthenticator;
}
private static class AccountAuthenticatorImpl extends
AbstractAccountAuthenticator {
private Context mContext;
public AccountAuthenticatorImpl(Context context) {
super(context);
mContext = context;
}
/*
* (non-Javadoc)
*
* @see
* android.accounts.AbstractAccountAuthenticator#addAccount(android.
* accounts.AccountAuthenticatorResponse, java.lang.String,
* java.lang.String, java.lang.String[], android.os.Bundle)
*/
@Override
public Bundle addAccount(AccountAuthenticatorResponse response,
String accountType, String authTokenType,
String[] requiredFeatures, Bundle options)
throws NetworkErrorException {
Bundle result = new Bundle();
Intent i = new Intent(mContext, AccountLoginActivity.class);
i.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
result.putParcelable(AccountManager.KEY_INTENT, i);
return result;
}
/*
* (non-Javadoc)
*
* @see
* android.accounts.AbstractAccountAuthenticator#confirmCredentials(
* android.accounts.AccountAuthenticatorResponse,
* android.accounts.Account, android.os.Bundle)
*/
@Override
public Bundle confirmCredentials(AccountAuthenticatorResponse response,
Account account, Bundle options) {
// TODO Auto-generated method stub
Log.i(TAG, "confirmCredentials, not supported, exception thrown.");
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
*
* @see
* android.accounts.AbstractAccountAuthenticator#editProperties(android
* .accounts.AccountAuthenticatorResponse, java.lang.String)
*/
@Override
public Bundle editProperties(AccountAuthenticatorResponse response,
String accountType) {
// TODO Auto-generated method stub
Log.i(TAG, "editProperties, not supported, exception thrown.");
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
*
* @see
* android.accounts.AbstractAccountAuthenticator#getAuthToken(android
* .accounts.AccountAuthenticatorResponse, android.accounts.Account,
* java.lang.String, android.os.Bundle)
*/
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
// TODO Auto-generated method stub
Log.i(TAG, "getAuthToken");
Bundle bundle = new Bundle();
// TODO this works, but isn't really doing any valid auth.
bundle.putString(AccountManager.KEY_AUTHTOKEN, account.name);
return bundle;
}
/**
* Ask for a localized label for the given authTokenType.
* <p>
* may return null if not known.
*
* @see android.accounts.AbstractAccountAuthenticator#getAuthTokenLabel(java
* .lang.String)
*/
@Override
public String getAuthTokenLabel(String authTokenType) {
// TODO Auto-generated method stub
Log.i(TAG, "getAuthTokenLabel, not supported, exception thrown.");
throw new UnsupportedOperationException();
}
/*
* Checking features of the Account Not Supported currently.
*
* @see
* android.accounts.AbstractAccountAuthenticator#hasFeatures(android
* .accounts.AccountAuthenticatorResponse, android.accounts.Account,
* java.lang.String[])
*/
@Override
public Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account, String[] features)
throws NetworkErrorException {
Log.i(TAG, "hasFeatures, not supported, exception thrown.");
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
*
* @see
* android.accounts.AbstractAccountAuthenticator#updateCredentials(android
* .accounts.AccountAuthenticatorResponse, android.accounts.Account,
* java.lang.String, android.os.Bundle)
*/
@Override
public Bundle updateCredentials(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options) {
// TODO Auto-generated method stub
Log.i(TAG, "updateCredentials, not supported, exception thrown.");
throw new UnsupportedOperationException();
}
}
}
以下是一个示例AccountLoginActivity,它扩展了 AccountAuthenticatorActivity
package edu.vuum.mocca.authentication;
import java.util.Locale;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import edu.vanderbilt.mooc.mooc_cp.R;
import edu.vuum.mocca.main.ApplicationConstants;
/**
* Activity that gets Launched when Adding an Account to the SyncManager
* <p>
* An Activity to prompt for a Server Address, a UserName, and a Password. Uses
* these to verify user login credentials and to create a 'token' identifying
* the user account on the device.
*
* @author Michael A. Walker
* @Date 2012-11-23
*/
public class AccountLoginActivity extends AccountAuthenticatorActivity {
public final static String LOG_TAG = AccountLoginActivity.class.getCanonicalName();
/**************************************************************
* UI component variables
*************************************************************/
EditText mServerIP;
EditText mUsername;
EditText mPassword;
Button mLoginButton;
/**************************************************************
* Examples of constants for message passing on the AsyncTask
*************************************************************/
public final static String PARAM_AUTHTOKEN_TYPE = "";
public final static String PARAM_ACCOUNT_TYPE = "";
/*
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(LOG_TAG, "onCreate() called");
setContentView(R.layout.authenticator_layout);
mServerIP = (EditText) findViewById(R.id.server);
mUsername = (EditText) findViewById(R.id.username);
mPassword = (EditText) findViewById(R.id.password);
mLoginButton = (Button) findViewById(R.id.login);
// might be able to make this go away and be in the XML
// just easier to put here for now.
mLoginButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
loginButtonPressed(v);
}
});
}
// start the background threaded action to authenticate the user
public void loginButtonPressed(View v) {
Log.d(LOG_TAG, "onCreate() called");
String user = mUsername.getText().toString().trim()
.toLowerCase(Locale.ENGLISH);
String password = mPassword.getText().toString().trim()
.toLowerCase(Locale.ENGLISH);
String testValue = ApplicationConstants
.getValue(ApplicationConstants.ACCOUNT_TYPE);
if (testValue != null) {
Toast.makeText(getApplicationContext(), "testValue: " + testValue,
Toast.LENGTH_SHORT).show();
}
if (user.length() > 0 && password.length() > 0) {
LoginTask t = new LoginTask(AccountLoginActivity.this);
t.execute(user, password);
}
}
/**
* This is the background logic behind the user login credentials checking
*
* @author Michael A. Walker
*
*/
private class LoginTask extends AsyncTask<String, Void, Boolean> {
Context mContext;
ProgressDialog mDialog;
// constructor
LoginTask(Context c) {
Log.d(LOG_TAG, "LoginTask() constructed");
mContext = c;
mLoginButton.setEnabled(false);
// display a dialog with a spinner showing progress being worked on
mDialog = ProgressDialog.show(c, "",
getString(R.string.authenticating), true, false);
mDialog.setCancelable(true);
}
// Threaded background work (doesn't block UI)
@Override
public Boolean doInBackground(String... params) {
Log.d(LOG_TAG, "LoginTask.doInBackground() called");
String user = params[0];
String pass = params[1];
// TODO:Do something internetty HERE
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
Bundle result = null;
Account account = new Account(user,
mContext.getString(R.string.ACCOUNT_TYPE));
AccountManager am = AccountManager.get(mContext);
if (am.addAccountExplicitly(account, pass, null)) {
result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
setAccountAuthenticatorResult(result);
return true;
} else {
return false;
}
}
// post processing of login verification
@Override
public void onPostExecute(Boolean result) {
Log.d(LOG_TAG, "LoginTask.onPostExecute() called");
mLoginButton.setEnabled(true);
mDialog.dismiss();
if (result)
finish();
}
}
}