2011年12月4日日曜日

[Android] 容量の大きなアプリをエミュレータで動かす場合の注意点

概要

容量の大きなアプリをエミュレータで実行しようとすると、インストール時に以下のエラーが出る問題.
Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE

エミュレータを起動してディスクサイズを調べてみると、
# df
/dev: 128276K total, 0K used, 128276K available (block size 4096)
/mnt/asec: 128276K total, 0K used, 128276K available (block size 4096)
/system: 77568K total, 77568K used, 0K available (block size 4096)
/data: 65536K total, 45036K used, 20500K available (block size 4096)
/cache: 397312K total, 1156K used, 396156K available (block size 4096)
/mnt/sdcard: 258064K total, 1K used, 258062K available (block size 512)
/mnt/secure/asec: 258064K total, 1K used, 258062K available (block size 512)

確かにdataの残量が少ない.アプリのサイズがどれくらいになるかはわからないが、プロジェクトのサイズは80MBくらいあるのでもう少し拡張しないといけないようだ.

やり方は以下.
Eclipse -> 実行構成 -> プロジェクトを選択 -> Target -> Emulator launch parameters
のAdditional Emulator Command Line Options
にオプションを追加する.今回は512とした.(単位はMBっぽい)
-partition-size 512




参考にしたサイト
INSTALL_FAILED_INSUFFICIENT_STORAGE - ぎじゅっやさん http://hain.jp/index.php/tech-j/2011/08/29/install_failed_insufficient_storage

2011年11月4日金曜日

[Android] アプリから画面ロックをかける

概要

アプリケーションからデバイスをロック状態(スリープ)にする.
結構てこずったので手順をメモ.


手順

  1. android.app.admin.DeviceAdminReceiver をインポート
  2. DeviceAdminReceiver を継承したクラスを作成
  3. デバイス管理者権限の付与
  4. Manifest ファイルの定義
  5. デバイス管理ポリシー定義ファイルの追加


1.android.app.admin.DeviceAdminReceiver をインポート

DeviceAdminReceiver.lockNow() を実行したいActivity内に定義すればEclipseの補完機能でPackageのインポートまでやってくれる.

2.DeviceAdminReceiver を継承したクラスを作成

onEnabled と onDisabled をOverrideする. 特に処理がなければ中身は空でも良い.(なぜこれが必要なのかは不明)
public class MyDeviceReceiver extends DeviceAdminReceiver {

    @Override
    public void onEnabled(Context context, Intent intent) {
    }

    @Override
    public void onDisabled(Context context, Intent intent) {
    }
}


3.デバイス管理者権限の付与

Activityを継承したクラス(画面ロックを実行したいアクティビティ)のメンバ変数に以下を定義
 static final int RESULT_ENABLE = 1;
 ComponentName mCN;
 DevicePolicyManager mDPM;
onCreate 内でデバイス管理者の登録を行う.
mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
mCN = new ComponentName(this, MyDeviceReceiver.class);

if (!mDPM.isAdminActive(mCN)) {
    // デバイス管理者の登録
    Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);  
    intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mCN);
    startActivityForResult(intent, RESULT_ENABLE);
}
else {
    // 権限が取れていればロック実行
    devicePolicyManager_.lockNow();
}
デバイス管理者登録したActivityの戻りを受け取る.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case RESULT_ENABLE:
            if (resultCode == Activity.RESULT_OK) {
                // Has become the device administrator.
                Log.i("tag", "Administration enabled!");
            }
            else {
                //Canceled or failed.
                Log.i("tag", "Administration enable FAILED!");
            }
            return;
    }
    super.onActivityResult(requestCode, resultCode, data);
}


4.Manifest ファイルの定義

Manifestにレシーバを定義する.
<receiver android:name=".MyDeviceReceiver"
    android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data android:name="android.app.device_admin"
                         android:resource="@xml/lock_policy" />
        <intent-filter>
            <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
        </intent-filter>
</receiver>


5.デバイス管理ポリシー定義ファイルの追加

res/xml 以下にxmlファイルを作成する.

<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-policies>
    <force-lock/>
  </uses-policies>
</device-admin>



