@blog.justoneplanet.info

日々勉強

Androidで本体の電源を入れた時にアプリを起動させる

以下のようにBroadcastReceiverを実装する。

public class BootBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (
                (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED) && intent.getDataString().contains("com.my.app")) ||
                intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)
        ) {
            Intent i = new Intent(context, NotificationService.class);
            context.startService(i);
        }
    }
}

Manifestファイルに以下の記述を付加してBroadcastIntentを受け取れるようにする。

        <receiver android:name=".BootBroadcastReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <data android:scheme="package" android:path="com.my.app" />
            </intent-filter>
        </receiver>

permissionを忘れずに付加する。

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

permissionを書き忘れると、Android3.1以降の端末で上手く検知できなくなる。また、SDカードにインストールしている場合は、Intentを受け取れないのでSDカードがマウントされた時にフックする必要がある。

参考

CakePHPでOAuth Service Providerを実装する

■プロジェクト

以下のコマンドでCakePHPをダウンロードして展開する。

wget https://github.com/cakephp/cakephp/tarball/master
tar xvzf cakephp-cakephp-2.1.3-1-g5270721.tar.gz
cd cakephp-cakephp-5270721

■Pluginの設置

面倒なのでプラグインを使う。

cd app/Plugin
git clone https://github.com/seddonmedia/cakephp-oauth-server.git OAuth
mv OAuth/Controller/OAuthController.php OAuth/Controller/OauthController.php #多分必要

oauth2-phpが必要になるので以下のコマンドを実行する。

cd app/Vendor
git clone https://github.com/quizlet/oauth2-php.git

■Schema

CREATE TABLE IF NOT EXISTS `access_tokens` (
  `oauth_token` varchar(40) NOT NULL,
  `client_id` char(36) NOT NULL,
  `user_id` int(11) unsigned NOT NULL,
  `expires` int(11) NOT NULL,
  `scope` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`oauth_token`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `auth_codes` (
  `code` varchar(40) NOT NULL,
  `client_id` char(36) NOT NULL,
  `user_id` int(11) unsigned NOT NULL,
  `redirect_uri` varchar(200) NOT NULL,
  `expires` int(11) NOT NULL,
  `scope` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `clients` (
  `client_id` char(20) NOT NULL,
  `client_secret` char(40) NOT NULL,
  `redirect_uri` varchar(255) NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`client_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `refresh_tokens` (
  `refresh_token` varchar(40) NOT NULL,
  `client_id` char(36) NOT NULL,
  `user_id` int(11) unsigned NOT NULL,
  `expires` int(11) NOT NULL,
  `scope` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`refresh_token`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

■ログイン

アプリケーションによって実装は様々だが、以下の変数にuniqueなユーザidを保持している必要がある。

$this->Auth->user('id');

以降はドキュメントに書いてあるので必要ないが一応。

■ルーティング

app/Config/bootstrap.phpの最終行に以下を追記する。

CakePlugin::loadAll(array(
    'OAuth' => array('routes' => true)
));

■Client IDとClient Secretの取得

var_dump($this->OAuth->Client->add('http://sample.org'));

ここで取得できるのはクライアントID(a)とSecret(b)である。表示されるSecretは実際の値で、DB側に保存されている値はhash化されている。

■Authorization Codeの取得

/oauth/authorize?response_type=code&client_id=xxxx&redirect_url=http%3a%2f%2fsample.org

Authorization Codeが取得できる。(c)

■Access Tokenの取得

/oauth/token?grant_type=authorization_code&code=(c)&client_id=(a)&client_secret=(b)

Access Tokenの取得時に(b)は以下の部分でhash化してfindされる。

    public function checkClientCredentials($client_id, $client_secret = NULL) {
        $conditions = array('client_id' => $client_id);
        if ($client_secret) {
            $conditions = array(
                'client_secret' => self::hash($client_secret),
            );
        }
        $client = $this->Client->find('first', array(
            'conditions' => $conditions,
            'recursive'  => -1
        ));
        if ($client){
            return $client['Client'];
        };
        return false;
    }

既存のプロジェクトをARC対応する

面倒ではあるがARC対応されたものしかライブラリとして存在しないものが少しづつ出てきたので時代の流れだししょうがない。

■Edit > Refactor > Convert to Objective-C ARC…

  1. Check
  2. Cannot Convert to Objective-C ARC…
  3. 左側でエラーが出たものを除外して、1に戻る

2が出なくなったら自動で変換される。

■Target > Build Phases > Compile Sources

除外したものに-fno-objc-arcが付いている。

  • ライブラリはARC版が出ていたら入れ替える
  • 自前のコードは頑張る

foreverでexpressを動作させる

特に変わった事はない。

■インストール

npm install -g forever

■起動

forever start app.js

■停止

forever list
#info:   Forever processes running
#data:       uid  command script forever pid   logfile                                   uptime       
#data:   [0] T5dT node    app.js 24921   24922 /home/user/.forever/T5dT.log 0:0:0:35.653 
forever stop 0

Manifest Version 2

これの訳。結構適当。

  • コンテントセキュリティ・ポリシーはデフォルトで`script-src ‘self’; object-src ‘self’にセットされる。content_security_policyのドキュメントに長々と書いたけど、これは開発者に様々な影響を与えるよ
  • パッケージのリソースはデフォルトでimageやscriptのsrcとして外部のウェブサイトを参照できない。もしウェブサイトからパッケージに含まれるリソースをロードできるようにしたいなら、web_accessible_resourcesのマニフェスト属性を通してホワイトリストに明示する必要がある。これはとりわけ挿入されたコンテントスクリプトを通してウェブサイトのインターフェースを構築する拡張機能に関連する。
  • background_pageのプロパティがscriptとpageプロパティを内包するbackgroundに変わった。
  • chrome.extension.getTabContentsesとchrome.extension.getExtensionTabsはなくなった。chrome.extension.getViews({ “type”: “tab” })を代わりに使ってね
  • Port.tabはなくなった。代わりにPort.senderを使ってね

ブラウザアクションの変更

  • マニフェストのbrowser_actionsとchrome.browserActionsはなくなった。代わりに単数形のbrowser_actionとchrome.browserActionを使ってね
  • browser_actionのiconsプロパティは削除された。代わりにdefault_iconプロパティやchrome.browserAction.setIconを使ってね
  • browser_actionのnameプロパティは削除された。代わりにdefault_titleプロパティやchrome.browserAction.setTitleを使ってね
  • browser_actionのpopupプロパティは削除された。代わりにdefault_popupプロパティやchrome.browserAction.setPopupを使ってね
  • browser_actionのdefault_popupプロパティはもはやオブジェクトとして指定できない。文字列でなければならない

ページアクションの変更

  • マニフェストのpage_actionsとchrome.pageActions APIはなくなった。代わりに単数形のpage_actionとchrome.pageActionを使ってね
  • page_actionのiconsプロパティは削除された。代わりにdefault_iconやchrome.pageAction.setIconを使ってね
  • page_actionのnameプロパティは削除された。代わりにdefault_titleやchrome.pageAction.setTitleを使ってね
  • page_actionのpopupプロパティは削除された。代わりにdefault_popupやchrome.pageAction.setPopupを使ってね
  • page_actionのdefault_popupプロパティはもはやオブジェクトとして指定できない。文字列でなければならない
  • chrome.self APIは削除された。代わりにchrome.extensionを使ってね