Community » Forums » Android - Examples > Development of an Android App - MyTwitter Part 2
February 2, 2010 10:38:08 PM PST (31 weeks ago). Seen 6,841 times.
Photo Serete Itebete
Member since Dec 23, 2009
Location: Oakland
Posts: 16
Goal of the part 2;

1. Build a User Interface (UI) for our application
2. Connect the UI to the application logic including menu system through preferences
3. Jtwitter connection to the application to twitter (you must have an twitter account)



1. Build a User Interface for the our application

Take sometime to understand the UI aspect of an Android app with its
android especially within the eclipse IDE and this is the main part of this
section and there will be some logic to get stuff to work.

Designing the UI in eclipse if fairly easy with the builtin gui tool.

The goals achieved in the UI design.
1. Separation of UI from android implementation
2. Separation into sensible xml related files that carry out different functions in our application.

If you have not already drop the unzipped the images file available in the Part 1 of this tutorial and drag and drop the image files into the res/drawable folder.


Step 1: In the strings.xml file

Click on the strings.xml in the res/values folder and change the following.

Create the following by clicking the Add button and selecting String

element in the following Name and Value pairs;

Name: labelWhatsHappening
Value: Whats Happening?

Name: hintStatus
Value: Enter 160 characters status update

Name: labelUpdate
Value: update

strings.xml
Code:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MyTwitter!</string>
<string name="app_name">MyTwitter</string>
<string name="labelWhatsHappening">Whats Happening?</string>
<string name="hintStatus">Enter 160 characters status update</string>
<string name="labelUpdate">Update</string>
</resources>


Step 2: Create the following file: styles.xml in the res/values folder.

1. Click the add button and select Style/Theme and click "Ok" button and

create the with the following Name "Title" leave blank the parent field.
Create with add button with by selecting Item with a Name and Value

pair.Create the following;

Name: android:textSize
Value: 30sp

Name: android:typeface
Value: serif

Name: android:textColor
Value: @color/title


2. Click the add button and select Style/Theme and click "Ok" button and

create the with the following Name "Button" leave blank the parent field.
Create with add button with by selecting Item with a Name and Value

pair.Create the following;

Name: android:textSize
Value: 20sp

Name: android:padding
Value: 10pxs

styles.xml
Code:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Title">
<item name="android:textSize">30sp</item>
<item name="android:typeface">serif</item>
<item name="android:textColor">@color/title</item>
</style>
<style name="Button">
<item name="android:textSize">20sp</item>
<item name="android:padding">10px</item>
</style>
</resources>



Step 3: Create the following file: colors.xml in the res/values folder.

Click the add button and select Color and click "Ok" button and create the
with the following;

Name: title
Value: #FF00

Name: transparentBlue
Value: #60FF

colors.xml
Code:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color
name="title">#FF00</color>
<color name="transparentBlue">#60FF</color>
</resources>


Step 3: In the main.xml file

Use the properties tab and change these following properties with the

corresponding entries in the LinearLayout;
Background: @drawable/background
Orientation: vertical
Layout height: fill_parent
Layout width: fill_parent

Click on the textView ("Hello World, MyTwitter")
Change the following property and value;
Text: @string/labelWhatsHappening
Text size: 30sp
Gravity: center

Create EditText view and change the following properties;
Id: @+id/textStatus
Hint: @string/hintStatus
Background: @color/transparentBlue
Max Length: 160
Min lines: 4
Padding: 5px
Text color: #E6E6E6
Text color hint: #E6E6E6
Layout height: 100px
Layout margin 5px
Layout width: fill_parent

Create Button view and change the following properties;
Id: @+id/buttonUpdate
Background: @drawable/buttonbg
Text: @string/labelUpdate
Layout width: fill_parent

main.xml
Code:

<?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"
android:background="@drawable/background">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/labelWhatsHappening"
android:textSize="30sp"
android:gravity="center"
android:textStyle="bold" />
<EditText
android:id="@+id/textStatus"
android:typeface="serif"
android:textColorHint="#E6E6E6"
android:textColor="#E6E6E6"
android:maxLength="160"
android:hint="@string/hintStatus"
android:background="@color/transparentBlue"
android:layout_width="fill_parent"
android:layout_height="100px"
android:layout_margin="5px"
android:padding="5px"
android:minLines="4"></EditText>
<Button
android:layout_height="wrap_content"
android:id="@+id/buttonUpdate"
android:text="@string/labelUpdate"
android:layout_width="fill_parent"
android:background="@drawable/buttonbg"></Button>
</LinearLayout>