注意事項

  • デバイス管理者の権限がないとDeviceAdminReceiver.lockNow() メソッドが実行できない
  • デバイス管理者の付与はAndroid2.2からサポートされる


参考にしたサイト

DeviceAdminSample.java | Android Developers
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.html

androidで画面をロックする方法がよく分からない。 - よせばいいのに
http://d.hatena.ne.jp/compound/20110813/1313245962

java - Android DevicePolicyManager lockNow() problem - Stack Overflow
http://stackoverflow.com/questions/6560426/android-devicepolicymanager-locknow-problem

[Android] Make your application a device administrator « Rootfs's Blog
http://rootfs.wordpress.com/2010/09/09/android-make-your-application-a-device-administrator/
※手順が丁寧に解説されていて役に立つ

[Android] ビルドエラー -Conversion to Dalvik format failed with error 1

対象APIバージョンを変更した後にビルドエラーが出るようになった。
解決まで結構ハマったのでメモ。


Conversion to Dalvik format failed with error 1

ビルドして上記エラーが出てしまった場合、エラーメッセージで検索すると解決手順が結構出てくる。

試してみたが解決しなかったもの

  • プロジェクトをクリーンして再ビルド
  • Java のビルド・パス設定でビルドの順序を変える

以下、うまく行った手順
  • プロジェクトのプロパティのAndroidの項目の対象APIのバージョンを修正
  • Java のビルド・パス設定のライブラリからJarを除去
  • プロジェクトをクリーンして再ビルド

参考にしたサイト

Ill-advised or mistaken usage of a core class (Android forum at JavaRanch)

2011年11月1日火曜日

[PHP] ベーシック認証がかかったページのコンテンツを取得

例えばベーシック認証が必要なサイト内の画像を取得するには
以下のような関数を作る.

function getContent($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url_);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_USERPWD, "{$user}:{$password}");
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    $buf = curl_exec($ch);

    curl_close($ch);

    return $buf;
}


バイナリで返ってくるので利用する際はエンコード等が必要.



参考にしたページ

http://memo.funny-k.com/archives/8

2011年10月31日月曜日

[Android] 明るさを変更する方法と注意点

実装方法

Activity 内に以下のコードを記述

 WindowManager.LayoutParams lp = getWindow().getAttributes();
 systemBrightness = lp.screenBrightness;
 lp.screenBrightness = 1.0;
 getWindow().setAttributes(lp);

システム設定を保持しておいて、後で元に戻す.

注意事項

値を0にするとWindowフォーカスを失ってしまうらしいので要注意.


参考にしたサイト

明るさ設定の落とし穴 - Hacking My Way ~ itogのhack日記
http://d.hatena.ne.jp/itog/20100913/1284346565

2011年10月30日日曜日

AndroidのWidgetを実装する

実装する機能


ホーム画面にWidgetを追加し、タップした時の動作を設定


必要なもの


  • Android Manifestの設定(XML)
  • Widgetの設定(XML)
  • Widgetのレイアウト定義(XML)
  • AppWidgetProviderを継承したクラス


Android Manifestの設定


AppWidgetProviderを定義する
<receiver android:name=".MyWidget" android:label="MyWidget">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget" />
</receiver>


Widgetの設定


プロジェクトファイルのres/xmlフォルダに「widget.xml」を定義する

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="72dip"
        android:minHeight="72dip"
        android:updatePeriodMillis="0"
        android:initialLayout="@layout/main" />


Widgetのレイアウト定義





AppWidgetProviderを継承したクラス

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.Toast;

public class MyWidget extends AppWidgetProvider {

 @Override
    public void onUpdate(Context context, AppWidgetManager manager, int[] appWidgetIds) {
  Toast.makeText(context, R.string.msg, Toast.LENGTH_SHORT).show();
    }
}



参考にしたサイト

Androidのホーム画面に常駐するアプリを作るには (1/3) - @IT
http://www.atmarkit.co.jp/fsmart/articles/android10/android10_1.html

ボコ:【Android開発】バッテリー残量ウィジェットの作り方 (1/4)
http://boco.hp3200.com/beginner/widget02-1.html

◆とても詳しくて参考になる
Y.A.M の 雑記帳: Android AppWidget
http://y-anz-m.blogspot.com/2011/06/androidappwidget.html