■ステータスバーにメッセージを表示


ステータスバーにメッセージを表示と言ってもなんだかわかりにくいですが、
こういう感じのものです。
よく、メールが来たりした時にメッセージが表示されるアレですよね。



画面にボタンを張り付けて次のプログラムを実行してボタンを押すとこのようなメッセージが表示されます。
また、メッセージをクリックするとブラウザが開いてホームページが表示されます。

package com.jp.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        android.widget.Button button=(android.widget.Button)findViewById(R.id.button);
        button.setOnClickListener(new button_listener());
    }
    int i;
    private class button_listener implements android.view.View.OnClickListener {
        public void onClick(android.view.View view) {

            android.support.v4.app.NotificationCompat.Builder builder = new android.support.v4.app.NotificationCompat.Builder(getApplicationContext());
            builder.setSmallIcon(R.mipmap.ic_launcher);
            builder.setContentTitle("aaaaaaaa");
            builder.setContentText("bbbbbbbb");
            builder.setSubText("cccccccc");
            builder.setAutoCancel(true);//メッセージをクリックしたら消す

            android.content.Intent intent = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse("http://7ujm.net"));
            android.app.PendingIntent pendingIntent = android.app.PendingIntent.getActivity(getApplicationContext(), i, intent, android.app.PendingIntent.FLAG_UPDATE_CURRENT);
            builder.setContentIntent(pendingIntent);

            android.support.v4.app.NotificationManagerCompat.from(getApplicationContext()).notify(i++, builder.build());

        }
    }
}

▼音やバイブレーションを鳴らす

メッセージを受け取った時にバイブレーションを鳴らすには以下の行を追加します。
builder.setDefaults(android.support.v4.app.NotificationCompat.DEFAULT_VIBRATE);
ただし、マニフェストをいじってバイブレーションが使用できる権限を与える必要があります
権限の追加の仕方はココ

音のみを鳴らすには以下の行を追加します。
builder.setDefaults(android.support.v4.app.NotificationCompat.DEFAULT_SOUND);

音とバイブレーションの両方を鳴らすには以下の行を追加します。
builder.setDefaults(android.support.v4.app.NotificationCompat.DEFAULT_ALL);


▼メッセージの更新と追加

一番最後の行のグリーンの文字の部分を0とか1とか一定の数にすると、メッセージが新しく作成されるのではなくて一つのメッセージが更新されるようになります。
android.support.v4.app.NotificationManagerCompat.from(getApplicationContext()).notify(i++, builder.build());
現在の i++ のようにすると、メッセージがどんどん追加されていきます。


▼クリックしたときに自身のプログラムが実行されるようにする

赤文字の部分により、メッセージをクリックした時に目的のURLに飛ぶようになっていますが、
赤文字の部分の最初の一行を次のように変更すると、
android.content.Intent intent = new android.content.Intent(view.getContext(),com.jp.myapplication.MainActivity.class);
クリックされた時にURLではなくて自分自身のプログラムが実行されるようになります。
ただし、ピンク色で示した部分は現在のプログラムのパッケージとクラス名で変更する必要があります。

自分自身のパッケージ名などを入力するのが面倒な場合なら
android.content.pm.PackageManager pm = getPackageManager();
android.content.Intent intent = pm.getLaunchIntentForPackage(getPackageName());
このようにすると動きますが、手持ちの android 4.4.4 上では画面を閉じてからメッセージをクリックして画面が表示状態にしておいて
その後に連続でメッセージをクリックすると、この下の章の"プログラム間の情報伝達"が動作しなくなりました。
また、色々と挙動がおかしい時がありますので使わない方がいいかもしれん。


▼プログラム間の情報伝達

しかし、だが、自身のプログラムが実行されたとしてもこのままでは、ただ、実行されただけで、目的のページなどをいきなり表示することはできません。
なんらかの情報伝達手段が必要になります。
そこで、Intentに値をセットして起動時にIntentを取得して値を読み出すようにしてみました。

