Android の In-app Billing 定期購読をテストしようとしたら「認証が必要です。Googleアカウントにログインしてください。」と表示される

久々に Android の Subscription 課金を実装してテストしてみようと思い、課金処理を走らせて見たら

「認証が必要です。Googleアカウントにログインしてください。」

と表示されて先に進めません。

Googleアカウントではログインしてるんだけどな、と思いつつ、昔の記憶をたどってみたら、思い出しました。

APKファイルをコンソールにアップしないと、課金処理が走らない!

そうだそうだ、と早速アルファ版にAPKをアップするも同様のエラーで怒られる。

ネットを検索して調べてみたところどうやら「公開」状態にしないといけないみたい。

早速「公開」してみる。

「更新を処理中です」みたいな表示がずっと出ている。

以前は公開ボタンを押してからGoogle側のデータが更新されるまで、何の表示も無く待つだけだったが、どうやら更新中と表示してくれるようになったようだ。

で、1時間ぐらい待ったあと更新中の表示が消えたので課金を試してみたら無事に課金ダイアログが表示されました。

しかも、一昔前は定期購読のテスト購入はできなかった(本当に課金されてた)のに、今回はテスト購入なので実際に課金はされませんよ、という表示になっている!

これでテストがやりやすくなりました^^

Android Studio Confusing ‘null’ argument to var-arg method

 

method = this.getClass().getMethod(methodName, null) ;

こんな感じで、可変引数のところに null を渡していたら
Confusing ‘null’ argument to var-arg method
という警告が出るようになった。

Eclipse でやっていたときは出なかったのだが、Android Studio では出るようになった。

ほっておいても良かったのですが、アプリを実行するたびに画面がこのソースファイルに切り替わってしまって、すごくウザイです。

どうやら、配列型にキャストすればこの警告は出なくなるようで
method = this.getClass().getMethod(methodName, (Class<?>[])null) ;
とキャストするように変更したら治りました。

 

AndroidStudio で画像リソースをドラッグ&ドロップしたが追加できない

Eclipse で開発していたときは、画像ファイルをEclipse上のリソースフォルダにドラッグ&ドロップすれば画像ファイルが追加できていました。
しかし、AndroidStudioでは、ドラッグ&ドロップができません。
しかたがないので、エクスプローラ でプロジェクトディレクトリ src/main/res/drawable-ldpi にファイルをコピーしてみたら、AndroidStudio上にもちゃんと出てきました。
エクスプローラ(MacならFinder)などでファイルを直接ディレクトリにコピーすれば良いようです。
他によい方法がありそうな気もするけどとりあえずはこの方法で行きます。

 

Android Studio で Eclipse のプロジェクトを Import したらコメントが文字化けしてエラー

Android Studio で Eclipse のプロジェクトを Import したらコメントが文字化けしてエラーになりました。
コメントなのに、エラーになってしまいます。
どうやらコメントにSJIS日本語が入っているとエラーになるようです。(コメントに限らず?)

Javaファイルの文字コードを以下のツールを使ってUTF-8に変換したらエラーは消えました。
http://www.vector.co.jp/soft/dl/winnt/util/se478635.html

URLConnection でリダイレクトされたファイルが取得できない

URLConnection::openConnection() でオープンしたコネクションから getInputStream() でストリームを取り出して、Webサーバからの画像をファイルに保存する以下のようなコードを書いて動かしていました。

今まではちゃんと保存できていたのに、ある日突然ファイルが保存できなくなりました。

try {
	FileOutputStream outputStream = context.openFileOutput(fileName,Activity.MODE_PRIVATE) ;
	BufferedOutputStream bufferedOutputStream ;
	bufferedOutputStream = new BufferedOutputStream(outputStream,BUFFER_SIZE) ;

	URL url = new URL(urlString) ;
	URLConnection connection = url.openConnection() ;
	InputStream is = connection.getInputStream() ;
	BufferedInputStream in = new BufferedInputStream(is, BUFFER_SIZE) ;

	byte buf[] = new byte[BUFFER_SIZE] ;
	int totalBytes = 0 ;
	int size = -1 ;
	while((size = in.read(buf)) != -1){
		bufferedOutputStream.write(buf, 0, size) ;
		totalBytes += size ;
	} 
	bufferedOutputStream.flush() ;
	bufferedOutputStream.close() ;
	in.close() ;
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}

何が原因か調べていったところ、どうやら、画像ファイルのURLが http から https にリダイレクトするようになったのが原因のようでした。

例えば

http://example.com/image1.png

https://example.com/ssl_image1.png

にリダイレクトされているような場合だと、inputStream からデータを読み込むことができません。
なぜ読めないか(読めないようにしているか)というと、セキュリティの問題らしい。
試しに https://example.com/ssl_image1.png を始めから指定すると、正しくデータは読めました。

そこで以下のようにコードを修正しました。

try {
	FileOutputStream outputStream = context.openFileOutput(fileName,Activity.MODE_PRIVATE) ;
	BufferedOutputStream bufferedOutputStream ;
	bufferedOutputStream = new BufferedOutputStream(outputStream,BUFFER_SIZE) ;

	URL url = new URL(urlString) ;
	URLConnection connection = url.openConnection() ;
	InputStream is = connection.getInputStream() ;
	BufferedInputStream in = new BufferedInputStream(is, BUFFER_SIZE) ;

	byte buf[] = new byte[BUFFER_SIZE] ;
	int totalBytes = 0 ;
	int size = -1 ;
	while((size = in.read(buf)) != -1){
		bufferedOutputStream.write(buf, 0, size) ;
		totalBytes += size ;
	} 
	String finalUrlString = connection.getURL().toString() ;
	bufferedOutputStream.flush() ;
	bufferedOutputStream.close() ;
	in.close() ;

	if(totalBytes == 0){ // ファイルサイズが0で
		if(!urlString.equals(finalUrlString)){ // リダイレクトされているなら最終的なURLで再挑戦
			outputStream = context.openFileOutput(fileName,Activity.MODE_PRIVATE) ;
			bufferedOutputStream = new BufferedOutputStream(outputStream, BUFFER_SIZE) ;
			url = new URL(finalUrlString) ;
			connection = url.openConnection() ;
			is = connection.getInputStream() ;
			in = new BufferedInputStream(is, BUFFER_SIZE) ; 

			size = -1 ;
			while((size = in.read(buf)) != -1){
				bufferedOutputStream.write(buf, 0, size) ;
			} 
			bufferedOutputStream.flush() ;
			bufferedOutputStream.close() ;
			in.close() ;
		}
	}
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}

リダイレクトされてファイルが読み込めなかった場合は、リダイレクト先のURLで再度読み込み処理を記述したところ、正しくダウンロードできるようになりました。

Android アプリ開発でお困りの方へ