Step 4: Create a new folder in "res" folder and call the folder "xml" and then create a "prefs.xml" file inside the res/xml folder. Select the resource as Preference (radio button). Click the Add button and add the following :
i) the Key enter "username", Title enter "User Name" and Summary enter "Please provide username"
ii) the Key enter "password", Title enter "Password" and Summary enter "Please provide password"
prefs.xml
Code:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference
android:summary="Please provide user name"
android:title="User Name"
android:key="username"></EditTextPreference>
<EditTextPreference
android:summary="Please enter your password"
android:title="Password" android:password="true"
android:key="password"></EditTextPreference>
</PreferenceScreen>


Step 5: Working with JTwitter file (JTwitter.Jar)

1. Create inside the "res" folder another folder called "libs"
2. Download the Jtwitter.jar from the http://www.winterwell.com/software/jtwitter.php into the "libs" folder.
3. Right click the MyTwitter project and click on project properties > java
build path > (on the Libraries Tab)click "Add External Jar". click ok.

In your MyTwitter.java, you can create an instantiate of Twitter i.e. Twitter tweet; and if there are no errors on the line, you have full access of the JTwitter api and its associated methods.


2. Connect the UI to the application logic including a menu system through preferences


The MyTwitter.java file is pretty simple;Gets the content of the editView where you update your twitter status and listens to the update button for a click and simply fires off an intent to a menu (might not mean much now).

Note that SharedPreferences prefs is used to store preferences that are needed. To access the these preferences and instance of SharedPreferences prefs has to be created and accessed using the PreferenceManager.getDefaultSharedPreferences(context). Preferences here is stores the twitter username and password.

To activate the menu button(on the Phone's Hardware) onCreateOptionsMenu(Menu menu) is triggered in the following sequence:
Code:

@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}


To react to a click on the Menu button we call the method onOptionsItemSelected(MenuItem item) and react to the click.

I have included a number of Toast methods to look at content at various stages of the application.

MyTwitter.java
Code:

package com.example;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import winterwell.jtwitter.Twitter;

public class MyTwitter extends Activity implements OnClickListener{

static final String TAG = "MyTwitter";

Twitter twitter;
SharedPreferences prefs;

Button buttonUpdate;
Button buttonPrefs;
EditText textStatus;


@Override
public void onClick(View src) {

String status = textStatus.getText().toString();

Log.d(TAG, "Clicked on "+ status);

// Toast
Toast.makeText(this, textStatus.getText(), Toast.LENGTH_LONG).show();

// set twitter status
twitter.setStatus(status);

//reset status string
textStatus.setText("");
}
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// find views by id
buttonUpdate = (Button) findViewById(R.id.buttonUpdate);
textStatus = (EditText) findViewById(R.id.textStatus);

// Add listener
buttonUpdate.setOnClickListener(this);

//Initialize twitter
prefs = PreferenceManager.getDefaultSharedPreferences(this);
String username = prefs.getString("username", "n/a");
String password = prefs.getString("password", "n/a");
if (username != null && password != null){
twitter = new Twitter(username, password);
}


}

@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}

// Called when menu item is selected //
@Override
public boolean onOptionsItemSelected(MenuItem item){

switch(item.getItemId()){

case R.id.menuPrefs:
// Launch Prefs activity
Intent i = new Intent(MyTwitter.this, Prefs.class);
startActivity(i);
Log.d(TAG, "MenuPrefs starting Prefs");
Toast.makeText(MyTwitter.this, textStatus.getText(), Toast.LENGTH_LONG).show();
break;

}
return true;
}
}



Create Prefs.java class that extends PreferenceActivity interface and is used to load up preferences and the menu through the prefs.xml thats included in the res/xml.

Prefs.java
Code:

package com.example;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class Prefs extends PreferenceActivity{

@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

addPreferencesFromResource(R.xml.prefs);
}

}


In the AndroidManifest file do not forget to give internet permissions for the application to have access to the internet.

Also do not forget to register the second Activity namely "Prefs.java", preferably using the Eclipse XML Gui tool.

