|
Posts
|
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/google_blue"
android:textColorLink="@color/google_red"
android:lineSpacingExtra="5sp"
android:padding="10dp"
/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/google_blue"
android:textColorLink="@color/google_red"
android:lineSpacingExtra="5sp"
android:padding="10dp"
android:layout_below="@id/textView1"
/>
text1 = (TextView) findViewById(R.id.textView1);
text2 = (TextView) findViewById(R.id.textView2);
text1.setText(
Html.fromHtml(
"We got rid of over 60 different privacy policies across Google and replaced them with one that’s a lot shorter and easier to read. " +
"<a href=\"http://www.google.co.uk/intl/en/policies\"> Find out more on our website.</a> "));
text1.setMovementMethod(LinkMovementMethod.getInstance());
text2.setText(
Html.fromHtml("Problems singning into your account?"
+ " Visit our " +
"<a href=\"http://support.google.com/?hl=en\">Help Centers</a> "
+ " to learn the ins-and-outs of Google products and solve any problems you encounter."));
text2.setMovementMethod(LinkMovementMethod.getInstance());
import android.text.TextPaint;
import android.text.style.URLSpan;
public class URLSpanNoUnderline extends URLSpan {
public URLSpanNoUnderline(String url) {
super(url);
}
@Override
public void updateDrawState(TextPaint tp) {
super.updateDrawState(tp);
tp.setUnderlineText(false);
}
}
private void stripUnderlines(TextView tv) {
Spannable s = (Spannable)tv.getText();
URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
for (URLSpan span: spans) {
int start = s.getSpanStart(span);
int end = s.getSpanEnd(span);
s.removeSpan(span);
span = new URLSpanNoUnderline(span.getURL());
s.setSpan(span, start, end, 0);
}
tv.setText(s);
}
stripUnderlines(text1);
stripUnderlines(text2);
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/refresh"
android:layout_gravity="center_horizontal"
android:text="@string/refresh"
android:layout_width="160dp"
android:layout_height="60dp"/>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@android:id/empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="No Data Connection" />
</LinearLayout>
<uses-permission android:name="android.permission.INTERNET" />
package com.android.bbcxmlfeed;
/**
* This class handles the mutator and accessors methods of a news item.
* For each news item the title and the description is assigned as a string value.
*
* @author Andrei
*
*/
public class XMLItem{
// class fields
private String title = null;
private String description = null;
/**
* Empty constructor.
*/
public XMLItem(){
}
/**
* Assign the news title to the title field.
* @param value Set item title.
*/
public void setTitle(String value){
title = value;
}
/**
* Assign the news description to the description field.
* @param value
*/
public void setDescription(String value){
description = value;
}
/**
* This method returns the news item title.
* @return News item title.
*/
public String getTitle(){
return title;
}
/**
* This method returns the news item description.
* @return News item description.
*/
public String getDescription(){
return description;
}
/**
* Create a toString which appends the news item title with the news item description.
*/
@Override
public String toString(){
return ("Title: "+title+"."+"\n"+"Description: "+description+"\n");
}
}
package com.android.bbcxmlfeed;
import java.util.List;
import java.util.Vector;
/**
* This class handles the XML feed by creating a list of all the news items
* with their titles and descriptions.
*
* @author Andrei
*
*/
public class XMLFeed {
// The fields.
private String title = null;
private String description = null;
// The vector array.
private List<XMLItem> itemList;
/**
* A list of items is created and assigned to a constructor with an initial empty initial size.
*/
public XMLFeed(){
itemList = new Vector<XMLItem>(0);
}
/**
* Adds a news item to the list of news items.
* @param item News item.
*/
public void addItem(XMLItem item){
itemList.add(item);
}
/**
* Gets and returns the news item location.
* @param location News item array location.
* @return The location in the array.
*/
public XMLItem getItem(int location){
return itemList.get(location);
}
/**
* Returns the list of new items.
* @return News items.
*/
public List<XMLItem> getList(){
return itemList;
}
/**
* Assigns string value to the news item title.
* @param value The title.
*/
public void setTitle(String value){
title = value;
}
/**
* Assigns a string value to the news item description.
* @param value The Description.
*/
public void setDescription(String value)
{
description = value;
}
/**
* Returns the title string.
* @return The title.
*/
public String getTitle()
{
return title;
}
/**
* Returns the description string.
* @return The description.
*/
public String getDescription()
{
return description;
}
}
package com.android.bbcxmlfeed;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* This class handles the SAX parsing.
*
* @author Andrei
*
*/
public class XMLHandler extends DefaultHandler {
static final int state_unknown = 0;
static final int state_title = 1;
static final int state_description = 2;
private int currentState = state_unknown;
private XMLFeed feed;
private XMLItem item;
private boolean itemFound = false;
/**
* Class constructor method.
*/
public XMLHandler(){
}
/**
* Gets the XML feed items.
* @return Feed items.
*/
public XMLFeed getFeed(){
return feed;
}
// SAX parsing elements from here
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
feed = new XMLFeed();
item = new XMLItem();
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
itemFound = true;
item = new XMLItem();
currentState = state_unknown;
}
else if (localName.equalsIgnoreCase("title")){
currentState = state_title;
}
else if (localName.equalsIgnoreCase("description")){
currentState = state_description;
}
else{
currentState = state_unknown;
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
feed.addItem(item);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
String strCharacters = new String(ch,start,length);
if (itemFound==true){
//If a news item is found, set it to the item parameter
switch(currentState){
case state_title:
item.setTitle(strCharacters);
break;
case state_description:
item.setDescription(strCharacters);
break;
default:
break;
}
}
else{
// No news items found, it a feeds parameter
switch(currentState){
case state_title:
feed.setTitle(strCharacters);
break;
case state_description:
feed.setDescription(strCharacters);
break;
default:
break;
}
}
currentState = state_unknown;
}
}
package com.android.bbcxmlfeed;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import com.android.testfeed3.R;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
/**
* The application's main activity. Handles the onCreate, onResume,
* refresh and getNews methods - which ultimately display the news items.
*
* @author Andrei
*
*/
public class BBCXMLReader extends ListActivity {
private static final int THREAD_FINISHED = 0;
private XMLFeed myXMLFeed = null;
private ProgressDialog progressDialog;
private Button refreshFeed;
private boolean resumeHasRun = false;
//Handler handler = new Handler();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//
processThread();
//Get the UI controls - in this case we only have the refresh button.
initControls();
}
/**
* This method is used to handle all the UI controls. In this case it only deals with the refresh button.
*/
public void initControls(){
refreshFeed = (Button) findViewById(R.id.refresh);
refreshFeed.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v){
processThread();
}
});
}
/**
* Tracks to see if onResume has been called before,
* to avoid for both onResume and onCreate to be called.
*/
protected void onResume() {
super.onResume();
if (!resumeHasRun){
resumeHasRun = true;
return;
}
processThread();
}
/**
* This method is used as a background processor for the app.
* It shows the progress dialog and it retrieves the news items.
*
*/
protected void processThread() {
//Show a simple progress dialog.
progressDialog = ProgressDialog.show(BBCXMLReader.this, "",
"Fetching news items...", true, false);
//Create a new thread.
Thread t = new Thread(){
public void run(){
//Retrieve the news items from the BBC link.
getNews();
//Sends message to the handler so it updates the UI.
handler.sendMessage(Message.obtain(handler, THREAD_FINISHED));;
}
};
t.start();
}
/**
* The handler mainly deals with the UI of the application.
* It handles the loading of the ListView with all the items in it,
* and also it handles the dismissal of the progress dialog after the UI has been loaded.
*/
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case THREAD_FINISHED:
UI();
progressDialog.dismiss();
break;
};
};
};
/**
* This method loads the ListView UI.
*/
private void UI(){
if (myXMLFeed!=null){
ArrayAdapter<XMLItem> adapter =
new ArrayAdapter<XMLItem>(this,
android.R.layout.simple_list_item_1,myXMLFeed.getList());
setListAdapter(adapter);
}
}
/**
* This method parses the data from the BBC XML link, via the SAX Parser and XMLHandler class.
* @see XMLHandler
*/
private void getNews(){
try {
URL xmlUrl = new URL("http://feeds.bbci.co.uk/news/uk/rss.xml");
SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
XMLReader myXMLReader = mySAXParser.getXMLReader();
XMLHandler myXMLHandler = new XMLHandler();
myXMLReader.setContentHandler(myXMLHandler);
InputSource myInputSource = new InputSource(xmlUrl.openStream());
myXMLReader.parse(myInputSource);
myXMLFeed = myXMLHandler.getFeed();
}
//catch a bunch of exceptions
catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
volumeManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int maxVolume = volumeManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
int curVolume = volumeManager.getStreamVolume(AudioManager.STREAM_MUSIC);
SeekBar volumeControl = (SeekBar)findViewById(R.id.VolumeBar);
volumeControl.setMax(maxVolume);
volumeControl.setProgress(curVolume);
volumeControl.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
volumeManager.setStreamVolume(AudioManager.STREAM_MUSIC, arg1, 0);
}
});
private void initControls() {
inputText = (EditText) findViewById(R.id.InputField);
speakUp = (Button) findViewById(R.id.SpeakButton);
clearText = (Button) findViewById(R.id.ClearField);
speakUp.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
SpeakText(v);
}
});
clearText.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
Clear(v);
}
});
}
private void SpeakText(View v) {
String text = inputText.getText().toString();
if(text!=null && text.length()>0) {
tts.speak(text, TextToSpeech.QUEUE_ADD, null);
}
}
private void Clear(View v) {
inputText.setText("");
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
tts = new TextToSpeech(this, this);
}
else {
// missing data, install it
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
}
}
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
Toast.makeText(SpeakUpActivity.this,
"Text-To-Speech engine is initialized", Toast.LENGTH_LONG).show();
}
else if (status == TextToSpeech.ERROR) {
Toast.makeText(SpeakUpActivity.this,
"Error occurred while initializing Text-To-Speech engine", Toast.LENGTH_LONG).show();
}
}
package com.android.database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
/**
* Adapts the database to deal with the front end.
*
* @author Andrei
*
*/
public class DatabaseAdapter {
//Table name
private static final String LOGIN_TABLE = "user";
//Table unique id
public static final String COL_ID = "id";
//Table username and password columns
public static final String COL_USERNAME = "username";
public static final String COL_PASSWORD = "password";
private Context context;
private SQLiteDatabase database;
private DatabaseHelper dbHelper;
/**
* The adapter constructor.
* @param context
*/
public DatabaseAdapter(Context context) {
this.context = context;
}
/**
* Creates the database helper and gets the database.
*
* @return
* @throws SQLException
*/
public DatabaseAdapter open() throws SQLException {
dbHelper = new DatabaseHelper(context);
database = dbHelper.getWritableDatabase();
return this;
}
/**
* Closes the database.
*/
public void close() {
dbHelper.close();
}
/**
* Creates the user name and password.
*
* @param username The username.
* @param password The password.
* @return
*/
public long createUser(String username, String password) {
ContentValues initialValues = createUserTableContentValues(username, password);
return database.insert(LOGIN_TABLE, null, initialValues);
}
/**
* Removes a user's details given an id.
*
* @param rowId Column id.
* @return
*/
public boolean deleteUser(long rowId) {
return database.delete(LOGIN_TABLE, COL_ID + "=" + rowId, null) > 0;
}
public boolean updateUserTable(long rowId, String username, String password) {
ContentValues updateValues = createUserTableContentValues(username, password);
return database.update(LOGIN_TABLE, updateValues, COL_ID + "=" + rowId, null) > 0;
}
/**
* Retrieves the details of all the users stored in the login table.
*
* @return
*/
public Cursor fetchAllUsers() {
return database.query(LOGIN_TABLE, new String[] { COL_ID, COL_USERNAME,
COL_PASSWORD }, null, null, null, null, null);
}
/**
* Retrieves the details of a specific user, given a username and password.
*
* @return
*/
public Cursor fetchUser(String username, String password) {
Cursor myCursor = database.query(LOGIN_TABLE,
new String[] { COL_ID, COL_USERNAME, COL_PASSWORD },
COL_USERNAME + "='" + username + "' AND " +
COL_PASSWORD + "='" + password + "'", null, null, null, null);
if (myCursor != null) {
myCursor.moveToFirst();
}
return myCursor;
}
/**
* Returns the table details given a row id.
* @param rowId The table row id.
* @return
* @throws SQLException
*/
public Cursor fetchUserById(long rowId) throws SQLException {
Cursor myCursor = database.query(LOGIN_TABLE,
new String[] { COL_ID, COL_USERNAME, COL_PASSWORD },
COL_ID + "=" + rowId, null, null, null, null);
if (myCursor != null) {
myCursor.moveToFirst();
}
return myCursor;
}
/**
* Stores the username and password upon creation of new login details.
* @param username The user name.
* @param password The password.
* @return The entered values.
*/
private ContentValues createUserTableContentValues(String username, String password) {
ContentValues values = new ContentValues();
values.put(COL_USERNAME, username);
values.put(COL_PASSWORD, password);
return values;
}
}
/**
* The main application activity which serves as a login page.
* @author Andrei
*
*/
public class login extends Activity {
public static final String MY_PREFS = "SharedPreferences";
private DatabaseAdapter dbHelper;
private EditText theUsername;
private EditText thePassword;
private Button loginButton;
private Button registerButton;
private Button clearButton;
private Button exitButton;
private CheckBox rememberDetails;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences mySharedPreferences = getSharedPreferences(MY_PREFS, 0);
Editor editor = mySharedPreferences.edit();
editor.putLong("uid", 0);
editor.commit();
dbHelper = new DatabaseAdapter(this);
dbHelper.open();
setContentView(R.layout.main);
initControls();
}
private void initControls() {
//Set the activity layout.
theUsername = (EditText) findViewById(R.id.Username);
thePassword = (EditText) findViewById(R.id.Password);
loginButton = (Button) findViewById(R.id.Login);
registerButton = (Button) findViewById(R.id.Register);
clearButton = (Button) findViewById(R.id.Clear);
exitButton = (Button) findViewById(R.id.Exit);
rememberDetails = (CheckBox) findViewById(R.id.RememberMe);
//Create touch listeners for all buttons.
loginButton.setOnClickListener(new Button.OnClickListener(){
public void onClick (View v){
LogMeIn(v);
}
});
registerButton.setOnClickListener(new Button.OnClickListener(){
public void onClick (View v){
Register(v);
}
});
clearButton.setOnClickListener(new Button.OnClickListener(){
public void onClick (View v){
ClearForm();
}
});
exitButton.setOnClickListener(new Button.OnClickListener(){
public void onClick (View v){
Exit();
}
});
//Create remember password check box listener.
rememberDetails.setOnClickListener(new CheckBox.OnClickListener(){
public void onClick (View v){
RememberMe();
}
});
//Handle remember password preferences.
SharedPreferences prefs = getSharedPreferences(MY_PREFS, 0);
String thisUsername = prefs.getString("username", "");
String thisPassword = prefs.getString("password", "");
boolean thisRemember = prefs.getBoolean("remember", false);
if(thisRemember) {
theUsername.setText(thisUsername);
thePassword.setText(thisPassword);
rememberDetails.setChecked(thisRemember);
}
}
/**
* Deals with Exit option - exits the application.
*/
private void Exit()
{
finish();
}
/**
* Clears the login form.
*/
private void ClearForm() {
saveLoggedInUId(0,"","");
theUsername.setText("");
thePassword.setText("");
}
/**
* Handles the remember password option.
*/
private void RememberMe() {
boolean thisRemember = rememberDetails.isChecked();
SharedPreferences prefs = getSharedPreferences(MY_PREFS, 0);
Editor editor = prefs.edit();
editor.putBoolean("remember", thisRemember);
editor.commit();
}
/**
* This method handles the user login process.
* @param v
*/
private void LogMeIn(View v) {
//Get the username and password
String thisUsername = theUsername.getText().toString();
String thisPassword = thePassword.getText().toString();
//Assign the hash to the password
thisPassword = md5(thisPassword);
// Check the existing user name and password database
Cursor theUser = dbHelper.fetchUser(thisUsername, thisPassword);
if (theUser != null) {
startManagingCursor(theUser);
if (theUser.getCount() > 0) {
saveLoggedInUId(theUser.getLong(theUser.getColumnIndex(DatabaseAdapter.COL_ID)), thisUsername, thePassword.getText().toString());
stopManagingCursor(theUser);
theUser.close();
Intent i = new Intent(v.getContext(), Helloworld.class);
startActivity(i);
}
//Returns appropriate message if no match is made
else {
Toast.makeText(getApplicationContext(),
"You have entered an incorrect username or password.",
Toast.LENGTH_SHORT).show();
saveLoggedInUId(0, "", "");
}
stopManagingCursor(theUser);
theUser.close();
}
else {
Toast.makeText(getApplicationContext(),
"Database query error",
Toast.LENGTH_SHORT).show();
}
}
/**
* Open the Registration activity.
* @param v
*/
private void Register(View v)
{
Intent i = new Intent(v.getContext(), Register.class);
startActivity(i);
}
private void saveLoggedInUId(long id, String username, String password) {
SharedPreferences settings = getSharedPreferences(MY_PREFS, 0);
Editor myEditor = settings.edit();
myEditor.putLong("uid", id);
myEditor.putString("username", username);
myEditor.putString("password", password);
boolean rememberThis = rememberDetails.isChecked();
myEditor.putBoolean("rememberThis", rememberThis);
myEditor.commit();
}
The full source code for the Login class can be found here. /**
* Handles the registration process.
* @param v
*/
private void RegisterMe(View v)
{
//Get user details.
String username = newUsername.getText().toString();
String password = newPassword.getText().toString();
String confirmpassword = newConfiPass.getText().toString();
//Check if all fields have been completed.
if (username.equals("") || password.equals("")){
Toast.makeText(getApplicationContext(),
"Please ensure all fields have been completed.",
Toast.LENGTH_SHORT).show();
return;
}
//Check password match.
if (!password.equals(confirmpassword)) {
Toast.makeText(getApplicationContext(),
"The password does not match.",
Toast.LENGTH_SHORT).show();
newPassword.setText("");
newConfiPass.setText("");
return;
}
//Encrypt password with MD5.
password = md5(password);
//Check database for existing users.
Cursor user = dbHelper.fetchUser(username, password);
if (user == null) {
Toast.makeText(getApplicationContext(), "Database query error",
Toast.LENGTH_SHORT).show();
} else {
startManagingCursor(user);
//Check for duplicate usernames
if (user.getCount() > 0) {
Toast.makeText(getApplicationContext(), "The username is already registered",
Toast.LENGTH_SHORT).show();
stopManagingCursor(user);
user.close();
return;
}
stopManagingCursor(user);
user.close();
user = dbHelper.fetchUser(username, password);
if (user == null) {
Toast.makeText(getApplicationContext(), "Database query error",
Toast.LENGTH_SHORT).show();
return;
} else {
startManagingCursor(user);
if (user.getCount() > 0) {
Toast.makeText(getApplicationContext(), "The username is already registered",
Toast.LENGTH_SHORT).show();
stopManagingCursor(user);
user.close();
return;
}
stopManagingCursor(user);
user.close();
}
//Create the new username.
long id = dbHelper.createUser(username, password);
if (id > 0) {
Toast.makeText(getApplicationContext(), "Your username was created",
Toast.LENGTH_SHORT).show();
saveLoggedInUId(id, username, newPassword.getText().toString());
Intent i = new Intent(v.getContext(), Helloworld.class);
startActivity(i);
finish();
} else {
Toast.makeText(getApplicationContext(), "Failt to create new username",
Toast.LENGTH_SHORT).show();
}
}
}
|
Repositories
|
|
Info
|
|
Tweets
|
|
Photos
|
|
Checkins
|
Mobile Apps Developer, Technical Architect, Developer Team Lead.
UX Enthusiast.
Amateur Photographer.