代码之家  ›  专栏  ›  技术社区  ›  Matze

如何在android系统状态栏中显示文本

  •  12
  • Matze  · 技术社区  · 7 年前

    我正在尝试为Android Nougat开发一个应用程序,我想在状态栏中显示一些由Android服务例程生成的信息/文本。所以我的问题是,我不知道如何在状态栏中显示文本。

    我添加了一个示例图像来显示我的确切意思(红色圆圈)。 我知道这是可能的,因为我在play store的电池监视器应用程序中看到了它。

    Sample

    我已经试过NotificationCombat了。建筑商,但我认为这不是正确的方式。可能是覆盖图,但搜索后我没有找到什么。

    编辑:这里是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

    3 回复  |  直到 7 年前
        1
  •  5
  •   Matze    7 年前

    我确实找到了一个解决方案,关键字是 覆盖 浮动窗口 .

    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);
    
        2
  •  3
  •   Shoaib Kakal    4 年前

    text 对我来说,一个偶像是完美的。 在上测试 Oreo

    1. Bitmap
    2. 然后转换 至图标。

    输出

    enter image description here

     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            displayNotification("5F");
        }
    
     public void displayNotification(String text) {
    
            Notification.Builder builder = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                builder = new Notification.Builder(this, CHANNEL_ID);
            }
    
            //convert text to bitmap
            Bitmap bitmap = createBitmapFromString(text.trim());
    
            //setting bitmap to staus bar icon.
            builder.setSmallIcon(Icon.createWithBitmap(bitmap));
    
            builder.setContentTitle("Simple Notification");
            builder.setContentText("This is a simple notification");
            builder.setPriority(Notification.PRIORITY_MAX);
    
            NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(this);
            notificationManagerCompat.notify(NOTIFICATION_ID, builder.build());
    
            createNotificationChannel();
        }
    
      private void createNotificationChannel() {
            // Create the NotificationChannel, but only on API 26+ because
            // the NotificationChannel class is new and not in the support library
            if (VERSION.SDK_INT >= VERSION_CODES.O) {
                CharSequence name = "testing";
                String description = "i'm testing this notification";
                int importance = NotificationManager.IMPORTANCE_DEFAULT;
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
                channel.setDescription(description);
                // Register the channel with the system; you can't change the importance
                // or other notification behaviors after this
                NotificationManager notificationManager = getSystemService(NotificationManager.class);
                assert notificationManager != null;
                notificationManager.createNotificationChannel(channel);
            }
        }
    
      
    
      private Bitmap createBitmapFromString(String inputNumber) {
    
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setTextSize(100);
            paint.setTextAlign(Paint.Align.CENTER);
    
            Rect textBounds = new Rect();
            paint.getTextBounds(inputNumber, 0, inputNumber.length(), textBounds);
    
            Bitmap bitmap = Bitmap.createBitmap(textBounds.width() + 10, 90,
                    Bitmap.Config.ARGB_8888);
    
            Canvas canvas = new Canvas(bitmap);
            canvas.drawText(inputNumber, textBounds.width() / 2 + 5, 70, paint);
            return bitmap;
        }
    

    如果有人知道更好的方法,请务必提及

        3
  •  0
  •   anomeric    7 年前

    您可以在文档中找到答案,如下所示: 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;
     }