AndroidManifest.xml
Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.example">
<application
android:icon="@drawable/twitter_icon"
android:label="@string/app_name">
<activity
android:name=".MyTwitter"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="Prefs"></activity>
</application>
<uses-sdk android:minSdkVersion="3" />

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>



NOTE: Please excuse any errors including spelling mistakes that may be in this long tutorial, which should be used as a teaching guide.


ScreenShot

Home


Home with Menu


Menu with Username and Password



Source
http://marakana.com/static/tutorials/MyTwitter-Part2.zip
Edited 6 times. Last edit by Bob Gonza on Aug 31, 2010 at 2:10:17 PM (about 11 weeks ago).
February 3, 2010 1:50:49 AM PST (31 weeks ago)
Photo DIA Mamadou
TCHAP
Member since Jan 27, 2010
Posts: 3
coool,
that's really clear, very helpfull

thank's
March 15, 2010 9:50:39 AM PDT (25 weeks ago)
Photo Laam Lam
University
Member since Mar 15, 2010
Posts: 1
Hello,

Good work, but I have a problem with that, I always have this error message: "Activity ... is not responding"
What can I do?

Thanks.
March 16, 2010 6:23:28 PM PDT (25 weeks ago)
Photo Marko Gargenta
Marakana, Inc.
Member since Jan 19, 2007
Location: San Francisco
Posts: 95
You can read the log file and try to figure it out. It's impossible to answer this question without more details.
May 13, 2010 4:50:59 AM PDT (16 weeks ago)
Photo Surf Excelo
Member since May 13, 2010
Posts: 2
I didnt understand step 4 where you have mentioned - "Select the resource as Preference (radio button)"?

I was able to create a folder "xml" and a file "prefs.xml" in it, but do see any options to select resource as Preference. Am I missing out something? Please correct me!
Edited one time. Last edit by Surf Excelo on May 13, 2010 at 4:52:05 AM (about 11 weeks ago).
May 14, 2010 11:30:12 AM PDT (16 weeks ago)
Photo Surf Excelo
Member since May 13, 2010
Posts: 2
hi Marko .. could u please help me out.

I didnt understand step 4 where you have mentioned -

"Select the resource as Preference (radio button). Click the Add button and add the following :
i) the Key enter "username", Title enter "User Name" and Summary enter "Please provide username"
ii) the Key enter "password", Title enter "Password" and Summary enter "Please provide password"?


When an xml file is newly created in the "res/layout" folder, the xml editor comes up with a neat GUI giving me options to choose layout, view, etc.

However, when I create an xml file under "res/xml" folder, no such options are shown. Where do I select the resource as Preference (radio button)?

Pls help me proceed!
May 16, 2010 6:24:30 PM PDT (16 weeks ago)
Photo Marko Gargenta
Marakana, Inc.
Member since Jan 19, 2007
Location: San Francisco
Posts: 95
1. Use the Android XML wizard (icon looks like a+) to create a new Preferences XML file.
2. Open that file and a PreferenceScreen with two EditTextPreferences.
May 25, 2010 11:11:49 PM PDT (15 weeks ago)
Photo Anais Kuen
IT
Member since May 25, 2010
Posts: 1
I have one problem. When I put the update button, the application was forced to close due to exception error.
I'm not sure which is main reason...(DNS Server name, ...)
My browser on emulator is working. Also, I'm trying this code from behind a proxy based on 2.2(Froyo)SDK

Can you tell me what I'm missing

05-26 14:18:50.895: DEBUG/dalvikvm(116): GC_EXPLICIT freed 64 objects / 3552 bytes in 72ms
05-26 14:18:55.965: DEBUG/dalvikvm(109): GC_EXPLICIT freed 1127 objects / 74872 bytes in 138ms
05-26 14:18:59.676: DEBUG/dalvikvm(101): GC_FOR_MALLOC freed 7042 objects / 302040 bytes in 127ms
05-26 14:18:59.714: WARN/KeyCharacterMap(397): No keyboard for id 0
05-26 14:18:59.714: WARN/KeyCharacterMap(397): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
05-26 14:19:20.245: DEBUG/MyTwitter(397): Clicked on test
05-26 14:19:36.480: DEBUG/AndroidRuntime(397): Shutting down VM
05-26 14:19:36.480: WARN/dalvikvm(397): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
05-26 14:19:36.684: ERROR/AndroidRuntime(397): FATAL EXCEPTION: main
05-26 14:19:36.684: ERROR/AndroidRuntime(397): winterwell.jtwitter.TwitterException: java.net.UnknownHostException: Host is unresolved: api.twitter.com:80
Edited one time. Last edit by Anais Kuen on May 26, 2010 at 12:29:23 AM (about 11 weeks ago).
May 26, 2010 8:51:15 AM PDT (15 weeks ago)
Photo Marko Gargenta
Marakana, Inc.
Member since Jan 19, 2007
Location: San Francisco
Posts: 95

