package jaangari.opensoft.iitkgp.jaankari; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.TargetApi; import android.app.AlertDialog; import android.app.LoaderManager.LoaderCallbacks; import android.content.CursorLoader; import android.content.DialogInterface; import android.content.Intent; import android.content.Loader; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.ContactsContract; import android.provider.MediaStore; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.text.TextUtils; import android.util.Base64; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import jaangari.opensoft.iitkgp.jaangari.R; /** * A login screen that offers login via email/password. */ public class LoginActivity extends FragmentActivity implements LoaderCallbacks<Cursor> { private static final int SELECT_PHOTO = 100; private static final int REQUEST_CAMERA = 101; private Pattern pattern; private Matcher matcher; private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; private static final String PASSWD_PATTERN= "(?=.*[0-9])(?=.*[a-z])" + "(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}"; private UserLoginTask mAuthTask = null; private DownloadTask mDownloadTask = null; // UI references. private AutoCompleteTextView mEmailView; private EditText mPasswordView; private View mProgressView; private View mLoginFormView; private ImageView mImageView; private MainFragment mainFragment; public void imagePick(View view){ final CharSequence[] items = {"Take Photo", "Choose from Library","Cancel"}; AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this); builder.setTitle("Add profile picture"); builder.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int item){ if(items[item].equals("Take Photo")){ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File f = new File(android.os.Environment.getExternalStorageDirectory(),"temp.jpg"); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)); startActivityForResult(intent,REQUEST_CAMERA); } else if(items[item].equals("Choose from Library")){ Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); photoPickerIntent.setType("image/*"); startActivityForResult(photoPickerIntent, SELECT_PHOTO); } else if(items[item].equals("Cancel")){ dialog.dismiss(); } } }); builder.show(); } private void writeProfilePic(Bitmap yourSelectedImage){ String path = android.os.Environment.getExternalStorageDirectory() + File.separator + getString(R.string.app_name); OutputStream fOut = null; File file = new File(path); if (!file.exists()) file.mkdirs(); path += File.separator + "proPics.jpg"; file = new File(path); try { fOut = new FileOutputStream(file); yourSelectedImage.compress(Bitmap.CompressFormat.JPEG, 85, fOut); fOut.flush(); fOut.close(); SharedPreferences sp = getSharedPreferences("Login", 0); SharedPreferences.Editor Ed = sp.edit(); Ed.putString("proPic", path); Ed.commit(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } private void setProfilePic(Bitmap yourSelectedImage , boolean set){ mImageView = (ImageView) findViewById(R.id.profile_pic); ViewGroup.LayoutParams params = mImageView.getLayoutParams(); params.height = 200; params.width = 200; mImageView.setLayoutParams(params); mImageView.setImageBitmap(yourSelectedImage); if(set) { writeProfilePic(yourSelectedImage); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { super.onActivityResult(requestCode, resultCode, imageReturnedIntent); switch(requestCode) { case REQUEST_CAMERA: File f = new File(Environment.getExternalStorageDirectory().toString()+"/temp.jpg"); try { Uri selectedImage = Uri.fromFile(f); Bitmap yourSelectedImage = decodeUri(selectedImage); setProfilePic(yourSelectedImage,true); } catch (Exception e) { e.printStackTrace(); } break; case SELECT_PHOTO: if(resultCode == RESULT_OK){ Uri selectedImage = imageReturnedIntent.getData(); Bitmap yourSelectedImage = null; try { yourSelectedImage = decodeUri(selectedImage); setProfilePic(yourSelectedImage,true); } catch (FileNotFoundException e) { e.printStackTrace(); } } } } private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o); // The new size we want to scale to final int REQUIRED_SIZE = 300; // Find the correct scale value. It should be the power of 2. int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) { break; } width_tmp /= 2; height_tmp /= 2; scale *= 2; } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // if(AppStatus.getInstance(this).isOnline()){ // Intent intent_service = new Intent(getApplicationContext(),GlobalDatabaseImageService.class); // startService(intent_service); // } // if(savedInstanceState==null){ // mainFragment = new MainFragment(); // getSupportFragmentManager() // .beginTransaction() // .add(android.R.id.content, mainFragment) // .commit(); // } // else{ // mainFragment = (MainFragment) getSupportFragmentManager() // .findFragmentById(android.R.id.content); // } SharedPreferences sp1 = this.getSharedPreferences("Login", 0); String sLogin = sp1.getString("sLogin", null); String path = sp1.getString("proPic",null); if (sLogin != null) { if (sLogin.equals("true")) { Intent intent = new Intent(getApplicationContext(), HomeScreen.class); startActivity(intent); } } else { setContentView(R.layout.activity_login); mDownloadTask = new DownloadTask(); mDownloadTask.execute((Void) null); if(path!=null){ try { Bitmap yourSelectedImage = BitmapFactory.decodeFile(path); setProfilePic(yourSelectedImage,false); }catch(Exception e){ Log.e("Profile Pic path","Error Could not find file at " + path); e.printStackTrace(); } } // 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; } }); mLoginFormView = findViewById(R.id.login_form); mProgressView = findViewById(R.id.login_progress); } } public void loginButton(View view){ Log.v(PRINT_SERVICE, "Attempting Login"); if (AppStatus.getInstance(this).isOnline()){ attemptLogin(); } else{ final AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this); builder.setTitle("Internet Connection not Available"); builder.setPositiveButton("Ok",new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.show(); } } 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; } Log.v(PRINT_SERVICE,"In Login"); // 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_field_required)); focusView = mPasswordView; cancel = true; } // Check for a valid email address. if (TextUtils.isEmpty(email)) { mEmailView.setError(getString(R.string.error_field_required)); focusView = mEmailView; cancel = true; } else if (!isEmailValid(email)) { mEmailView.setError(getString(R.string.error_invalid_email)); 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) { pattern = Pattern.compile(EMAIL_PATTERN); matcher = pattern.matcher(email); return matcher.matches(); } private boolean isPasswordValid(String password) { /* The password policy is: At least 8 chars Contains at least one digit Contains at least one lower alpha char and one upper alpha char Contains at least one char within a set of special chars (@#%$^ etc.) Does not contain space, tab, etc. */ pattern = Pattern.compile(PASSWD_PATTERN); matcher = pattern.matcher(password); return matcher.matches(); } /** * Shows the progress UI and hides the login form. */ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) 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; } 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 DownloadTask extends AsyncTask<Void, Void, Boolean>{ @Override protected Boolean doInBackground(Void... params) { Intent intent_service = new Intent(getApplicationContext(),GlobalDatabaseImageService.class); startService(intent_service); return true; } } 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) { try { HttpClient httpClient = new DefaultHttpClient(); // HttpPost httpPost = new HttpPost("http://10.132.235.67:3000/userLogin"); HttpPost httpPost = new HttpPost("http://"+getString(R.string.ip_address)+"login.php"); List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(2); nameValuePair.add(new BasicNameValuePair("email", mEmail)); nameValuePair.add(new BasicNameValuePair("passwd",mPassword)); httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair)); HttpResponse response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); InputStream inputStream = entity.getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } if("true\n".equals(sb.toString())){ return true; } else{ return false; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); return false; } catch (ClientProtocolException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } } @Override protected void onPostExecute(final Boolean success) { mAuthTask = null; showProgress(false); if (success) { SharedPreferences sp=getSharedPreferences("Login", 0); SharedPreferences.Editor Ed=sp.edit(); Ed.putString("sLogin","true"); Ed.putString("emailId",mEmail); Ed.putString("password",mPassword); Ed.commit(); Intent intent = new Intent(getApplicationContext(),HomeScreen.class); startActivity(intent); finish(); } else { mPasswordView.setError(getString(R.string.error_incorrect_password)); mPasswordView.requestFocus(); Log.i("Login","Incorrect Password"); } } @Override protected void onCancelled() { mAuthTask = null; showProgress(false); } } }