web-dev-qa-db-ja.com

Androidシステムステータスバーにテキストを表示するにはどうすればよいですか?

Android Nougat用のアプリを開発しようとしていますが、Androidサービスルーチンから生成されたステータスバーに情報/テキストを表示したいので、私の問題は、ステータスバーにテキストを表示する方法がわからないことです。

正確に何を意味するのかを示すためにサンプル画像を追加しました(赤い円)。 Playストアのバッテリーモニターアプリで見たので、それは可能だと思います。

Sample

私はすでにNotificationCombat.Builderを試しましたが、これは正しい方法ではないと思います。オーバーレイかもしれませんが、検索したところ何も見つかりませんでした。

誰かが私にそれを行う方法を教えたり、私にヒントを教えてもらえますか?

編集:ここにNotificationCompat.Builderのテストコードがあります

MainActivity.Java

import Android.app.Notification;
import Android.app.NotificationManager;
import Android.os.Bundle;
import Android.support.v4.app.NotificationCompat;
import Android.support.v7.app.AppCompatActivity;
import Android.support.v7.widget.Toolbar;

public class MainActivity extends AppCompatActivity
{
    private final int NOTIFICATION_ID = 10;

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
        mBuilder.setContentTitle("Value");
        mBuilder.setContentText("123");
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setOngoing(true);
        mBuilder.setAutoCancel(false);

        //Intent resultIntent = new Intent(this, MainActivity.class);
        //PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        //mBuilder.setContentIntent(resultPendingIntent);

        Notification notification = mBuilder.build();
        notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;

        NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        mNotifyMgr.notify(NOTIFICATION_ID, notification);
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <Android.support.design.widget.CoordinatorLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">

        <Android.support.design.widget.AppBarLayout Android:layout_height="wrap_content"
                                                    Android:layout_width="match_parent"
                                                    Android:theme="@style/AppTheme.AppBarOverlay">

            <Android.support.v7.widget.Toolbar Android:id="@+id/toolbar"
                                               Android:layout_width="match_parent"
                                               Android:layout_height="wrap_content"
                                               Android:background="#000000"
                                               app:popupTheme="@style/AppTheme.PopupOverlay" />

        </Android.support.design.widget.AppBarLayout>

        <LinearLayout
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:layout_alignParentLeft="true"
            Android:layout_alignParentTop="true"
            Android:orientation="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            Android:weightSum="100" >

            <TextView
                Android:id="@+id/tv_value"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="Hello World!"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        </LinearLayout>

    </Android.support.design.widget.CoordinatorLayout>

</RelativeLayout>

結果:

Result 1

Result 2

9
Matze

私は解決策を見つけました、キーワードはオーバーレイフローティングウィンドウです。

int statusBarHeight = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "Android");
if (resourceId > 0) statusBarHeight = getResources().getDimensionPixelSize(resourceId);

final WindowManager.LayoutParams parameters = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        statusBarHeight,
        WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,   // Allows the view to be on top of the StatusBar
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,    // Keeps the button presses from going to the background window and Draws over status bar
        PixelFormat.TRANSLUCENT);
parameters.gravity = Gravity.TOP | Gravity.CENTER;

LinearLayout ll = new LinearLayout(this);
ll.setBackgroundColor(Color.TRANSPARENT);
LinearLayout.LayoutParams layoutParameteres = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
ll.setLayoutParams(layoutParameteres);

TextView tv = new TextView(this);
ViewGroup.LayoutParams tvParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
tv.setLayoutParams(tvParameters);
tv.setTextColor(Color.WHITE);
tv.setGravity(Gravity.CENTER);
tv.setText("123");
ll.addView(tv);

WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.addView(ll, parameters);
4
Matze

あなたはここのドキュメントであなたの答えを見つけることができます: https://developer.Android.com/reference/Android/support/v4/app/NotificationCompat.html

編集::まあ、答えはドキュメントにあります。ただし、十分な調査と調査を行った結果、コミュニティ間のコンセンサスは、これはどのアプリケーションでも不可能であるということのようです。ステータスバーの右側に配置できるのは、特定のアイコン(時計、天気、システム情報など)のみです。

申し訳ありませんが、これ以上エキサイティングな答えはありませんが、少なくとも、なぜそれを理解できないのかについてストレスを感じるのをやめることができます。

編集2 ::どうやら、ロリポップ以前のデバイスは、システムアイコンを操作できるプライベートAPIにアクセスできました(ここでも、アラームアイコンについて考えてみてください)。その後、APIは削除されました。この stackoverflow post は、状況全体をかなり広範囲にわたって調べます。

編集3 ::ステータスバーの左側にアイコンを配置して生活できる場合は、次のようにテキストをビットマップに変換できます。

 TextView textView = new TextView(activity.getContext());
 textView.setText("Hello World");
 textView.setDrawingCacheEnabled(true);
 textView.destroyDrawingCache();
 textView.buildDrawingCache();
 Bitmap bitmap = getTransparentBitmapCopy(textView.getDrawingCache());
 private Bitmap getTransparentBitmapCopy(Bitmap source) { 
    int width = source.getWidth(); 
    int height = source.getHeight(); 
    Bitmap copy = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    int[] pixels = new int[width * height];
    source.getPixels(pixels, 0, width, 0, 0, width, height);
    copy.setPixels(pixels, 0, width, 0, 0, width, height);
    return copy;
 }
0
anomeric