The answer is in the last line of the output you provided (and first line of what is meaningful to provide).

ERROR/AndroidRuntime(397): winterwell.jtwitter.TwitterException: java.net.UnknownHostException: Host is unresolved: api.twitter.com:80

So, your emulator cannot find api.twitter.com. It could be the proxy. It could be some other emulator setting. You can set twitter object to use IP address for this host instead (look it up in docs for jtwitter).

August 18, 2010 2:42:50 PM PDT (3 weeks ago)
Photo Bob Gonza
Tripeo
Member since Aug 18, 2010
Posts: 3
I am getting the error: "invalid resource directory name" on Step 5: Working with JTwitter file (JTwitter.Jar). Location = line 1. Type=Android AAPT Problem. Path=/MyTwitter/res

I downloaded JTwitter.jar and saved it to C:\0_code\myTwitter\MyTwitter-Part1\MyTwitter\res\libs\

Then, in Eclipse, I selected the libs folder and did a right mouse click and selected New -> File -> Advanced and checked "Link to file in the file system". Then, browsed for the file in the folder C:\0_code\myTwitter\MyTwitter-Part1\MyTwitter\res\libs\. Finally, I hit ok.

Could you please let me know what I am doing wrong?

Thanks,
Bob
I am using Eclipse 3.5.2 (Galileo) on a Windows XP machine with Service Pack 3
Edited 3 times. Last edit by Bob Gonza on Aug 18, 2010 at 3:06:19 PM (about 11 weeks ago).
August 18, 2010 5:41:36 PM PDT (3 weeks ago)
Photo Marko Gargenta
Marakana, Inc.
Member since Jan 19, 2007
Location: San Francisco
Posts: 95
You cannot just create a directory in /res/ and put stuff there - that is a special directory with special set of rules. Put jtwitter.jar in the root of your project instead.
August 30, 2010 4:08:22 PM PDT (one week ago)
Photo Bob Gonza
Tripeo
Member since Aug 18, 2010
Posts: 3
After updating MyTwitter.java with the code shown on this page, I am getting the following error:

R.id.menuPrefs cannot be resolved
R.menu cannot be resolved

Do I need to define new items in the XML files?

Thanks,
Bob
August 30, 2010 8:21:42 PM PDT (one week ago)
Photo Marko Gargenta
Marakana, Inc.
Member since Jan 19, 2007
Location: San Francisco
Posts: 95
You are missing the res/menu/menu.xml file, so your R is out of date because of that. Create the menu.xml.
August 31, 2010 2:10:17 PM PDT (one week ago)
Photo Bob Gonza
Tripeo
Member since Aug 18, 2010
Posts: 3
When I click the "Update" button, I am getting an exception. I have configured my Twitter user id and password in the settings menu. The status is NOT updated in my Twitter account.

Thread [<1> main] (Suspended (exception TwitterException))
URLConnectionHttpClient.post(String, Map, boolean) line: 269
Twitter.updateStatus(String, long) line: 2680
Twitter.updateStatus(String) line: 2625
Twitter.setStatus(String) line: 2404
MyTwitter.onClick(View) line: 42
Button(View).performClick() line: 2408
View$PerformClick.run() line: 8816
ViewRoot(Handler).handleCallback(Message) line: 587
ViewRoot(Handler).dispatchMessage(Message) line: 92
Looper.loop() line: 123
ActivityThread.main(String[]) line: 4627
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 868
ZygoteInit.main(String[]) line: 626
NativeStart.main(String[]) line: not available [native method]

URLConnectionHttpClient.class
throw new TwitterException(e);

Thanks,
Bob
PS: One thing I noticed is that the constructor for the Twitter class is deprecated. I am getting this warning: "The constructor Twitter(String, String) is deprecated"
Edited 2 times. Last edit by Bob Gonza on Aug 31, 2010 at 2:27:16 PM (about 11 weeks ago).