SQLの窓

2013年10月17日


JSON オブジェクト記述と、jQuery を使用したボタンイベントの一括登録

ページのトップレベルで定義される変数は、window["変数名"] で参照する事ができます。

ここでは、変数に対して直接 JSON を記述していますが、外部で定義したテキストを jQuery のajax で取得して JSON オブジェクトを使用するともっと自由度の高いイベント登録をする事ができます

▼ JSON 文字列変換例
alert( JSON.parse('{"abc":"こんにちは"}').abc );
<script>
if ( !window.jQuery ) {
	document.write("<"+"script src=\"//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js\"></"+"script>");

}
</script>
<script>

var event_lst = {
 "target_a" : function() {
	alert(this.id);
	// this はイベントを起こした要素
	console.dir(this);
 },
 "target_b" : function() {
	alert(this.id);
 },
 "target_c" : function() {
	alert(this.id);
 },
 "target_d" : function() {
	alert(this.id);
 },
 "target_e" : function() {
	alert(this.id);
 }
};


$(function(){
	$( ".event_lst" ).each(function(index) {
		// this は参照した DOM
		$( this ).val(this.id);
		// event_lst の function をイベントに登録
		// var event_lst は トップで定義しているので、
		// window["event_lst"] で参照できます
		$( this ).click( window[this.className][this.id] );
	});
});
</script>
<input class="event_lst" type="button" id="target_a"><br>
<input class="event_lst" type="button" id="target_b"><br>
<input class="event_lst" type="button" id="target_c"><br>
<input class="event_lst" type="button" id="target_d"><br>
<input class="event_lst" type="button" id="target_e"><br>

▼ 実際の実行








タグ:jquery
posted by lightbox at 2013-10-17 15:26 | jQuery | このブログの読者になる | 更新情報をチェックする

2013年10月13日


Java : バッチでテストする Twiiter API の『検索処理』

更新履歴
2013-10-09 : 初回投稿
2013-10-13 : rfc3986 対応と、検索結果を一覧で表示

SkyDrive へ移動


BASE64 のエンコードには、外部ライブラリが必要です。( Android ならば Android SDK 内に存在します )

URLエンコードに、URLEncoder.encode を使っていますが、正確には結果の文字列に少し加工が必要です
実装しました

JSON の処理には、google-gson を使用しています 

※ API に対して件数の引数は渡していません
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import com.google.gson.Gson;

public class HttpAndGet {