package com.jp.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        android.widget.Button button=(android.widget.Button)findViewById(R.id.button);
        button.setOnClickListener(new button_listener());

        android.content.Intent intent = getIntent();
        int int_p=intent.getIntExtra("int_p", 0);
        String string_p=intent.getStringExtra("string_p");
        button.setText( int_p+ "\n" + string_p);
    }
    int i;
    private class button_listener implements android.view.View.OnClickListener {
        public void onClick(android.view.View view) {

            android.support.v4.app.NotificationCompat.Builder builder = new android.support.v4.app.NotificationCompat.Builder(getApplicationContext());
            builder.setSmallIcon(R.mipmap.ic_launcher);
            builder.setContentTitle(Integer.toString(i));
            builder.setContentText("bbbbbbbb");
            builder.setSubText("cccccccc");
            builder.setAutoCancel(true);//メッセージをクリックしたら消す

            android.content.Intent intent = new android.content.Intent(view.getContext(),com.jp.myapplication.MainActivity.class);
            intent.putExtra("int_p",i);
            intent.putExtra("string_p","test_"+i);
            android.app.PendingIntent pendingIntent = android.app.PendingIntent.getActivity(getApplicationContext(), i, intent, android.app.PendingIntent.FLAG_UPDATE_CURRENT);
            builder.setContentIntent(pendingIntent);

            android.support.v4.app.NotificationManagerCompat.from(getApplicationContext()).notify(i++, builder.build());

        }
    }
}
ピンク色の文字の部分ではプログラムの開始時にintentからキーの"int_p"と"string_p"の値を読み出しています。
赤文字の部分では任意のキーに対して値をセットし、その後にメッセージとして送り出します。
これにより情報が伝達できますのでメッセージを介してプログラムを適切に動作させることができるはずです。


■メッセージをカスタマイズする


メッセージをカスタマイズしてボタンやテキストビューなどを使ってデザインする事ができます。



このような感じにカスタマイズするには、まず新しいレイアウトを作成して適当にテキストビューとボタンを張り付けました。



ファイル名はres/layout/test.xmlで保存しました。
そのXMLファイルでメッセージを作成します。

package com.jp.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        android.widget.Button button=(android.widget.Button)findViewById(R.id.button);
        button.setOnClickListener(new button_listener());

        //ID 0番のメッセージを削除 自分で削除しないと自動で消えない
        ((android.app.NotificationManager)getSystemService(android.content.Context.NOTIFICATION_SERVICE)).cancel(0);
    }
    static int i;
    private class button_listener implements android.view.View.OnClickListener {
        public void onClick(android.view.View view) {
            android.support.v4.app.NotificationCompat.Builder builder = new android.support.v4.app.NotificationCompat.Builder(getApplicationContext());
            builder.setSmallIcon(R.mipmap.ic_launcher);

            android.widget.RemoteViews rv=new android.widget.RemoteViews(getPackageName(),R.layout.test);
            rv.setTextViewText(R.id.textView2,"テキストビュー");
            rv.setTextViewText(R.id.button4,"ボタン");

            android.content.Intent intent = new android.content.Intent(view.getContext(),com.jp.myapplication.MainActivity.class);
            android.app.PendingIntent pendingIntent = android.app.PendingIntent.getActivity(getApplicationContext(),0, intent, android.app.PendingIntent.FLAG_UPDATE_CURRENT);

            //ボタンをクリックしたときの起動先を指定
            rv.setOnClickPendingIntent(R.id.button4,pendingIntent);
            builder.setContent(rv);

            //ID 0番でメッセージを作成
            android.support.v4.app.NotificationManagerCompat.from(getApplicationContext()).notify(0, builder.build());
        }
    }
}
赤文字の部分を追加することによりリモートビューを作成して各リソースに文字を設定し、
クリックしたときの飛び先を設定しています。

ただ、メッセージのボタンをクリックした後に自動で消えないために、ピンクで示した部分で自分で削除しています。


▼メッセージの高さを高くする


メッセージの通常の高さは64dpという制限がかかりますが。
どうしても高さが足りない場合には、
builder.setContent(rv);
の部分を
builder.setCustomBigContentView(rv);
このようにすると高さが256dpまでもっていく事ができます。



通常のメッセージより高さが高いのがわかります。

リソースのレイアウトにButtonとImageViewを張り付けて、以下のコードによりImageViewに画像を表示しました。

android.graphics.Bitmap bmp = android.graphics.BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
rv.setImageViewBitmap(R.id.imageView,bmp);


▲トップページ > android