Android

爆リー2(仮名)開発します!

知る人ぞ知るAndroidアプリの迷作『爆リー』。公正と正義の名のもとG様に無慈悲にも闇に葬り去られてから、はやX年が経ちましたが、いよいよ新バージョンの開発に重い腰を上げることにしましたよ! 見てろよ、Gめ!おい、Aもだよ!

2020.08.01追記

Android版は公開しました。

爆リーII(for Android) 公開しました

iPhone版はもうちょっと待って下さい!

~~~ 以下は内容が古い可能性アリです ~~~

新バージョンはAndroid/iOS両成敗

します。(まあ審査に落ちる可能性もあるんですけど・・・。)

たぶんAndroidは大丈夫だと思いますが、Appleは審査がわりと厳しいのでちょっと心配。。。でもクロスプラットフォーム開発するので、申請しない理由はないよね!

というわけでチャレンジしてみます。

新バージョンで大きく変更する点

どうしても1点、大きく仕様を変更しないといけない点がありまして。

それは、どうして前バージョンがGoogle Playストアから削除されたかと関係があります。

どうして削除されたのか詳細は別の記事で書くとして・・・簡単に言うと『エロい画像が表示されてたから』です。これがアウトでPlayストアから削除されてしまいました。掲示板なんだから投稿内容まで制御できないんだぜ・・・俺のせいじゃないのにさ・・・

というわけで、他の2ch(5ch)ブラウザアプリのように、ユーザーが『能動的に』爆サイにアクセスしてスレや板を選び爆リーのお気に入りに登録する、という流れにすると思います。あくまでユーザーが見るコンテンツを選ぶ、ということで。これなら(きっと)大丈夫。でないと、普通のブラウザだってエロアプリ認定されちゃうことになりますよね。

ここが大きく変更される点です。ちょっと不便になってしまうかもしれませんが、なるべく簡便な方法を考えます!

その他旧バージョンと異なる点

これについてはまだ検討中なんですが、次のようなことを検討します。

  • お気に入りのフォルダ管理
  • 爆サイだけじゃなく、他の似たようなサイトも見れるように(ホスラブ?とかいうやつとか)
  • というわけでアプリ名も変えるかも!
  • 自動巡回&通知
  • レス返信を辿れるように

などなど。ただし、1番の目標は「まずは公開」なので、最初のバージョンから便利機能は詰め込まない気もします。しかし前作を下回るアプリにはしないつもりです。(たぶん)

リリース時期は・・・

本業とは別の個人開発なのであまりガッツリ時間取れないので、ちょっと時間はかかると思いますが、2020年春ぐらいになんとかできればと・・・ただこの辺りはあまり期待しないで待っててください。。。

というわけで、死なない程度に頑張りつつ開発しますので、声援やリクエストはコメントください。それなりにやる気が出ますので!よろしくお願いしますm(_ _)m

【Android】OnScrollListener#onScroll備忘録 – ListViewのフッターが見えたら何かする

よく忘れるのでメモ。

override fun onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int)

  1. view — スクロールを検知したView。ListViewとか。
  2. firstVisibleItem — 表示されているItemのうち一番上のもののIndex。一部しか見えていない場合でもよい。
  3. visibleItemCount — 表示されているItemの数。一部しか見えていないものもカウントする。
  4. totalItemCount — 非表示の部分も含めたItemの合計数。なお、ヘッダー・フッターもカウントする。

例えばListViewのフッターViewにProgressBarを配置しておき、このフッターが表示されたら追記読み込みをする・・・といった場合の末尾到達判定は以下のようになる。(kotlin)

📄OnScrollListener
...
override fun onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int) {
    if (firstVisibleItem + visibleItemCount >= totalItemCount) {
        // do something
    }
}
...

 

【Android】アップデート情報を表示するライブラリ【ReleaseAnimal】

Androidアプリを開発していると、アップデート後にリリースノートを表示したくなることがある。簡単に表示してくれるライブラリでもないかなと探してみたけど見つからなかったので、自分で『ReleaseAnimal』というものを作ってみた。

ReleaseAnimal

こんな感じのダイアログを簡単に表示できる。

もちろん1度表示したものは2度と表示しない。アプリを初めてインストールするより前のリリース情報は無視するとか、最低限の考慮はできていると思う。