	public static void main(String[] args) {

		// コマンドを入力する為の 128 バイトのバッファ
		byte[] line = new byte[128];
		// コマンド部分を抽出する文字列
		String command = "";
		int i_len = 0;
		// 終了コマンド
		while( !(command.toUpperCase().equals("Q")) ) {
			
			try {
				// プロンプト出力
				System.out.print("java>");
				// 入力( 改行付きで入力 )
				i_len = System.in.read(line);
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			try {
				// 入力内容を文字列に変換して、入力文を取り出す
				command = (new String(line, "SJIS")).substring(0, i_len);
				// コマンドのみに変換
				command = command.trim();
				
			} catch (UnsupportedEncodingException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
			
			// コマンド処理( 大文字小文字を区別しない )
			// "get 検索文字列" で検索( 省略時は "get sworc" とみなす )
			if ( (command.toUpperCase()+"   ").subSequence(0, 3).equals("GET") ) {
				String search_string = null;
				String[] data = command.split(" ");
				if ( data.length == 1 ) {
					search_string = "sworc";
				}
				else {
					search_string = data[1];
				}
				Twitter_Search(search_string);				
			}
			// MS932 で判断
			if ( command.equals("強制終了") ) {
				System.out.print("強制終了します");
				System.exit(0);
			}
			
		}
		
		System.out.print("プログラムを終了しました");
		
	}
	
	private static String _api_url = "https://api.twitter.com/1.1/search/tweets.json";
	private static String _consumer_key = "";
	private static String _consumer_secret = "";
	private static String _token = "";
	private static String _secret = "";

	// ******************************************************************
	// Twitter API の検索
	// ******************************************************************
	public static void Twitter_Search(String search_string) {
		
		System.out.println("Twitter_Search を実行中です");
		
		ArrayList<String> lst = new ArrayList<String>();
		String nonce = getNonce();
		String timeStamp = getTimeStamp();
		String result_string = "";
		try {
		
			// *********************************
			// 投稿に必要なデータ (1)
			// *********************************
			lst.add("oauth_consumer_key=" + _consumer_key);
			lst.add("oauth_nonce=" + nonce);
			lst.add("oauth_signature_method=" + "HMAC-SHA1");
			lst.add("oauth_timestamp=" + timeStamp);
			lst.add("oauth_token=" + _token);
			lst.add("oauth_version=1.0");				
			lst.add("q=" + rfc3986(URLEncoder.encode(search_string, "utf-8")));	

			Collections.sort(lst);
			
			String work = "";
			for(int i = 0; i < lst.size() ; i++ ){
				if ( i != 0 ) {
					work += "&";
				}
				work += lst.get(i);
			}
			
			// *********************************
			// 投稿に必要なデータ (2)
			// *********************************
			String work2 = "GET" + "&";
			// API のエントリポイント
			work2 += rfc3986(URLEncoder.encode(_api_url,"utf-8")) + "&";
			// 投稿に必要なデータ (1)
			work2 += rfc3986(URLEncoder.encode(work,"utf-8"));
			
			// *********************************
			// 投稿に必要なデータ (3)
			// *********************************
			String oauth_signature = getSignature(work2);
			
			// *********************************
			// 投稿に必要なデータ (4) / ヘッダ
			// *********************************
			String data = "oauth_consumer_key=" + dD(_consumer_key) +
				",oauth_nonce=" + dD(nonce) +
				",oauth_signature=" + dD(rfc3986(URLEncoder.encode(oauth_signature, "utf-8"))) +
				",oauth_signature_method=" + dD("HMAC-SHA1") +
				",oauth_timestamp=" + dD(timeStamp) +
				",oauth_token=" + dD(_token) +
				",oauth_version=" + dD("1.0");

			// 投稿先
			URL url = new URL(_api_url + "?q=" + rfc3986(URLEncoder.encode(search_string, "utf-8")));

			// 接続準備
			HttpURLConnection http = (HttpURLConnection)url.openConnection();
			http.setConnectTimeout(30000);
			http.setReadTimeout(30000);
			http.setRequestMethod("GET");					
			// ヘッダ
			http.setRequestProperty("Authorization", "OAuth " + data);
			
			InputStreamReader isr = null;
			try {
			// 受信用ストリーム
				isr = new InputStreamReader(http.getInputStream(), "UTF-8");
			}
			catch( Exception e ) {
				isr = new InputStreamReader(http.getErrorStream(), "UTF-8");
			}
			
			// 受信
			BufferedReader br = new BufferedReader(isr);   
			String line_buffer;   
			while ( null != (line_buffer = br.readLine() ) ) {   
				// コマンドプロンプトに表示   
				result_string += line_buffer;
			}

			// 終了処理
			br.close();
			isr.close();
			http.disconnect();
		}
		catch( Exception e ) {
			result_string = "{\"errors\":\"unknown\"}"; 
		}
		
		// Gson を作成
		Gson gson = new Gson();
		
		System.out.println(result_string);
		
		JSON_ENTRY je = gson.fromJson(result_string,JSON_ENTRY.class);
		
		for(TWITTER item : je.statuses) {
			System.out.println( item.text );
			System.out.println( item.user.name );
			System.out.println( item.user.profile_image_url );
			System.out.println( "-----------------------" );
		}
		
	}
	
	private static String rfc3986( String param ) {
		param = param.replace("+", "%20");
		param = param.replace("*", "%2A");
		param = param.replace("%7E","~");
		return param;
	}
	
	private static String dD(String param){
		return "\""+param+"\"";
	}

	private static String getNonce(){
		Random random = new Random(); 
		return String.valueOf(random.nextInt(1000000000));
	}
	
	private static String getTimeStamp(){
		return String.valueOf(System.currentTimeMillis() / 1000L);
	}		
	
	private static String getSignature(String baseString){
		
		String work = "";
		work += _consumer_secret;
		work += "&";
		work += _secret;
		   
		String signature = "";
		SecretKeySpec key = new SecretKeySpec(work.getBytes(), "HmacSHA1");
		
		try {
			
			Mac mac = Mac.getInstance(key.getAlgorithm());
			try{
				mac.init(key);
			} catch(InvalidKeyException ike){
			}
			
			byte[] rawHmac = mac.doFinal(baseString.getBytes());
			// http://commons.apache.org/proper/commons-codec/
			signature = new String (Base64.encodeBase64(rawHmac));
			
		} catch(NoSuchAlgorithmException e){
		}
		
		return signature;
	}
	

	// ******************************************************************
	// BufferedReader から テキストを取得
	// ******************************************************************
	static class TextReader {
		public String getText(BufferedReader br) throws IOException {

			String result_string = "";
			String line_buffer = null;   
			// BufferedReader は、readLine が null を返すと読み込み終了   
			while ( null != (line_buffer = br.readLine() ) ) {   
				result_string += line_buffer;
			}
			
			return result_string;
		
		}
	}
	
	static class JSON_ENTRY {
		TWITTER[] statuses;
	}
	
	static class TWITTER {
		String text;
		USER user;
	}

	static class USER {
		String name;
		String profile_image_url;
	}
}

関連する記事Java : Eclipse 実行の System.in.read(buff) でコンソール入力RFC 3986 に基づいた URL エンコード の簡単な理解Android : ListView Twitter 検索テンプレート


posted by lightbox at 2013-10-13 21:19 | java : 通信関連 | このブログの読者になる | 更新情報をチェックする

Android : ListView Twitter 検索テンプレート



OneDrive へ移動




ListView で表示されている画像は、『private Drawable[] image_icon = new Drawable[100];』を定義しておいて、検索結果分を保存しておくようにしています。アダプタ内の getView で行うと、Android の仕様により、画像の表示がスクロールに追いつかない状態になります。

TwitterSearch.java
package com.example.listviewobjectjson;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import android.os.AsyncTask;
import android.util.Base64;

public class TwitterSearch {

	// AsyncTask のインラインで参照する為の final
	private final String _consumer_key;
	private final String _consumer_secret;
	private final String _token;
	private final String _secret;

	// API
	private final String _tweet_api = "https://api.twitter.com/1.1/search/tweets.json";
	
	// **************************************************************
	// コンストラクタ
	// **************************************************************
	public TwitterSearch(String _consumer_key, String _consumer_secret,
			String _token, String _secret) {
		this._consumer_key = _consumer_key;
		this._consumer_secret = _consumer_secret;
		this._token = _token;
		this._secret = _secret;
	}

	// **************************************************************
	// AsyncTask の onPostExecute から外部イベントとして呼び出す為のインターフェイス
	// **************************************************************
	public interface Searched {
		public void onSearchResult(String result);
   	}
	
	// **************************************************************
	// Twitter 投稿
	// **************************************************************
	public void Search(String query, int count, final Searched OnSearchResult) {
		
		new AsyncTask<String, Void, String>() {

			// **************************************************************
			// 非同期処理
			// **************************************************************
			@Override
			protected String doInBackground(String... params) {

				ArrayList<String> lst = new ArrayList<String>();
				String nonce = getNonce();
				String timeStamp = getTimeStamp();
				String result_string = "";
				try {
				
					// *********************************
					// 投稿に必要なデータ (1)
					// *********************************
					lst.add("count=" + params[1]);
					lst.add("oauth_consumer_key=" + _consumer_key);
					lst.add("oauth_nonce=" + nonce);
					lst.add("oauth_signature_method=" + "HMAC-SHA1");
					lst.add("oauth_timestamp=" + timeStamp);
					lst.add("oauth_token=" + _token);
					lst.add("oauth_version=1.0");				
					lst.add("q=" + rfc3986(URLEncoder.encode(params[0], "utf-8")));	

					Collections.sort(lst);
					
					String work = "";
					for(int i = 0; i < lst.size() ; i++ ){
						if ( i != 0 ) {
							work += "&";
						}
						work += lst.get(i);
					}
					
					// *********************************
					// 投稿に必要なデータ (2)
					// *********************************
					String work2 = "GET" + "&";
					// API のエントリポイント
					work2 += rfc3986(URLEncoder.encode(_tweet_api,"utf-8")) + "&";
					// 投稿に必要なデータ (1)
					work2 += rfc3986(URLEncoder.encode(work,"utf-8"));
					
					// *********************************
					// 投稿に必要なデータ (3)
					// *********************************
					String oauth_signature = getSignature(work2);
					
					// *********************************
					// 投稿に必要なデータ (4) / ヘッダ
					// *********************************
					String data = "oauth_consumer_key=" + dD(_consumer_key) +
						",oauth_nonce=" + dD(nonce) +
						",oauth_signature=" + dD(rfc3986(URLEncoder.encode(oauth_signature, "utf-8"))) +
						",oauth_signature_method=" + dD("HMAC-SHA1") +
						",oauth_timestamp=" + dD(timeStamp) +
						",oauth_token=" + dD(_token) +
						",oauth_version=" + dD("1.0");

					// 投稿先
					URL url = new URL(_tweet_api + "?q="
						+ rfc3986(URLEncoder.encode(params[0], "utf-8"))
						+ "&count=" + params[1]
					);

					// 接続準備
					HttpURLConnection http = (HttpURLConnection)url.openConnection();
					http.setConnectTimeout(30000);
					http.setReadTimeout(30000);
					http.setRequestMethod("GET");					
					// ヘッダ
					http.setRequestProperty("Authorization", "OAuth " + data);
					
					InputStreamReader isr = null;
					try {
						// 受信用ストリーム
						isr = new InputStreamReader(http.getInputStream(), "UTF-8");
					}
					catch( Exception e ) {
						isr = new InputStreamReader(http.getErrorStream(), "UTF-8");
					}
					
					// 受信
					BufferedReader br = new BufferedReader(isr);   
					String line_buffer;   
					while ( null != (line_buffer = br.readLine() ) ) {   
						// コマンドプロンプトに表示   
						result_string += line_buffer;
					}

					// 終了処理
					br.close();
					isr.close();
					http.disconnect();
				}
				catch( Exception e ) {
					result_string = "{\"errors\":\"unknown\"}"; 
				}
				
				return result_string;
			}

			// **************************************************************
			// 非同期処理終了後の処理( 画面へのアクセスが可能 )
			// **************************************************************
			@Override
			protected void onPostExecute(String result) {
				// Tweet メソッドの引数のインターフェイス内のメソッドを呼び出す
				OnSearchResult.onSearchResult(result);
			}
			
		}.execute(query,String.valueOf(count));
	
	}
	
	private String rfc3986( String param ) {
		param = param.replace("+", "%20");
		param = param.replace("*", "%2A");
		param = param.replace("%7E","~");
		return param;
	}
	
	private String dD(String param){
		return "\""+param+"\"";
	}

	private String getNonce(){
		Random random = new Random(); 
		return String.valueOf(random.nextInt(1000000000));
	}
	
	private String getTimeStamp(){
		return String.valueOf(System.currentTimeMillis() / 1000L);
	}		
	
	private String getSignature(String baseString){
		
		String work = "";
		work += _consumer_secret;
		work += "&";
		work += _secret;
		   
		String signature = "";
		SecretKeySpec key = new SecretKeySpec(work.getBytes(), "HmacSHA1");
		
		try {
			
			Mac mac = Mac.getInstance(key.getAlgorithm());
			try{
				mac.init(key);
			} catch(InvalidKeyException ike){
			}
			
			byte[] rawHmac = mac.doFinal(baseString.getBytes());
			signature = new String (Base64.encodeToString(rawHmac, Base64.NO_WRAP));
			
		} catch(NoSuchAlgorithmException e){
		}
		
		return signature;
	}
	
}

※ リストビューの処理(MyListview.java)
ソース全体


posted by lightbox at 2013-10-13 20:19 | Android | このブログの読者になる | 更新情報をチェックする

2013年10月12日


トラブル : AndroidManifest.xml に XML 宣言があるとエラーになる???

ちょっと前に作ったプロジェクトが動かなくなったので、現在動作中のプロジェクトと比べてみると、動いているほうには XML 宣言がありません・・・・。

Android ドキュメントの The AndroidManifest.xml File には、XML 宣言あるんですけれど・・・
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.posttest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.posttest.MainActivity"
            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="NextPage">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
	</application>

</manifest>
1行目を削除すると動いてくれます。

ですが、わけが解らないのでいろいろ更新をかけていくうちに・・・・Eclipse の Android 部分が動かなくなりました。

なもんで、Google より最新版をダウンロードして日本語化して Window Builder をインストールしました。

Android は、4.3 になったので、AndroidManifest.xml の android:targetSdkVersion="17" を android:targetSdkVersion="18" に変えて動作確認しました。

※ 以下はプロジェクトのプロパティの変更です。


※ ようこそがちょっと違う???


関連する記事ADT( Android Development Tools ) Eclipse の導入(日本語化手順はこの中)
■ ADT( Android Development Tools ) Eclipse に Window Builder をインストールして Swing アプリケーションを作成する(1)ADT( Android Development Tools ) Eclipse に Window Builder をインストールして Swing アプリケーションを作成する(2)

結局今は、どちらの AndroidManifest.xml でも動作しています(なにがなんだか)。



最新の ADT の Eclipse は、特に変わらず Juno でした。
『.eclipseproduct』
name=Eclipse Platform
id=org.eclipse.platform
version=4.2.0


posted by lightbox at 2013-10-12 20:19 | Android | このブログの読者になる | 更新情報をチェックする

Twitter API の自分のアプリのトークンを使って投稿するだけの class Android_Twitter

更新履歴
2013-07-11 : 初回投稿
2013-08-24 : Twitter がエラーを返す場合は、getErrorStream を使う必要があったので修正
2013-10-12 : rfc3986 内部メソッドを追加( やはりきっちりしないとエラーになりました )

Twitter がエラーを返す場合( 例えば投稿データか空の場合 )は、getInputStream では無く getErrorStream を使わないと、エラー内容が取得できなかったので修正しました
Android なので、非同期処理は AsyncTask です。クラスのメソッド内で匿名のインナー型を使用して実装しています。終了時のイベントは、専用のインターフェイスを作成して、onPostExecute から呼び出しています。 Android_Twitter.java
package com.example.posttest;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import android.os.AsyncTask;
import android.util.Base64;
import android.widget.EditText;

public class Android_Twitter {

	// AsyncTask のインラインで参照する為の final
	private final String _consumer_key;
	private final String _consumer_secret;
	private final String _token;
	private final String _secret;

	// API
	private final String _tweet_api = "https://api.twitter.com/1.1/statuses/update.json";
	
	// **************************************************************
	// コンストラクタ
	// **************************************************************
	public Android_Twitter(String _consumer_key, String _consumer_secret,
			String _token, String _secret) {
		this._consumer_key = _consumer_key;
		this._consumer_secret = _consumer_secret;
		this._token = _token;
		this._secret = _secret;
	}

	// **************************************************************
	// AsyncTask の onPostExecute から外部イベントとして呼び出す為のインターフェイス
	// **************************************************************
	public interface Tweeted {
		public void onTweetResult(String result);
   	}
	
	// **************************************************************
	// Twitter 投稿
	// **************************************************************
	public void Tweet(String text, final Tweeted OnTweetResult) {
		
		new AsyncTask<String, Void, String>() {

			// **************************************************************
			// 非同期処理
			// **************************************************************
			@Override
			protected String doInBackground(String... params) {

				ArrayList<String> lst = new ArrayList<String>();
				String nonce = getNonce();
				String timeStamp = getTimeStamp();
				String result_string = "";
				try {
				
					// *********************************
					// 投稿に必要なデータ (1)
					// *********************************
					lst.add("oauth_consumer_key=" + _consumer_key);
					lst.add("oauth_nonce=" + nonce);
					lst.add("oauth_signature_method=" + "HMAC-SHA1");
					lst.add("oauth_timestamp=" + timeStamp);
					lst.add("oauth_token=" + _token);
					lst.add("oauth_version=1.0");				
					lst.add("status=" + rfc3986(URLEncoder.encode(params[0], "utf-8")));	

					Collections.sort(lst);
					
					String work = "";
					for(int i = 0; i < lst.size() ; i++ ){
						if ( i != 0 ) {
							work += "&";
						}
						work += lst.get(i);
					}
					
					// *********************************
					// 投稿に必要なデータ (2)
					// *********************************
					String work2 = "POST" + "&";
					// API のエントリポイント
					work2 += rfc3986(URLEncoder.encode(_tweet_api,"utf-8")) + "&";
					// 投稿に必要なデータ (1)
					work2 += rfc3986(URLEncoder.encode(work,"utf-8"));
					
					// *********************************
					// 投稿に必要なデータ (3)
					// *********************************
					String oauth_signature = getSignature(work2);
					
					// *********************************
					// 投稿に必要なデータ (4) / ヘッダ
					// *********************************
					String data = "oauth_consumer_key=" + dD(_consumer_key) +
						",oauth_nonce=" + dD(nonce) +
						",oauth_signature=" + dD(rfc3986(URLEncoder.encode(oauth_signature, "utf-8"))) +
						",oauth_signature_method=" + dD("HMAC-SHA1") +
						",oauth_timestamp=" + dD(timeStamp) +
						",oauth_token=" + dD(_token) +
						",oauth_version=" + dD("1.0");

					// 投稿先
					URL url = new URL(_tweet_api);

					// 接続準備
					HttpURLConnection http = (HttpURLConnection)url.openConnection();
					http.setConnectTimeout(30000);
					http.setReadTimeout(30000);
					http.setDoInput(true);
					// ヘッダ
					http.setRequestProperty("Authorization", "OAuth " + data);
					http.setRequestMethod("POST");					

					// 送信用ストリーム
					OutputStreamWriter osw = new OutputStreamWriter(http.getOutputStream());
					BufferedWriter bw = new BufferedWriter(osw);
					
					// 送信データの書き込み
					bw.write("status=" + rfc3986(URLEncoder.encode(params[0], "utf-8")));
					bw.close();
					osw.close();
					
					InputStreamReader isr = null;
					try {
					// 受信用ストリーム
						isr = new InputStreamReader(http.getInputStream(), "UTF-8");
					}
					catch( Exception e ) {
						isr = new InputStreamReader(http.getErrorStream(), "UTF-8");
					}
					
					// 受信
					BufferedReader br = new BufferedReader(isr);   
					String line_buffer;   
					while ( null != (line_buffer = br.readLine() ) ) {   
						// コマンドプロンプトに表示   
						result_string += line_buffer;
					}

					// 終了処理
					br.close();
					isr.close();
					http.disconnect();
				}
				catch( Exception e ) {
					result_string = "{\"errors\":\"unknown\"}"; 
				}
				
				return result_string;
			}

			// **************************************************************
			// 非同期処理終了後の処理( 画面へのアクセスが可能 )
			// **************************************************************
			@Override
			protected void onPostExecute(String result) {
				// Tweet メソッドの引数のインターフェイス内のメソッドを呼び出す
				OnTweetResult.onTweetResult(result);
			}
			
		}.execute(text);
	
	}
	
	private String rfc3986( String param ) {
		param = param.replace("+", "%20");
		param = param.replace("*", "%2A");
		param = param.replace("%7E","~");
		return param;
	}
	
	private String dD(String param){
		return "\""+param+"\"";
	}

	private String getNonce(){
		Random random = new Random(); 
		return String.valueOf(random.nextInt(1000000000));
	}
	
	private String getTimeStamp(){
		return String.valueOf(System.currentTimeMillis() / 1000L);
	}		
	
	private String getSignature(String baseString){
		
		String work = "";
		work += _consumer_secret;
		work += "&";
		work += _secret;
		   
		String signature = "";
		SecretKeySpec key = new SecretKeySpec(work.getBytes(), "HmacSHA1");
		
		try {
			
			Mac mac = Mac.getInstance(key.getAlgorithm());
			try{
				mac.init(key);
			} catch(InvalidKeyException ike){
			}
			
			byte[] rawHmac = mac.doFinal(baseString.getBytes());
			signature = new String (Base64.encodeToString(rawHmac, Base64.NO_WRAP));
			
		} catch(NoSuchAlgorithmException e){
		}
		
		return signature;
	}

}

処理が完了すると、onTweetResult が実行されます。

MainActivity.java
package com.example.posttest;

import com.example.posttest.Android_Twitter.Tweeted;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

	public void postAction(View view) {
		
		EditText et = (EditText)this.findViewById(R.id.editText1);
		
		new Android_Twitter(
                    "Consumer key",
                    "Consumer secret",
                    "Access token",
                    "Access token secret").Tweet(et.getText().toString(), new Tweeted() {
			
			@Override
			public void onTweetResult(String result) {
				System.out.println(result);
			}
		});

	}
   
}

関連する記事

Twitter API の自分のアプリのトークンを使って投稿するだけの class VS2010_Twitter

Twitter API の自分のアプリのトークンを使って投稿するだけの class VS2012_Twitter

WSH : VBScript と JavaScript で Twitter に投稿する

PHP : Twitter 投稿関数( twitter_update ) / cURL 関数

Twitter アプリの登録方法と、API キーの利用



タグ:twitter API
posted by lightbox at 2013-10-12 17:39 | Android | このブログの読者になる | 更新情報をチェックする

VS2010(C#)WPF : ListView Twitter 検索テンプレート

SkyDrive へ移動





Twitter_Search.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Diagnostics;
using System.Security.Cryptography;

namespace VS2010_Twitter
{
	class Twitter_Search
	{
		private string _consumer_key;
		private string _consumer_secret;
		private string _token;
		private string _secret;

		private string _tweet_api = "https://api.twitter.com/1.1/search/tweets.json";

		public Twitter_Search(
			string consumer_key,
			string consumer_secret,
			string token,
			string secret
			)
		{
			_consumer_key = consumer_key;
			_consumer_secret = consumer_secret;
			_token = token;
			_secret = secret;
		}

		public void Tweet(string text, int count, DownloadStringCompletedEventHandler newEvent = null)
		{

			WebClient wc = new WebClient();

			if (newEvent != null) {
				wc.DownloadStringCompleted += newEvent;
			}

			// ソートされるリスト
			SortedList<string, string> sl = new SortedList<string, string>();
			sl.Add("count", count.ToString());
			sl.Add("oauth_consumer_key", _consumer_key);
			sl.Add("oauth_nonce", Nonce());
			sl.Add("oauth_signature_method", "HMAC-SHA1");
			sl.Add("oauth_timestamp", TimeStamp());
			sl.Add("oauth_token", _token);
			sl.Add("oauth_version", "1.0");
			sl.Add("q", rfc3986(Uri.EscapeDataString(text)));

			// http ヘッダ用シグネチャ作成
			string work = "";
			foreach (KeyValuePair<string, string> kvp in sl) {
				if (work != "") {
					work += "&";
				}
				work += kvp.Key + "=" + kvp.Value;
			}

			string work2 = "";
			// メソッド
			work2 += "GET" + "&";
			// API URL
			work2 += rfc3986(Uri.EscapeDataString(_tweet_api)) + "&";
			// Oauth + データ
			work2 += rfc3986(Uri.EscapeDataString(work));

			// OAuth tool チェック用
			Debug.WriteLine(work2);

			string oauth_signature = Signature(work2);

			// ヘッダ情報を作成
			work = "";
			foreach (KeyValuePair<string, string> kvp in sl) {
				// oauth_* のみを使用する
				if (work != "") {
					if ((kvp.Key + "      ").Substring(0, 6) == "oauth_") {
						work += ", ";
					}
				}
				if ((kvp.Key + "      ").Substring(0, 6) == "oauth_") {
					work += kvp.Key + "=" + Dd(kvp.Value);
				}
			}
			// シグネチャを追加( ヘッダーはソートの必要は無い )
			work += ", oauth_signature=" + Dd(rfc3986(Uri.EscapeDataString(oauth_signature)));

			// OAuth tool チェック用
			Debug.WriteLine(work);

			// フォーマットは、 OAuth tool で確認。
			wc.Headers["Authorization"] = "OAuth " + work;

			// 投稿
			wc.DownloadStringAsync(new Uri(
				_tweet_api +
				"?" +
				"q=" + sl["q"] +
				"&count=" + sl["count"]
			));

		}

		private string rfc3986(string base_string)
		{
			string result = base_string.Replace("!", "%21");
			result = result.Replace("'", "%27");
			result = result.Replace("(", "%28");
			result = result.Replace(")", "%29");
			result = result.Replace("*", "%2A");
			return result;
		}

		// ダブルクォートで挟む
		private string Dd(string base_string)
		{
			return "\"" + base_string + "\"";
		}

		private string Nonce()
		{
			Random rand = new Random();
			int nonce = rand.Next(1000000000);
			return nonce.ToString();
		}

		// タイムスタンプ
		private string TimeStamp()
		{
			TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
			return Convert.ToInt64(ts.TotalSeconds).ToString();
		}

		// シグネチャ
		private string Signature(string target)
		{
			string work = _consumer_secret + "&" + _secret;
			byte[] bin = Encoding.UTF8.GetBytes(target);

			HMACSHA1 hmacsha1 = new HMACSHA1();
			hmacsha1.Key = Encoding.UTF8.GetBytes(work);
			byte[] hash = hmacsha1.ComputeHash(bin);

			return Convert.ToBase64String(hash);
		}
	}
}




posted by lightbox at 2013-10-12 00:20 | VS(C#) | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり