2015年3月29日日曜日

proguard dontwarn

proguard dontwarn

下記の趣旨のエラーが出た。
Warning: com.google.common.cache.Striped64: can't find referenced class sun.misc.Unsafe
Warning: there were 21 unresolved references to classes or interfaces.
         You may need to add missing library jars or update their versions.
         If your code works fine without the missing classes, you can suppress
         the warnings with '-dontwarn' options.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
:proguardRelease FAILED

対処方法
次の1行だけを記述したテキストファイルを適当なファイル名(ここでは'my_proguard-project.txt')で、(ルートでは無く)モジュール側のフォルダーに作成する。
-dontwarn sun.misc.Unsafe

(ルートでは無く)モジュール側のbuild.gradleファイルに次のように書く。
    buildTypes{
        release{
            minifyEnabled true//プロガードを実行する
            proguardFile getDefaultProguardFile('proguard-android.txt')
            proguardFile file('my_proguard-project.txt')
        }
getDefaultProguardFile()は${sdk.dir}/tools/proguard/proguard-android.txtを自動的に読み込む。
my_proguard-project.txtは、このプロジェクトのモジュール固有のproguard設定です。
ちなみに、デフォルトでは、minifyEnabledはfalseです。

(参考)Android Tools Project Site

Gradle Plugin User Guide

Gradle Plugin User Guide

取り敢えず日本語版を読んで概要を知る
第34回 バージョン管理 ─プロジェクト管理ファイルについて[中編]
第 4 回・新 IDE : Android Studio を使ってみよう!-Part2-

Gradle Tutorial : Part 6 : Android Studio + Gradle 画面の画像がある。
Gradle Plugin User Guide 本丸。ここに詳細がある。

DSL == Domain Specific Language。

Android Studioでいわゆる「カス」が溜まる現象について

Android Studioでいわゆる「カス」が溜まる現象について

Android Studioで矛盾するエラーメッセージが出る場合があります。

私の事例の場合のエラーは次のような趣旨でした。
Information:Gradle tasks [clean, : compileDebugSources]
Error:orientation|screenLayout|uiMode|screenSize|smallestScreenSize"

Information:Gradle tasks [clean, generateDebugSources, generateDebugAndroidTestSources]
Error:orientation|screenLayout|uiMode|screenSize|smallestScreenSize"

上記エラーが出たので、AndroidManifest.xmlファイルにおいて該当文言を削除しました。しかし、引き続き上記エラーが発生し続けたのです。
もはやプロジェクトファイルのどこにも上記エラー文言が存在しないのにも関わらずです。
多くの時間をかけて、やっと解決しました。

解決方法は次のとおりです。
File->Settings...->Compiler (Gradle-based Android Projects)
「Use in-process build」欄のチェックを外す。
「Configure on demand」欄のチェックを外す。
その上で、Clean等を行います。すると、いわゆる「カス」が除かれます。
そうすれば、再度上記チェックをonにしても、エラーは発生しません。

チェックを入れると、コンパイルは速くなるようです。
でも、わけのわからんエラーが発生し、その問題解決のために、コンパイルが早くなった時間以上の、多大な時間を浪費してしまいました。むむむ!

ちなみに、上記処理により、.idea/workspace.xmlの内容は自動的に書き換わります。.idea/workspace.xmlを手動で書き換えても意味ないです。

とにかく、わけわからんエラーが出たら、上記チェックを外す。

プロジェクトの構成を変更したら、自動的に、チェックを外してコンパイルするようにして欲しいな。

その後、上記対応を行っても同様のエラーが発生した。Proguardのtxtファイルが存在しなかったので、作成してやると、上記エラーが無くなった。

2015年3月23日月曜日

stacktrace option, debug option

stacktrace option, debug optionの設定方法

* Try:
Run with --stacktrace option to get the stack trace.
Run with --info or --debug option to get more log output.

上記メッセージが出たら、下記を参照する。
How to Add Stacktrace or debug Option when Building Android Studio Project

Android Studio->File->Settings->Compiler(Gradle-based Android Project)->Command-line Options:
ここの欄に「--stacktrace --debug」と書く。

Xlint deprecation

Xlint deprecation

次のような趣旨の注意が出ました。
compileDebugJava
注意:一部の入力ファイルは非推奨のAPIを使用またはオーバーライドしています。
注意:詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。

回答は次のページにありました。
How to add -Xlint:unchecked to my Android Gradle based project?
ルートのbuild.gradleファイル内に次のコマンドを追加・記述して、Build->Clean Projectをすればよろしい、とのことです。

allprojects {
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
        }
    }
}

そうすれば、ログに次のメッセージが出ました。

*\library\src\main\java\com\google\android\vending\licensing\LicenseChecker.java
Error:(257, 55) 警告: [deprecation] DateのtoGMTString()は非推奨になりました
Error:(257, 55) 警告: [deprecation] DateのtoGMTString()は非推奨になりました
警告1個

むむむ!このプログラムは、Google社が提供している、安全性を確保するための、ライセンスを検査するプログラムなんです。そのプログラムにおいて、非推奨メソッドを使って、警告が発せられるってのは面白いですね。

LicenseChecker.javaのverifyLicenseメソッド内で、次のようにログを出力するために使われていました。
Log.d(TAG, "Time: " + date.toGMTString());
なので実害は無いです。

2015年3月21日土曜日

Google Cloud Endpoints

Google Cloud Endpoints

背景
スマホアプリ開発に超絶便利なBaaSとは、MEAPとは
Google App Engine、「Cloud Endpoints」でモバイルバックエンド環境を提供
Google、アプリへのクラウドサービス実装を容易にする「Mobile Backend Starter」
モバイルアプリ開発を加速する「mBaaS」のメリット/デメリット
Google Cloud Platform のモバイル ソリューション
Google Cloud Endpoints の紹介
【RainbowAppsセミナー】Google Cloud Endpoints入門

英語
Cloud Endpoints Support Android Studioの視点から見た大雑把な概要
New ways to connect your app to the Cloud using Android Studio and Google Cloud Platform 開発の視点から見た概要
Google Cloud Endpoints Annotations等も載せた理論詳細
HelloEndpoints 開発画面も載せている。

実装詳細
20.Google Cloud Endpointsを試してみた (1/3)
Android Studioに追加されたGoogle App Engineテンプレートを試そう 導入編
Android Studioに追加されたGoogle App Engineテンプレートを試そう 実装編

1個の文字列だけを取得したいのであれば、HelloEndpointsにあるとおりにすれば良い。
しかし、実際には、複数のデータを取得したいのであるから、Android Studioに追加されたGoogle App Engineテンプレートを試そう 実装編の記事が役に立つ。

HelloEndpointsの「2. Connecting your Android app to the backend」では、EndpointsAsyncTaskを実行させようとしているが、この中の
    private static MyApi myApiService = null;
のMyApiが意味不明であった。

このMyApiキーワードに対して、Android Studioの「Find Usages」コマンドを実行してみると、MyApiはcom.google.api.client.googleapis.services.json.AbstractGoogleJsonClient から派生されたクラスであることがわかる。つまり、Jsonであるということですね。
そして、このクラスの名前にAndroid Studioの「Copy Path」コマンドを実行してみると、このクラスはjarファイルの中に入っていることがわかる。Windowsのエクスプローラを使うと、そのファイルの存在を確認できる。
つまり、ライブラリを生成していたということですね。Android Studioからは直接には見えない場所にあるのですね。

ちなみに、Android Studioでは、Javaコードのエディターにおいて、赤色になってエラーになっているキーワードに対して「Alt」キー+「Enter」キーの押し下げにより、import文が自動で生成される。

"http://10.0.2.2:8080"や"http://localhost:8080/_ah/api/explorer"のローカルホストを使う意義は、動作の確認のためなんですね。

2015年3月18日水曜日

In-app Billing に関するサイト

In-app Billing に関するサイト

In-app Billing Overview
概要や安全性に関する記事。概要以外の記事にも目を通しておいた方が良い。

Google Play のアプリ内課金機能を使用して払い戻しを処理することはできません。
アプリ内アイテムの価格、払い戻し、注文
Handling In-App Billing Refunds in v3
Does Google Play In-App Billing Version 3 support refunds?

Selling In-app Products
トレーニングであり、実践

Android In-app security recommendation - what does this mean?

In-App Billing Version 3 概要
アプリ内課金商品の購入 Purchase In-app Billing Products

Androidで課金アプリ作製 サンプルコード(BILLING V3) 起動編
サンプルプログラムの実行時画面がある。助かります。

Google Play In-app BillingをAPI v3のサンプルを使って楽して導入する

Google Play In-App Billing テスト方法
Testing In-app Billing
in app billing v3 でサンドボックステストするときの話

安全性について
Security and Design
Android LVL を使う - Securing Android LVL Applications -
Androidアプリの解読・改ざんを防ぐ難読化ツールとは
Why is it important to set the developer payload with in-app billing?
Tips for integrating with Google Accounts on Android

安全性の確保のためクラウドを使う
Cloud Tools for Android Studio

ProGuard の設定

SKU == Stock Keeping Unit



2015年3月14日土曜日

EclipseからAndroid studioへのプロジェクトの移植

EclipseからAndroid Studioへのプロジェクトの移植

移植に伴い発生するエラーの表現は適切ではない。ネットで検索してもヒットしない。自分で試行錯誤しよう。

●昔はEclipseにおいて移植に備えたコマンドを実行しておかねばならなかった。今はその必要は無い。

●EclipseにおいてAndroid 5.1が使えない状態で、Android 5.1しか使えないAndroid Studioにインポートした場合、意味不明なエラーになった。
EclipseにおいてSDK ManegerでAndroid 5.1をインストールして、これを使えるように設定した後で移植をすると問題がなくなった。