Usageとか

githubに書いた通りだけど、インストール方法はbuild.gradleに1行追加するだけ。(バージョン番号は適宜変更してください)

📄build.gradle
dependencies {
    ...
        compile 'itmammoth.releaseanimal:ReleaseAnimal:0.0.3'
    ...
}

そして自分のapp内にres/xml/releaseanimal.xmlというファイルを作成する。中身は次のような感じで。

📄res/xml/releaseanimal.xml
<?xml version="1.0" encoding="utf-8"?>
<releaseNotes>
    <note date="2016-11-20" versionName="0.0.0.2">
        <message>- New awesome features!</message>
        <message>- Small bug fixes</message>
    </note>
    <note date="2016-11-25" versionName="0.0.1.0">
        <message>- Foo bar yeah!</message>
        <message>- Pen pineapple apple pen!</message>
        <message>- Blah blah blah</message>
    </note>
</releaseNotes>

dateにはリリース日、versionNameには、そのままんだけどversionNameを指定する。例えば今日アップデートをリリースする予定だとすると、dateには今日の日付、versionNameにはアップデート後のversionNameを指定する。messageは適当に改行でjoinされて表示される。

表示するJavaコードは次のように。

📄MainActivity.java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        new ReleaseAnimal.Builder(this).show();
    }
    ...
}

これだけ。我ながら楽チン。

その他詳しいことはgithubを見てほしい。 ...続きを読む

【Android】安全にonActivityResultを実行する

アクティビティから他のアクティビティを呼び出して、その結果を貰い何かを実行する場合がある。定石としてはonActivityResultメソッドをオーバーライドして、その中で処理を実行するというものだが、この方法だと稀にわけの分からん例外が発生する。

📄BaseActivity.java
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {your_class}: java.lang.NullPointerException

この例外を発生させずに安全にコードを実行するサンプルを書いてみてる。

例外の原因

いろいろ調べてみた結果、次のような記事を発見した。

“Failure Delivering Result ” – onActivityForResult

この回答によると、

At the time that onActivityResult() is called, the activity/fragment’s state may not yet have been restored, and therefore any transactions that happen during this time will be lost as a result.

らしい。要するにonActivityResultが呼ばれたときにアクティビティ/フラグメントが完全にリストアされているかどうか保証されていないということ。

解決策としては復帰後に呼ばれるonPostResumeメソッドでやりたい処理を実行すればよいとのこと。これは順序的にはonActivityResult => onPostResume => onResume にとなっており、onPostResumeメソッドは、アクティビティ/フラグメントがリストア済で呼び出されるようだ。

解決コード

というわけでStackoverflowの回答を発展させて、次のようなコードを書いた。

public abstract class BaseActivity extends AppCompatActivity {

    private class ActivityResult {
        private final int requestCode;
        private final int resultCode;
        private final Intent data;

        private ActivityResult(int requestCode, int resultCode, Intent data) {
            this.requestCode = requestCode;
            this.resultCode = resultCode;
            this.data = data;
        }
    }

    private ActivityResult activityResult;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        activityResult = new ActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        if (activityResult != null) {
            onPostResumeWithActivityResult(activityResult.requestCode, activityResult.resultCode, activityResult.data);
            activityResult = null;
        }
    }

    protected void onPostResumeWithActivityResult(int requestCode, int resultCode, Intent data) {
        // override if necessary
    }
}

大して難しいことはしていなくて、単にonActivityResultメソッドで結果を保持しておいて、onPostResumeメソッドが呼び出されたときにonPostResumeWithActivityResultメソッドを呼び出してあげる。

各アクティビティクラスは次のような感じになる。

📄MainActivity.java
public class MainActivity extends BaseActivity {

...

    @Override
    protected void onPostResumeWithActivityResult(int requestCode, int resultCode, Intent data) {
        super.onPostResumeWithActivityResult(requestCode, resultCode, data);
        // ここで煮るなり焼くなりする
    }

...

}

各アクティビティのonPostResumeWithActivityResultメソッドには、従来onAcitivityResultメソッドに書いていた処理を書くことになるわけだ。

とりあえずこれで上手くいっている。なんか問題あったら教えてください。