How to setup static website on Amazon AWS S3?

All instructions here:

https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html

Remember that if you bought your domain name elsewhere like godaddy.com, then you need to tell godaddy to point its NS records to Amazon Route53 NS records.

Settings > Name Servers > Custom: Here add the Name Servers that you see in AWS Console > Route53 > Your Hosted Zone > NS Values

Here’s another reference (does not contain info. about the DNS part):

http://aws.amazon.com/blogs/aws/root-domain-website-hosting-for-amazon-s3/

 

How do i integrate Facebook Login in Android app?

The Activity Layout File

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
xmlns:facebook=”http://schemas.android.com/apk/res-auto&#8221;
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:gravity=”center_horizontal”
android:orientation=”vertical”
android:padding=”20dp” >

<com.facebook.login.widget.LoginButton
android:id=”@+id/login_button”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_gravity=”center_horizontal”
android:layout_marginTop=”30dp”
android:layout_marginBottom=”30dp” />

</LinearLayout>

===

The Activity

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;

import com.yourapp.R;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.Profile;
import com.facebook.login.LoginResult;

public class FBConnect1 extends Activity {

private com.facebook.login.widget.LoginButton loginButton;
private Button logoutBtn;
private Button closeBtn;
private TextView userName;

boolean isFetching = false;
CallbackManager callbackManager;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println(“FACEBOOK STARTING”);
FacebookSdk.sdkInitialize(getApplicationContext());

setContentView(R.layout.activity_fbconnect1);

callbackManager = CallbackManager.Factory.create();

loginButton = (com.facebook.login.widget.LoginButton) findViewById(R.id.login_button);

loginButton.setReadPermissions(“user_friends”);
// If using in a fragment
// loginButton.setFragment(this);
// Other app specific specialization

// Callback registration
loginButton.registerCallback(callbackManager, new FacebookCallback() {
@Override
public void onSuccess(LoginResult loginResult) {
System.out.println(“SUCCESS FACEBOOK LOGIN”);

Profile profile = Profile.getCurrentProfile();
System.out.println(“FACEBOOK PROFILE onSuccess ” + profile);
System.out.println(“FACEBOOK USER: ” + profile.getName());

// Get User Name
//mTextDetails.setText(profile.getName() + “”);
//loginResult.
// App code
}

@Override
public void onCancel() {

System.out.println(“FACEBOOK SUCCESS FACEBOOK CANCELED”);
// App code
}

@Override
public void onError(FacebookException exception) {

System.out.println(“FACEBOOK ERROR : ” + exception);
// App code
}
});
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}

}

How do i connect to development/local MySQL in Google App Engine (GAE) application?

Place mysql-connector jdbc jar here:

<googleAppEngineSDKBundle>\<appEngineSDK>\lib\impl\

You can find location of your appEngineSDKBundle by: Project>Properties>Google>SDK>Configure

Configure Cloud/Local MySQL

Project>Properties> Google>  App Engine>

Enable (checkbox yes) Google Cloud SQL

App Engine SQL Instance – put any junk values here even if u don’t have Cloud SQL yet.

Select Radio button Use MySQL Instance, and hit configure link to configure.

Click OK and close

The Code

import com.google.cloud.sql.jdbc.Connection; //This is your Connection Class.

Class.forName(“com.mysql.jdbc.Driver”);

conn = (Connection) DriverManager.getConnection(“jdbc:google:rdbms://localhost:3306/root”);

Even though your code seems to point to Cloud, while running locally based on all the above configuration, it will actually point to your local MySQL instance.

See here: http://stackoverflow.com/questions/8952696/java-google-app-engine-and-google-cloud-sql-running-on-local-dev-server (Mark Scheel’s explanation)

How do i develop Android applications on Mac OS?

Install Eclipse IDE

Add ADT Plugin

https://dl-ssl.google.com/android/eclipse

Download Android SDK

http://developer.android.com/sdk

Use the SDK Manager, to update Packages.

Configure Android SDK path in Eclipse Preferences.

Connected to Wi-Fi, but No Internet Access

Problem Statement

You are connected to a wi-fi network (or something similar), yet there is no internet access. You may also see ‘No Internet’ message when you hover over  your network connection icon at bottom right toolbar.

Solution

  1. Control Panel > Manage Wireless Networks > Select your wirless network > Click Adapter Properties (usually available at the top)
  2. From the popup window, choose Internet Protocol V6 and Internet > Click Properties.
  3. Make sure that Obtain IP Address Automatically and Obtain DNS automatically is selected.
  4. Repeat steps 2 n 3 for: Internet Protocol V4
  5. Disconnect and Connect to your wi-fi connection again.

That’s It

How to set bucket policies for Amazon AWS S3?

In Amazon AWS S3 Console > Select your bucket > hit Properties tab on right-hand side > Edit bucket policies button

Public bucket policy:

{
“Version”:”2008-10-17″,
“Statement”:[{
“Sid”:”MyAllowPublicRead”,
“Effect”:”Allow”,
“Principal”: {
“AWS”: “*”
},
“Action”:[“s3:GetObject”],
“Resource”:[“arn:aws:s3:::YOUR_BUCKET/*”
]
}
]
}

 

 

How to secure Amazon AWS S3 bucket and access from Android app?

Two possible approaches – differing in how credentials are used (i.e what kind of credentials are embedded in your app).

EMBEDDING COGNITO IDENTITY POOL ID IN APPLICATION

The advantage of this approach is that you do not have to embed the Access Key, Secret Key in your code – for example in a android application. Amazon creates temporary credentials for use by your client application.

Create Cognito Pool Id

In Amazon AWS Console > Cognito:

Provide a name, and it will create two roles for you too:

  • Unauthenticated Users Role
  • Authenticated Users Role (Google/Twitter/Facebook login etc.)

Create a Policy:

In Amazon AWS Console > IAM > Policies

{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Action”: [
“s3:Get*”
],
“Resource”: “arn:aws:s3:::YOUR_BUCKET/*”
}
]
}

 

Attach the Policy to Roles created previously

In AWS Console > IAM > Roles

Attach Policy to both roles (or one of them depending on authenticated or unauthenticated access requirements)

Note: You can attach Roles to this Policy as well (its the same thing)

Code

package com.s3test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;

public class S3Test {

static AWSCredentials credentials = null;
static String bucketName = “BUCKET_NAME”;
static String key = “YOUR_FILE_IN_BUCKET”;

public static void main(String[] args) {

CognitoCachingCredentialsProvider cognitoProvider = new CognitoCachingCredentialsProvider(

    ctx, // get the context for the current activity

    “whatever:whatever-whatever-whatever..”, /* Identity Pool ID */

    Regions.US_EAST_1 /* Region */

);

AmazonS3 s3 = new AmazonS3Client(cognitoProvider);

Region usWest2 = Region.getRegion(Regions.US_WEST_1);//Make sure region is same as where S3 bucket exists
s3.setRegion(usWest2);

S3Object object = s3.getObject(new GetObjectRequest(bucketName, key));
System.out.println(“Content-Type: ” + object.getObjectMetadata().getContentType());
try {
displayTextInputStream(object.getObjectContent());
} catch (IOException e) {

e.printStackTrace();
}
}

private static void displayTextInputStream(InputStream input) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
while (true) {
String line = reader.readLine();
if (line == null) break;

System.out.println(” ” + line);
}
System.out.println();
}
}

 

 

EMBEDDING ACCESS_KEY AND SECRET_KEY IN APPLICATION

Create a IAM User

In Amazon AWS Console > IAM :

Create a User, you will get Access Key Id, and Secret Key for that user.

Create a Policy

In Amazon AWS Console > IAM > Policies

{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Action”: [
“s3:Get*”
],
“Resource”: “arn:aws:s3:::YOUR_BUCKET/*”
}
]
}

Attach this Policy to the User (Or Group, if you added user to a Group)

Use Attach button (available in the policy page) for this.

All set – Now access S3 Bucket from Java Program:

NOTE: You will need AWS-JAVA_SDK in path eg: aws-java-sdk-1.9.17.jar

package com.s3test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;

public class S3Test {

static AWSCredentials credentials = null;
static String bucketName = “BUCKET_NAME”;
static String key = “YOUR_FILE_IN_BUCKET”;

public static void main(String[] args) {
//– credentials = new ProfileCredentialsProvider()..getCredentials();
credentials = new BasicAWSCredentials(“USER_ACCESS_KEY_ID”, “USER_SECRET_ACCESS_KEY”);
AmazonS3 s3 = new AmazonS3Client(credentials);
Region usWest2 = Region.getRegion(Regions.US_WEST_1);//Make sure region is same as where S3 bucket exists
s3.setRegion(usWest2);

S3Object object = s3.getObject(new GetObjectRequest(bucketName, key));
System.out.println(“Content-Type: ” + object.getObjectMetadata().getContentType());
try {
displayTextInputStream(object.getObjectContent());
} catch (IOException e) {

e.printStackTrace();
}
}

private static void displayTextInputStream(InputStream input) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
while (true) {
String line = reader.readLine();
if (line == null) break;

System.out.println(” ” + line);
}
System.out.println();
}
}

 

That’s It

How to add Twitter Login (Authentication) to Android Mobile App?

NOTE: This is not the best way to go about it becz:

  • This opens a new browser window for login
  • After logging in, the app’s callback is not being invoked.

Step 0: Create a Twitter App

Create a Twitter App here: https://apps.twitter.com/

Make sure you:

  • Put some URL in Callback URL – it wouldn’t matter what you put there.
  • Sign in with Twitter is Yes.

You will get Consumer Key and Access Key here.

Step 1: Download Twitter 4j

Download jar from here: http://twitter4j.org/en/index.html

Add jar to your Mobile Android App. You can put it in Android App Prokect > lib directory.

Step 2: Create Twitter Activity Java Class, Layout XML, Update Android Manifest

package com.whatever.activity;

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.whatever.R;

public class TwitterActivity extends Activity {

Twitter twitter;
RequestToken requestToken;
//Please put the values of consumerKy and consumerSecret of your app
public final static String consumerKey = “YOUR_TWITTER_CONSUMER_KEY;
public final static String consumerSecret = “YOUR_TWITTER_CONSUMER_SECRET_KEY”;
private final String CALLBACKURL = “T4J_OAuth://callback_main”;

//Callback URL that tells the WebView to load this activity when it finishes with twitter.com. (see manifest)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_twitter);

MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();
}

void OAuthLogin() {
try {
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(consumerKey, consumerSecret);
requestToken = twitter.getOAuthRequestToken(CALLBACKURL);
String authUrl = requestToken.getAuthenticationURL();
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse(authUrl)));
} catch (TwitterException ex) {
//Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show();
Log.e(“in Main.OAuthLogin”, ex.getMessage());
}
}
/*
* – Called when WebView calls your activity back.(This happens when the user has finished signing in)
* – Extracts the verifier from the URI received
* – Extracts the token and secret from the URL
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Uri uri = intent.getData();
try {
String verifier = uri.getQueryParameter(“oauth_verifier”);
AccessToken accessToken = twitter.getOAuthAccessToken(requestToken,
verifier);
String token = accessToken.getToken(), secret = accessToken
.getTokenSecret();
//–displayTimeLine(token, secret); //after everything, display the first tweet

} catch (TwitterException ex) {
Log.e(“Main.onNewIntent”, “” + ex.getMessage());
}

}

private class MyAsyncTask extends AsyncTask<String, Void, String> {

@Override
protected String doInBackground(String… params) {
OAuthLogin();
return null;
}

@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
//
}

}
}

 

Twitter Layout XML: res\layout\activity_twitter.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
xmlns:facebook=”http://schemas.android.com/apk/res-auto&#8221;
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:gravity=”center_horizontal”
android:orientation=”vertical”
android:padding=”20dp” >

<LinearLayout

android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:orientation=”vertical” >

<TextView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Hello” />
</LinearLayout>

</LinearLayout>

 

Make sure Manifest file of your Android App has the following:

<uses-permission android:name=”android.permission.INTERNET” />
<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />

….

<activity
android:name=”com.whatever.activity.TwitterActivity”
android:label=”The Twitter Login~” >

<intent-filter>
<action android:name=”android.intent.action.VIEW” />
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
<data android:scheme=”T4J_OAuth” android:host=”callback_main” />
</intent-filter>
</activity>

Step 3: Invoke Twitter Login 

Intent intent1 = new Intent(this, TwitterActivity.class);
startActivity(intent1);

….

How to setup Google Analytics for Android Apps?

Using Google Android Analytics API v4

The official documentation is here: https://developers.google.com/analytics/devguides/collection/android/v4 – but it is confusing.

Download Google Play Services

Using Android SDK Manager download Extras > Google Play Services.

Add Google Play Services to your Eclipse as a Project:

  • File > Import > Android > Existing Android Code into Workspace > Choose Google Play Services Lib project (that you just downloaded)
  • Make sure that yous select: Copy Project into Workspace checkbox.

Add Google Play Services Project as a Library to your Project

Eclipse > Your Android Project > Properties > Android > Library > Add (do not check Is Library checkbox)

Update Android Manifest

Add following in your manifest xml under Application node:

<meta-data
android:name=”com.google.android.gms.analytics.globalConfigResource”
android:resource=”@xml/global_tracker” />
<meta-data
android:name=”com.google.android.gms.version”
android:value=”@integer/google_play_services_version” />

Create Global Tracker XML

Create this file: res/xml/global_tracker.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<resources>

<!– the Local LogLevel for Analytics –>
<string name=”ga_logLevel”>verbose</string>

<!– how often the dispatcher should fire –>
<integer name=”ga_dispatchPeriod”>200</integer>

<!– Treat events as test events and don’t send to google –>
<bool name=”ga_dryRun”>false</bool>

<!– The screen names that will appear in reports –>
<!– <screenName name=”com.whatever.My1Activity”>My 1 Activity</screenName> –>
</resources>

Create App Tracker

Create this file: res/xml/app_tracker.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<resources>

<!– The apps Analytics Tracking Id. Important: Update this –>
<string name=”ga_trackingId”>XX-WHATEVER-Y</string>

<!– Percentage of events to include in reports –>
<string name=”ga_sampleFrequency”>100.0</string>

<!– Enable automatic Activity measurement –>
<bool name=”ga_autoActivityTracking”>true</bool>

<!– catch and report uncaught exceptions from the app –>
<bool name=”ga_reportUncaughtExceptions”>true</bool>

<!– How long a session exists before giving up –>
<integer name=”ga_sessionTimeout”>300</integer>

<!– If ga_autoActivityTracking is enabled, an alternate screen name can be specified to
substitute for the full length canonical Activity name in screen view hit. In order to
specify an alternate screen name use an <screenName> element, with the name attribute
specifying the canonical name, and the value the alias to use instead. –>
<!– <screenName name=”com.activity.My2Activity”>My 2 Activity</screenName> –>

</resources>

 

Create App Class

package com.whatever;

import android.app.Application;

import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.Tracker;

import java.util.HashMap;

public class YourApp extends Application {

// The following line should be changed to include the correct property id.
private static final String PROPERTY_ID = “XX-WHATEVER-Y”; //Important: Update this

// Logging TAG
private static final String TAG = “MyApp”;//Only used for logging

public static int GENERAL_TRACKER = 0;

public enum TrackerName {
APP_TRACKER, // Tracker used only in this app.
GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg:
// roll-up tracking.
ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a
// company.
}

HashMap<TrackerName, Tracker> mTrackers = new HashMap<TrackerName, Tracker>();

public YourApp() {
super();
}

public synchronized Tracker getTracker(TrackerName trackerId) {
if (!mTrackers.containsKey(trackerId)) {

GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);

Tracker t = (trackerId == TrackerName.APP_TRACKER) ? analytics.newTracker(R.xml.app_tracker)

: (trackerId == TrackerName.GLOBAL_TRACKER) ? analytics.newTracker(PROPERTY_ID)

: analytics.newTracker(R.xml.app_tracker);
mTrackers.put(trackerId, t);

}
return mTrackers.get(trackerId);
}
}

 

Update your My1 Activity Class (i.e any Activity Class you want to track)

In onCreate method, just after: setContentView, add following:

((YourApp) getApplication()).getTracker(YourApp.TrackerName.APP_TRACKER);

Also add following two methods:

@Override
protected void onStart() {
super.onStart();
GoogleAnalytics.getInstance(this).reportActivityStart(this);
}

@Override
protected void onStop() {
super.onStop();
GoogleAnalytics.getInstance(this).reportActivityStop(this);
}

Add this code to all Activity Classes you want to track.

That’s it – Run your application.

Go to https://www.google.com/analytics – to see Analytics

Open Questions

  • There does not seem to be any way to track Active Users outside the context of Activities i.e If you do not care about tracking activities, but only want to track active user’s in your app (they maybe on any activity) – there is no way. You have to enable activity level tracking.  Anyone knows better?
  • What if Google Play App (assuming google play services uses Google Play internally) dies on the Android Mobile, will my app hang or get stuck?
  • How can we ensure that our App is unaffected (speed/performance) even if Google Play Services is not working for some reason.
  • Any other considerations – please leave your comments below – will add them to this blog post.
Follow

Get every new post delivered to your Inbox.