├── sample ├── res │ ├── drawable │ │ ├── icon.png │ │ ├── groddle.png │ │ └── background.xml │ ├── values │ │ └── strings.xml │ └── layout │ │ └── main.xml ├── default.properties ├── AndroidManifest.xml └── src │ └── com │ └── tinyspeck │ └── sample │ └── Main.java ├── sdk ├── AndroidManifest.xml ├── default.properties └── src │ └── com │ └── tinyspeck │ └── android │ ├── GlitchSessionDelegate.java │ ├── GlitchRequestDelegate.java │ ├── GlitchAsyncTask.java │ ├── GlitchRequest.java │ └── Glitch.java ├── README.md ├── LICENSE.md └── .gitignore /sample/res/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinyspeck/glitch-android-sdk/HEAD/sample/res/drawable/icon.png -------------------------------------------------------------------------------- /sample/res/drawable/groddle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinyspeck/glitch-android-sdk/HEAD/sample/res/drawable/groddle.png -------------------------------------------------------------------------------- /sample/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sample Glitch App 4 | 5 | 6 | -------------------------------------------------------------------------------- /sdk/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /sample/res/drawable/background.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Glitch Android SDK 2 | =============== 3 | 4 | This SDK is intended to help you interact with the [Glitch API](http://api.glitch.com/). The SDK includes authorization through OAuth and functionality for calling the API. 5 | 6 | If you have any feedback or find bugs, please let us know on the [Glitch Developer Forum](http://api.glitch.com/forum/). We want to hear from you! -------------------------------------------------------------------------------- /sdk/default.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system use, 7 | # "build.properties", and override values to adapt the script to your 8 | # project structure. 9 | 10 | android.library=true 11 | 12 | # Project target. 13 | target=android-4 14 | -------------------------------------------------------------------------------- /sample/default.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system use, 7 | # "build.properties", and override values to adapt the script to your 8 | # project structure. 9 | 10 | # Project target. 11 | 12 | split.density=false 13 | target=android-4 14 | android.library.reference.1=../sdk 15 | -------------------------------------------------------------------------------- /sdk/src/com/tinyspeck/android/GlitchSessionDelegate.java: -------------------------------------------------------------------------------- 1 | package com.tinyspeck.android; 2 | 3 | // Implement this in the activity that will be receiving session (login success / login failed / logout) information 4 | public interface GlitchSessionDelegate { 5 | 6 | // Called when login is successful 7 | public void glitchLoginSuccess(); 8 | 9 | // Called when login isn't successful 10 | public void glitchLoginFail(); 11 | 12 | // Called when the user logs out 13 | public void glitchLoggedOut(); 14 | } 15 | -------------------------------------------------------------------------------- /sdk/src/com/tinyspeck/android/GlitchRequestDelegate.java: -------------------------------------------------------------------------------- 1 | package com.tinyspeck.android; 2 | 3 | // Implement this in the activity that will be receiving request information 4 | // Then pass into the call to get a new request object 5 | public interface GlitchRequestDelegate { 6 | 7 | // Called when a request is completed 8 | // Check the method via request.method and response via request.response 9 | public void requestFinished(GlitchRequest request); 10 | 11 | // Called when a request fails 12 | public void requestFailed(GlitchRequest request); 13 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2011 Tiny Speck, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /sample/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | sdk/proguard.cfg 3 | 4 | sdk/.project 5 | 6 | sdk/.classpath 7 | 8 | sdk/.DS_Store 9 | 10 | sample/.DS_Store 11 | 12 | sample/.classpath 13 | 14 | sample/.project 15 | 16 | .DS_Store 17 | 18 | sample/bin/classes.dex 19 | 20 | sample/bin/com/tinyspeck/android/Glitch.class 21 | 22 | sample/bin/com/tinyspeck/android/GlitchAsyncTask.class 23 | 24 | sample/bin/com/tinyspeck/android/GlitchRequest.class 25 | 26 | sample/bin/com/tinyspeck/android/GlitchRequestDelegate.class 27 | 28 | sample/bin/com/tinyspeck/android/R$attr.class 29 | 30 | sample/bin/com/tinyspeck/android/GlitchSessionDelegate.class 31 | 32 | sample/bin/com/tinyspeck/android/R$drawable.class 33 | 34 | sample/bin/com/tinyspeck/android/R$layout.class 35 | 36 | sample/bin/com/tinyspeck/android/R$string.class 37 | 38 | sample/bin/com/tinyspeck/android/R.class 39 | 40 | sample/bin/com/tinyspeck/sample/Main$1.class 41 | 42 | sample/bin/com/tinyspeck/sample/Main$2.class 43 | 44 | sample/bin/com/tinyspeck/sample/Main.class 45 | 46 | sample/bin/com/tinyspeck/sample/R$attr.class 47 | 48 | sample/bin/com/tinyspeck/sample/R$drawable.class 49 | 50 | sample/bin/com/tinyspeck/android/R$id.class 51 | 52 | sample/bin/com/tinyspeck/sample/R$id.class 53 | 54 | sample/bin/com/tinyspeck/sample/R$layout.class 55 | 56 | sample/bin/com/tinyspeck/sample/R$string.class 57 | 58 | sample/bin/com/tinyspeck/sample/R.class 59 | 60 | sample/bin/glitch-android-sample.apk 61 | 62 | sample/bin/resources.ap_ 63 | 64 | sample/gen/com/tinyspeck/android/R.java 65 | 66 | sample/gen/com/tinyspeck/sample/R.java 67 | 68 | sample/proguard.cfg 69 | 70 | sdk/res/proguard.cfg 71 | -------------------------------------------------------------------------------- /sdk/src/com/tinyspeck/android/GlitchAsyncTask.java: -------------------------------------------------------------------------------- 1 | package com.tinyspeck.android; 2 | 3 | import android.os.AsyncTask; 4 | import android.util.Log; 5 | import org.json.JSONException; 6 | import org.json.JSONObject; 7 | import org.json.JSONTokener; 8 | 9 | import java.io.ByteArrayOutputStream; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.net.MalformedURLException; 13 | import java.net.URL; 14 | 15 | 16 | public class GlitchAsyncTask extends AsyncTask { 17 | 18 | GlitchRequest request; 19 | GlitchRequestDelegate delegate; 20 | 21 | public GlitchAsyncTask(GlitchRequestDelegate startDelegate, GlitchRequest startRequest) { 22 | delegate = startDelegate; 23 | request = startRequest; 24 | } 25 | 26 | @Override 27 | protected Object doInBackground(String... strings) { 28 | 29 | URL url = null; 30 | try { 31 | url = new URL(strings[0]); 32 | String result = readURL(url); 33 | 34 | Log.i("vetal", result); 35 | 36 | JSONTokener tokener = new JSONTokener(result); 37 | JSONObject jObject = new JSONObject(tokener); 38 | 39 | return jObject; 40 | 41 | } catch (MalformedURLException e) { 42 | e.printStackTrace(); 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } catch (JSONException e) { 46 | e.printStackTrace(); 47 | } 48 | 49 | return null; 50 | } 51 | 52 | private String readURL(URL url) throws IOException { 53 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 54 | InputStream is = url.openStream(); 55 | int r; 56 | while ((r = is.read()) != -1) { 57 | baos.write(r); 58 | } 59 | return new String(baos.toByteArray()); 60 | } 61 | 62 | protected void onPostExecute(Object result) { 63 | if (delegate != null && result != null && result.getClass() == JSONObject.class) 64 | { 65 | request.response = (JSONObject)result; 66 | delegate.requestFinished(request); 67 | } 68 | else 69 | { 70 | delegate.requestFailed(request); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /sdk/src/com/tinyspeck/android/GlitchRequest.java: -------------------------------------------------------------------------------- 1 | package com.tinyspeck.android; 2 | 3 | 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.json.JSONObject; 8 | 9 | public class GlitchRequest { 10 | 11 | //// Strings and objects used for authentication and requests //// 12 | 13 | public static final String API_URL = Glitch.BASE_URL + "/simple/"; 14 | 15 | public String url; // Full url for request, e.g. "http://api.glitch.com/simple/players.info" 16 | public String method; // Specific method without 'simple', e.g. "players.info" 17 | public Map params; // Dictionary of parameters passed in the request 18 | public GlitchRequestDelegate delegate; // Handler that will be called when events occur before, during, and after the request 19 | public JSONObject response; // JSON response object 20 | 21 | private GlitchAsyncTask task; // Async task that interacts with API 22 | private Glitch glitch; // Glitch parent 23 | 24 | 25 | //// Constructors //// 26 | 27 | public GlitchRequest(String startMethod, Map startParams, Glitch startGlitch) { 28 | method = startMethod; 29 | params = startParams; 30 | glitch = startGlitch; 31 | } 32 | 33 | public GlitchRequest(String startMethod, Glitch startGlitch) { 34 | this(startMethod, null, startGlitch); 35 | } 36 | 37 | 38 | //// Interacting with the API //// 39 | 40 | // Call this to execute your request 41 | // Pass in the delegate which will be called when events occur that are related to this object 42 | public void execute(GlitchRequestDelegate requestDelegate) { 43 | delegate = requestDelegate; 44 | 45 | String fullUrl = API_URL + method; 46 | 47 | if (params == null) 48 | { 49 | params = new HashMap(); 50 | } 51 | 52 | if (glitch.accessToken != null) 53 | { 54 | params.put("oauth_token", glitch.accessToken); 55 | } 56 | 57 | fullUrl = serializeURL(fullUrl, params); 58 | 59 | task = new GlitchAsyncTask(delegate, this); 60 | task.execute(fullUrl); 61 | } 62 | 63 | // Cancel the pending request 64 | public boolean cancel(boolean mayInterruptIfRunning){ 65 | if (task != null) 66 | return task.cancel(mayInterruptIfRunning); 67 | return false; 68 | } 69 | 70 | 71 | //// URL Helper Methods //// 72 | 73 | public static String serializeURL(String url, Map params) 74 | { 75 | url = url + "?"; 76 | 77 | url = url + serializeParams(params); 78 | 79 | return url; 80 | } 81 | 82 | public static String serializeParams(Map params) 83 | { 84 | String parameters = ""; 85 | 86 | if (params != null && !params.isEmpty()) 87 | { 88 | for (String key : params.keySet()) 89 | { 90 | parameters = parameters + "&" + key + "=" + params.get(key); 91 | } 92 | 93 | // Remove extra ampersand from front 94 | parameters = parameters.substring(1); 95 | } 96 | 97 | return parameters; 98 | } 99 | } -------------------------------------------------------------------------------- /sdk/src/com/tinyspeck/android/Glitch.java: -------------------------------------------------------------------------------- 1 | package com.tinyspeck.android; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | 7 | import java.util.Map; 8 | 9 | 10 | public class Glitch { 11 | 12 | //// Strings used for authentication and requests //// 13 | 14 | public static final String BASE_URL = "http://api.glitch.com"; // Base service URL 15 | 16 | public String accessToken = null; // Access token for the currently logged in user 17 | 18 | private String redirectUri = null; // Redirect URI for OAuth flow 19 | private String clientId = null; // Client Id for OAuth flow 20 | 21 | 22 | // Constructor for Glitch object 23 | // API Key is required for generating an auth token 24 | // Redirect URI is required for OAuth flow 25 | public Glitch(String apiKey, String uri) 26 | { 27 | if (apiKey == null || uri == null) 28 | { 29 | throw new IllegalArgumentException( 30 | "Please specify your API key and Redirect URI when initializing a Glitch object"); 31 | } 32 | 33 | this.clientId = apiKey; 34 | this.redirectUri = uri; 35 | } 36 | 37 | 38 | //// Interacting with the API //// 39 | 40 | public GlitchRequest getRequest(String method) 41 | { 42 | return getRequest(method, null); 43 | } 44 | 45 | public GlitchRequest getRequest(String method, Map params) 46 | { 47 | return new GlitchRequest(method, params, this); 48 | } 49 | 50 | 51 | //// Authorization //// 52 | 53 | // Start browser with authorize URL so the user can authorize the app with OAuth 54 | public void authorize(String scope, Activity activity) { 55 | Uri authorizeUri = getAuthorizeUri(scope); 56 | 57 | Intent browserIntent = new Intent(Intent.ACTION_VIEW, authorizeUri); 58 | browserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 59 | activity.startActivity(browserIntent); 60 | } 61 | 62 | public void handleRedirect(Uri uri, GlitchSessionDelegate delegate) 63 | { 64 | if (uri != null) { 65 | // Get access token from URI fragment 66 | String fragment = uri.getFragment(); 67 | 68 | String token = Glitch.extractTokenFromFragment(fragment); 69 | 70 | if (token != null) 71 | { 72 | this.accessToken = token; 73 | delegate.glitchLoginSuccess(); 74 | } 75 | } 76 | } 77 | 78 | public boolean isAuthenticated() 79 | { 80 | return this.accessToken != null; 81 | } 82 | 83 | 84 | //// Authorization URI Creation //// 85 | 86 | public Uri getAuthorizeUri(String scope) { 87 | return this.getAuthorizeUri(scope, null); 88 | } 89 | 90 | public Uri getAuthorizeUri(String scope, String state) { 91 | scope = scope == null ? "identity" : scope; 92 | 93 | String url = this.getAuthUrl(scope, state); 94 | 95 | return Uri.parse(url); 96 | } 97 | 98 | public String getAuthUrl(String scope, String state){ 99 | 100 | String authUrl = BASE_URL + "/oauth2/authorize?response_type=token&client_id=" + this.clientId + "&scope=" + scope + "&redirect_uri=" + this.redirectUri; 101 | 102 | if (state != null) 103 | { 104 | authUrl = authUrl + "&state=" + state; 105 | } 106 | 107 | return authUrl; 108 | } 109 | 110 | 111 | //// Static Helper Methods //// 112 | 113 | private static String extractTokenFromFragment(String fragment) { 114 | String[] vars = fragment.split("&"); 115 | for (int i = 0; i < vars.length; i++) { 116 | String[] param = vars[i].split("="); 117 | 118 | if (param.length == 2 && param[0].equals("access_token")) { 119 | return param[1]; 120 | } 121 | } 122 | 123 | return null; 124 | } 125 | } -------------------------------------------------------------------------------- /sample/src/com/tinyspeck/sample/Main.java: -------------------------------------------------------------------------------- 1 | package com.tinyspeck.sample; 2 | 3 | import org.json.JSONObject; 4 | 5 | import com.tinyspeck.android.Glitch; 6 | import com.tinyspeck.android.GlitchRequest; 7 | import com.tinyspeck.android.GlitchRequestDelegate; 8 | import com.tinyspeck.android.GlitchSessionDelegate; 9 | import com.tinyspeck.sample.R; 10 | 11 | import android.app.Activity; 12 | import android.app.AlertDialog; 13 | import android.app.Dialog; 14 | import android.content.DialogInterface; 15 | import android.content.Intent; 16 | import android.net.Uri; 17 | import android.os.Bundle; 18 | import android.widget.TextView; 19 | 20 | public class Main extends Activity implements GlitchRequestDelegate, GlitchSessionDelegate { 21 | 22 | //// Dialog Constants //// 23 | 24 | static final int DIALOG_LOGIN_FAIL_ID = 0; 25 | static final int DIALOG_REQUEST_FAIL_ID = 1; 26 | 27 | //// Private instance variables //// 28 | 29 | private Glitch glitch; 30 | private TextView nameTextView; 31 | 32 | 33 | //// Overridden methods //// 34 | 35 | @Override 36 | protected void onCreate(Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | 39 | // Set content view 40 | setContentView(R.layout.main); 41 | 42 | // Initialize new Glitch object with API key and redirect URI 43 | // !!! Get an API key and set up your redirect URI at http://api.glitch.com !!! 44 | // Sample API key: "98-abd43ea0d93cb45adb24e0b361f04e7b325183ee" 45 | // Sample RedirectURI: "glitchandroidsdk://auth" 46 | //glitch = new Glitch(null, null); 47 | glitch = new Glitch("98-abd43ea0d93cb45adb24e0b361f04e7b325183ee", "glitchandroidsdk://auth"); 48 | 49 | // Associate our textview with private variable 50 | nameTextView = (TextView) findViewById(R.id.nameTextView); 51 | 52 | // Check our intent for browsable to see whether we came from the browser 53 | Intent intent = getIntent(); 54 | if (intent.hasCategory(Intent.CATEGORY_BROWSABLE)) 55 | { 56 | final Uri uri = intent.getData(); 57 | 58 | if (uri != null) 59 | { 60 | glitch.handleRedirect(uri, this); 61 | } 62 | } 63 | // We didn't come from the browser, so let's authorize 64 | else 65 | { 66 | glitch.authorize("identity", this); 67 | } 68 | } 69 | 70 | 71 | //// GlitchRequester interface methods //// 72 | 73 | public void requestFinished(GlitchRequest request) { 74 | if (request != null && request.method != null && request.method == "players.info") 75 | { 76 | JSONObject response = request.response; 77 | 78 | if (response != null) 79 | { 80 | String playerName = response.optString("player_name"); 81 | nameTextView.setText("Hello " + playerName + "!"); 82 | } 83 | } 84 | } 85 | 86 | 87 | public void requestFailed(GlitchRequest request) { 88 | showDialog(DIALOG_REQUEST_FAIL_ID); 89 | } 90 | 91 | 92 | //// GlitchSession interface methods //// 93 | 94 | public void glitchLoginSuccess() { 95 | GlitchRequest request = glitch.getRequest("players.info"); 96 | request.execute(this); 97 | } 98 | 99 | public void glitchLoginFail() { 100 | showDialog(DIALOG_LOGIN_FAIL_ID); 101 | } 102 | 103 | public void glitchLoggedOut() { 104 | // Called when user logs out (method stub, not yet implemented) 105 | } 106 | 107 | 108 | //// Dialog Creation //// 109 | 110 | protected Dialog onCreateDialog(int id) { 111 | Dialog dialog; 112 | 113 | switch(id) { 114 | case DIALOG_LOGIN_FAIL_ID: 115 | 116 | AlertDialog.Builder builder = new AlertDialog.Builder(this); 117 | builder.setMessage("Login failure!") 118 | .setCancelable(false) 119 | .setPositiveButton("Darn", new DialogInterface.OnClickListener() { 120 | public void onClick(DialogInterface dialog, int id) { 121 | dialog.cancel(); 122 | } 123 | }); 124 | dialog = builder.create(); 125 | 126 | break; 127 | 128 | case DIALOG_REQUEST_FAIL_ID: 129 | 130 | AlertDialog.Builder builder1 = new AlertDialog.Builder(this); 131 | builder1.setMessage("Request failure!") 132 | .setCancelable(false) 133 | .setPositiveButton("Argh!", new DialogInterface.OnClickListener() { 134 | public void onClick(DialogInterface dialog, int id) { 135 | dialog.cancel(); 136 | } 137 | }); 138 | dialog = builder1.create(); 139 | 140 | break; 141 | default: 142 | dialog = null; 143 | } 144 | 145 | return dialog; 146 | } 147 | } 148 | --------------------------------------------------------------------------------