●Android Studioを使っているとウイルス検出プログラムで「aaptを使用するな」と警告されるが、aaptを使用する必要がある。
誤ってウイルス検出プログラムでaaptを削除してしまった場合には、デバッグができなくなる。SDK Manegerを使って、「Android SDK Build-tools」をインストールすれば治る。

●Google Play Service等のライブラリを使用している場合には、Android Studioでインポートする時に表示されるダイアログ「Import Project from ADT (Eclipse Android)」画面で表示されている「Replace jars ...」と「Replace library ...」のチェックを外さねばならない。
チェックをしたままインポートすると、意味不明な結果になる。

●Android StudioのAnalyze> Inspect Code...を実行させて、そこにある各種指摘のとおりコードを修正する。この修正と、移植に伴うエラーとは何の論理的関係も無い。無いのであるが、この修正を行うと、何故か分からんが、移植に伴うエラーが消えた。

(これが最も効果があった)
特に、アイコン画像ファイルを入れているdrawable系のフォルダーをmipmap系に変えて、使わないdrawable系を削除する。この作業に伴い、AndroidManifest.xmlファイル内での「drawable」を「mipmap」に変更する。
この処置は「Javaのバージョンが異なります」的なエラーをも消去してくれる。
エラー表示内容と、上記対応が何の関連も無いように見えるので「まさかこんなことで?」と半信半疑になる。

●Android Studioで新規プロジェクトを生成する。そしてその新規プロジェクトと、自分が開発中のプロジェクトの構成の違いを観察し、修正する。

2015年3月10日火曜日

AdMobのInterstitial ad

AdMobのInterstitial ad

詳しくは次のサイトに掲載されています。
Interstitial Ad
Integrating New Google Admob with Banner and Interstitial ads
AdMob インタースティシャルの設置

私のJavaコードは次のとおりです。
private class InterstitialView{
    private InterstitialAd adInterstitial;
    public InterstitialView(Context context) {
        Builder adB = new AdRequest.Builder();
        adB.addTestDevice("__xxxx__");
        adInterstitial = new InterstitialAd(context);
        adInterstitial.setAdUnitId("__ID__");
        adInterstitial.loadAd(adB.build());
    }

    public boolean show(){
        boolean b = adInterstitial.isLoaded();
        if(b==true) adInterstitial.show();
        return b;
    }
}

private InterstitialView adInterstitialView = null;
private void ShowInterstitialAD(){
    if(adInterstitialView==null) return;
    adInterstitialView.show();
}

表示は、Activityのように、全画面表示になってしまいます。
全画面であるため、バナー広告のように表示位置を指定する必要はありません。つまり、xmlファイルに何かレイアウトを施す必要はありません。
携帯端末だと、広告内容の絵柄が全画面に表示されますが、タブレット端末の場合は、画面中央に絵柄が配置されて、周囲が濃い灰色で表示されます。
端末利用者は、左上にある、小さい×ボタンを押して、画面を非表示にすることになります。タブレット端末の視点からすると、本当に小さい。

この画面は、端末利用者に次の疑問を持たせます。
むむむ。いきなり画面が変わったぞ? アプリが壊れたのか? アプリの一部なのか? 広告なのか? どうやって閉じるのだ?
このように、違和感を持つと思います。

Google Play Supportは、このような仕様はリジェクトはしないのですね。同じGoogleが作ったからね。

2015年3月1日日曜日

BroadcastReceiverの遅延及びServiceとの関係

BroadcastReceiverの遅延及びServiceとの関係 2題

BroadcastReceiverの遅延
BroadcastReceiverではonReceive()で情報を受け取ることになります。
EclipseでCleanコマンドを実行した後で、デバッグによるアプリの実行を行うと、アプリの稼働後(onCreate()が呼ばれた後)に(アプリを更新したことを原因として)BroadcastReceiverのonReceive()が実行されてしまう場合があります。
止むを得ないため、アプリにおいて、こういう状況ではアプリを終了させるようにコーディングを行いました。
つまり、アプリを再起動させなければならないということです。

Serviceの終了行程時におけるBroadcastReceiverによる呼び出し
Serviceが役目を果たし終えたので、Service内においてstopSelf()を実行させたところ、onDestroy()が呼ばれる前に、BroadcastReceiverのonReceive()が呼ばれ、ServiceのonStartCommand()が呼ばれました。
既にstopSelf()が実行された後なので、BroadcastReceiverに基ずく仕事は何もできませんでした。
このようなタイミングはほとんど発生はしないです。人工的に作ろうとしても難しいでしょう。
しかしながら、発生してしまった以上、見逃すことはできないため、アプリの設計を見直しました。
stopSelf()を実行したのであれば、それ以降は、Serviceはメッセージを受け取らないという仕様にして欲しかったです。

開発環境:Windows & Eclipse
Android 4.4W.2(API20)