Android OSから発行されるブロードキャストインテントの受信
Androidではいくつかの標準ブロードキャストインテントが定義されていて、システムの様々な状態変化を取得できるようになっています。今回はアプリのアンインストールの検知を試してみました。
# 最初、機内モードIN/OUTを検知しようとしてうまく検知できず…
【参考】 android.content.Intent のリファレンスの Standard Broadcast Actions の項
http://developer.android.com/reference/android/content/Intent.html
テスト環境は以下の通りです。
AndroidManifest.xmlの記述
試してみた限りでは、intent-filter中の は必須で、これがないとロードキャストレシーバが起動されませんでした。
<application> .... <receiver android:name=".UninstallReceiver"> <intent-filter> <action android:name="android.intent.action.PACKAGE_REMOVED" /> <data android:scheme="package" /> </intent-filter> </receiver> </application>
Broadcast Receiverの作成
以下のようなブロードキャストレシーバを記述します。AndroidManifestの記述に従って、PACKAGE_REMOVEDが発行されるとUninstallReceiverがインスタンス化され、onReceiverが呼び出されることになります。ここでは、別のアクティビティ (Main) を起動する処理を行っています。
UninstallReceiver.java
public class UninstallReceiver extends BroadcastReceiver { private static final String TAG = "DEBUG"; @Override public void onReceive(Context context, Intent received_intent) { Log.d(TAG, "receiver activated"); Intent intent = new Intent(context, Main.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_MAIN); context.startActivity(intent); } } }
(メモ) Ubuntu 12.04 on Zenbook Prime UX31A
最近Zenbook Prime UX31Aを購入したので、Ubuntuを入れた際の設定などのメモを書いておきます。
機種・バージョン情報
- ZENBOOK Prime UX31A-R4256 (Intel Core i7-3517U, 1.9GHz×2コア, メモリ 4GB, SSD 256GB)
- Ubuntu Desktop 12.04 LTS 64bit
最初Linux Mint 13 Cinnamonを試したものの、GRUBのインストールに失敗したので、ひとまず何も考えずにUbuntuに切り替えました。
Ubuntuのインストール
UX31Aは従来のBIOSに代わるUEFIを用いてブートするので、パーティションの扱いが以前とは異なっています (今どきのマシンはみんなこうなんでしょうかね…?)
初期状態でWindowsのデータ領域 (Dドライブ) として確保されていた約130GBのパーティションを3つに分け、以下のように割り当てました。
- /dev/sda5 (20GB) Linuxシステム用 (/) (今回Ubuntuを入れたパーティション)
- /dev/sda7 (20GB) 予備
- /dev/sda8 (92GB) Linuxデータ用 (/data)
(GUIDパーティションテーブルのため、従来の基本パーティションや論理パーティションの概念はない)
Ubuntu上のGNU partedでは以下のように見えています。
(parted) print list Model: ATA SanDisk SSD U100 (scsi) Disk /dev/sda: 252GB Sector size (logical/physical): 512B/512B Partition Table: gpt Number Start End Size File system Name Flags 1 1049kB 211MB 210MB fat32 EFI system partition boot 2 211MB 345MB 134MB Microsoft reserved partition msftres 3 345MB 104GB 104GB ntfs Basic data partition 4 104GB 109GB 4295MB Basic data partition 5 109GB 129GB 20.0GB ext4 7 129GB 149GB 20.0GB 8 149GB 241GB 92.6GB ext4 6 241GB 252GB 10.7GB ntfs Basic data partition hidden, diag
タッチパッド操作について
Ubuntuインストール直後の状態で、2本指スクロール含めてタッチパッド使えていますが、右クリックが機能しません。
2本指タップ (クリックではなくタッチパッドに短く触れる操作) が右クリックとして機能します。
OSが固まる現象とカーネル更新
インストール直後の状態では、ブラウザ (Firefox, Chrome) でWebサイトにアクセスするタイミングでかなり頻繁にOS全体がフリーズする現象が発生していました。
Ubuntuのcomminuty wikiページを見ると、2012/7/22時点で最新の3.2.0-26バージョンのカーネルでWi-Fi接続時にkernel panicが発生する問題があるようです。
https://help.ubuntu.com/community/AsmusZenbookPrime#Bugs_and_issues
この状況に該当するかどうかは明確ではないものの、proposed (テスト版) の3.2.0-27では問題が解決されているとのことなので、ひとまずこれに置き換えます。
初期状態ではproposedはapt-getの取得対象に入っていないので、Ubuntuソフトウェアセンターの「ソフトウェアソース」で、「プレリリースされたアップデート (precise-proposed) にチェックを入れる必要があります。
この状態でapt-getやアップデートマネージャ等によりlinux-image-3.2.0-27-genericを入れることができます。
カーネルを置き換えた状態で2日ほど使って限りではフリーズは発生していないので、当面これで問題なさそうです。
Unsettingsを用いたグローバルメニュー無効化
Zenbookに限った話ではありませんが、最近のUbuntuではアプリケーションのファイル、編集などのメニューが画面全体の最上部に出る (グローバルメニューと呼ぶらしい) のがどうも使いづらいので、Unsettingsという設定ツールを使って、ウィンドウ上部に来るように変更します。
初期状態でのUbuntuデスクトップ (グローバルメニュー表示)
参考情報:
UnsettingsはUbuntu公式のリポジトリには含まれないので、aptにリポジトリを追加した後でapt-getでインストールします。
$ sudo add-apt-repository ppa:diesch/testing $ sudo apt-get update $ sudo apt-get install unsettings
Unsettingsを起動して、Windowsタブの中の「Global menu」をOFFにします (有効にするには一旦ログアウトする必要あり)。
ブラウザから送出されるWebSocketハンドシェイクを取得
WebSocketプロトコルとRubyのTCPServerのお勉強を兼ねて、WebブラウザからWebSocketサーバへの接続時に、ブラウザが送出するハンドシェイクの内容を取得してみます。
参考情報:
- 1.WebSocket仕様解説 実装WebSocketクライアント対応プロトコルバージョン確認編 (2012/09/28 Update) - gtk2kの日記
- RFC 6455 - The WebSocket Protocol / http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html
- Ruby 1.9.3 リファレンスマニュアル > TCPServerクラス
動作環境:
- Linux Mint 13 (64ビット版)
- Ruby 1.9.3-p194
- Google Chrome 20.0.1132.47
TCPサーバ
RubyリファレンスマニュアルのTCPServerクラス中のサンプルほぼそのままです。
WebSocketのハンドシェイク中のヘッダフィールドをテキトーに解釈しています。
ws_handshake.rb:
require 'socket' server = TCPServer.new(8000) while true Thread.start(server.accept) do |s| while line = s.gets.chomp case line when /^GET/ puts line when /^\S+?\: \S+$/ puts line else break end end s.close end end
サーバ起動:
$ ruby ws_handshake.rb # 8000/tcpで待ち受け
ブラウザからの出力
ここでは、ChromeのJavaスクリプトコンソールから、先ほど開いたサーバポートにWebSocketプロトコルで接続してみます。
> new WebSocket('ws://localhost:8000/test');
すると、先ほどサーバを起動したターミナル上に、以下のように表示されます。
GET /test HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: localhost:8000 Origin: chrome://newtab Sec-WebSocket-Key: l25AVE4wwuIb6Ed/qlreGg== Sec-WebSocket-Version: 13 Sec-WebSocket-Extensions: x-webkit-deflate-frame
リンク先の解説によると、これだけではWebSocketプロトコルバージョンは特定できず、hybi-13〜RFC 6455のいずれかのバージョンであることが分かることになります。
メモ: node.jsでHello world
- node.jsバージョン: 0.6.19
- 参考: node.jsハンズオン資料 (インストール、HTTP Serverの章)
コンソール版Hello world
hello.js:
console.log("Hello, world");
これをターミナル上で実行すると "Hello, world" と表示される。
$ node hello.js Hello, world $
Webサーバ版Hello world
「参考」に挙げたハンズオン資料中のコード例ほぼそのままですが。
hello_server.js:
var http = require('http'); var server = http.createServer(function(req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.write('Hello, world\n'); res.end(); }); server.listen(8000);
ターミナル上で hello_server.jsを実行
$ node hello_server.js
この状態で、同じホスト上のWebブラウザから http://localhost:8000/ に接続すると、ブラウザ上に "Hello, world" と表示される。
『弱者99%社会』
2章「現役世代をどう支えるか」を中心にざっと拾い読み。
- 作者: 宮本太郎+BSフジプライムニュース
- 出版社/メーカー: 幻冬舎
- 発売日: 2011/12/22
- メディア: 新書
- 購入: 4人 クリック: 31回
- この商品を含むブログ (11件) を見る
以下は自分なりの解釈を含んでいるので、必ずしも本文の内容とは一致していない可能性があります。
日本的雇用と社会
伝統的に (高度成長期〜1980年代くらい?) 日本における正社員は以下のような性質を持つ。
- 安定した雇用 (主に解雇要件の厳しさに起因)
- 年功型の賃金上昇
- 充実した社会保障、社会的信用
- 異動、転勤、長時間残業/休日出勤など、過酷な勤務内容
一方、アルバイト、パートなどの非正規雇用は、これとは対称的に、以下のような状況にある。
- 不安定な雇用
- ほとんど上昇しない賃金
- 薄い社会保障、低い社会的信用
20年前くらいまでは、夫が正社員として安定した収入を得て、妻がパートなどの形で補助収入を得るという形で、それなりにうまく回っていた。しかし、近年の正規雇用の縮小とともに、この構図が成り立たなくなってきた。狭き門となった正規雇用を獲得できないと、家庭を築くのが困難というのが今の状況。また、正社員としては、「少数精鋭」化のために要求される能力が高度化し、疲弊しやすい状況になっている。
この状況に対して濱口桂一郎氏が提唱しているのが、「ジョブ型正社員」という雇用形態。
- 雇用契約の中で、職務、労働時間、就業場所が規定される (→契約で規定された仕事以上のことはする必要がない)
- 雇用期間の限定はない (会社から見ると、仕事がなくなった時点で解雇可能。逆に雇用期間の上限もない)
ジョブ型正社員は (日本型) 正社員と非正規社員の中間的な存在であり、正社員として働き続けるのが無理な人、および非正規社員からステップアップしたい人の両方にとっての選択肢となる。
(以下感想)
ジョブ型正社員の可能性について、思いついたことを列挙してみます。
- ジョブ型正社員のような制度は、確かに多くの人にとっては適した選択肢になりうると思う半面、現状の延長として考えると、結局ブラック職場のような問題が発生するのではないかという気もする。
- 現状でも、正社員の立場でもそれほど疲弊する状況でない人も多い (であろう) ことからの類推で、結局ジョブ型正社員が成立するかどうかは、個別の業界や会社の状況に依存するのではないかと思う。
- 企業にとってジョブ型正社員の導入にどのような合理性があるのかが1つのポイントと思う。企業が戦力とみなすような高度な専門性を持っていて、かつ正社員として働くことができない/希望しない人については、ジョブ型正社員として雇用する必然性がある。
Himawari Readerその後
以前取り上げた、Android版EPUBリーダーアプリ「Himawari Reader」にアップデート来ました。
前回の記事→ Himawari Readerに期待 - m-kawato@hatena_diary
https://market.android.com/details?id=jp.green_fld.himawari
このバージョンの新機能: 2012/1/30 Ver1.1.0(build 2012001) Nightモードを追加 フォント切り替え機能を追加(外部フォント利用可能) 文書表示時、全画面化するように変更 画像が正しく表示されない場合があった問題を修正
以前のバージョンでは、手持ちの電子書籍の埋め込み画像がうまく表示されないという問題がありました。
では早速新バージョンで同じタイトルを表示してみます。
おおっ、ちゃんと表示されている!
フォント切り替え機能はまだ試していませんが、これは普通に常用できるんじゃないでしょうか。
OAuth認証メモ
過去日記では書いていなかったので、復習を兼ねてRubyのoauthライブラリを使ったOAuth認証+Twitter APIの呼び出しを試してみます。
FacebookやGoogle系のAPIはOAuth 2.0が採用されているようですが、Twitter APIではまだAuth 1.0のみ正式対応なので、今回はOAuth 1.0を使います。
やったこと
Rubyのoauthライブラリは、Railsと組み合わせて、認可ページ (○○アプリがあなたのアカウントを利用することを許可しますか?) にリダイレクト→呼び出し元のページにリダイレクトという動作が基本のようですが、ここではRailsなしで試す前提で、認可ページからPINコードを発行する形で動かしてみます。
テスト環境
- Ubuntu 11.10 (32ビット版) on VMware Player
- Ruby 1.9.3-p0
- oauth 0.4.5 (RubyGems) http://oauth.rubyforge.org/
oauthは公式のドキュメントが充実していないので結構やっかいでした…
Consumer key/secret取得
Twitterアプリケーション管理ページには、http://dev.twitter.com/apps あるいはTwitterの設定ページ→アプリ連携→開発者 で入れます。
ここで、登録したアプリのConsumer keyとConsumer secretが参照できます。
アクセストークン発行
認可用スクリプトoauth_auth.rbの流れは以下のようになります。
- 取得したConsumer key/secretからリクエストトークン (RequestToken) 作成
- (ブラウザから、リクエストトークンに含まれる認可用URLにアクセス→PINコード発行)
- RequestToken#get_access_token にPINコードを渡して、アクセストークン (AccessToken) 発行
- AccessTokenオブジェクトに含まれるアクセストークンとシークレットを出力
ここで取得したAccessTokenオブジェクトを直接使ってTwitter APIを呼び出すこともできますが、一旦発行したアクセストークンは後で使い回すことができるので、ここで出力したアクセストークンを別スクリプトのtwitter_api.rbで使うことにします。
oauth_auth.rb:
require 'oauth' CONSUMER_KEY = "Consumer Key" CONSUMER_SECRET = "Consumer Secret" consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, :site => "http://twitter.com") request_token = consumer.get_request_token puts "authorize_url = #{request_token.authorize_url}" print "type pin: " pin = gets.chomp access_token = request_token.get_access_token(:oauth_verifier => pin) puts "oauth token: #{access_token.token}" puts "token secret: #{access_token.secret}"
このスクリプトを実行すると、"authorize_url = " に続いて認可用URLが出力されます。ブラウザのアドレスバーにこのURLを入れると、おなじみの認可画面が現れ、「連携アプリを認証」をクリックするとPINコードが出力されます。このPINコードを、"type pin: " のプロンプトに入力すると、リクエストトークン (oauth token) とシークレット (token secret) が出力されます。
Twitter API呼び出し
基本的には、先ほど取得したAccessTokenオブジェクトを使って、
response = access_token.get(url)
のようにすれば、OAuth認証ヘッダつきのHTTPリクエストが発行されます。
前述した通り、一旦発行したアクセストークンを使い回す目的から、Consumer Key/Secret、Access Token/Secretの組からAccessTokenオブジェクトを生成し、そのAccessTokenを使ってTwitter APIを呼び出してみます。
# -*- coding: utf-8 -*- require 'oauth' require 'json' require 'pp' CONSUMER_KEY = "Consumer Key" CONSUMER_SECRET = "Consumer Secret" OAUTH_TOKEN = "Access Token" OAUTH_TOKEN_SECRET = "Token Secret" consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, :site => "http://twitter.com") access_token = OAuth::AccessToken.from_hash(consumer, :oauth_token => OAUTH_TOKEN, :oauth_token_secret => OAUTH_TOKEN_SECRET ) response = access_token.get("http://api.twitter.com/1/statuses/home_timeline.json") result = JSON.parse(response.body) pp result
成功すると、oauth_auth.rb実行途中にブラウザからログインしたTwitterアカウントのタイムラインが出力されるはずです。