美文网首页
新特性与行为变更 -- 代码3

新特性与行为变更 -- 代码3

作者: TomyZhang | 来源:发表于2019-11-23 17:10 被阅读0次

通知渠道

Android 8.0+ 通知栏适配

//build.gradle(module)
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.tomorrow.architetest"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:support-compat:28.0.0'

    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tomorrow.architetest">
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".TestBroadcastReceiver">
            <intent-filter>
                <action android:name="com.tomorrow.broadcast" />
            </intent-filter>
        </receiver>
        <service android:name=".TestService"/>
    </application>
</manifest>

//TestService
public class TestService extends Service {
    private static final String TAG = "TestService";
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "zwm, onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "zwm, onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }
}

//TestBroadcastReceiver
public class TestBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "TestBroadcastReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "zwm, onReceive, this: " + this);
    }
}

//MainActivity
package com.tomorrow.architetest;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private static final int NOTIFICATION_ID = 10;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
        setContentView(R.layout.activity_main);

        //创建通知渠道
        NotificationChannelController.createChannels(getApplicationContext());

        Intent intent = new Intent(this, TestService.class);
        PendingIntent actionIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        intent = new Intent(this, TestService.class);
        PendingIntent contentIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        intent = new Intent("com.tomorrow.broadcast");
        intent.setPackage(getPackageName());
        PendingIntent deleteIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NotificationChannelController.CHANNEL_ID_TEST_NOTIFICATION);
        builder.setShowWhen(true)
                .setContentTitle("title")
                .setContentText("content")
                .setLargeIcon(bitmap)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setStyle(new NotificationCompat.BigTextStyle().bigText("content"))
                .setPriority(NotificationCompat.PRIORITY_MIN)
                .setDeleteIntent(deleteIntent)
                .setContentIntent(contentIntent)
                .addAction(0, "action", actionIntent);

        Notification notification = builder.build();
        NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, notification);
    }
}

//NotificationChannelController
package com.tomorrow.architetest;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.annotation.StringRes;

import java.util.ArrayList;
import java.util.List;

public class NotificationChannelController {
    public static final String CHANNEL_ID_TEST_NOTIFICATION = "CHANNEL_ID_TEST_NOTIFICATION";

    @RequiresApi(api = Build.VERSION_CODES.O)
    private enum Channel {
        TEST_NOTIFICATION(CHANNEL_ID_TEST_NOTIFICATION, R.string.app_name, NotificationManager.IMPORTANCE_LOW, true);

        private final String id;
        private final int nameResId;
        private final int importance;
        private final boolean showBadge;

        Channel(String id, @StringRes int nameResId, int importance, boolean showBadge) {
            this.id = id;
            this.nameResId = nameResId;
            this.importance = importance;
            this.showBadge = showBadge;
        }

        public String getId() {
            return id;
        }

        public int getNameResId() {
            return nameResId;
        }

        public int getImportance() {
            return importance;
        }

        public boolean canShowBadge() {
            return showBadge;
        }
    }

    public static void createChannels(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            List<NotificationChannel> channelList = new ArrayList<>();
            for (Channel channel : Channel.values()) {
                NotificationChannel notificationChannel = new NotificationChannel(channel.getId(), context.getString(channel.getNameResId()), channel.getImportance());
                notificationChannel.setShowBadge(channel.canShowBadge());
                channelList.add(notificationChannel);
            }
            if (notificationManager != null) {
                notificationManager.createNotificationChannels(channelList);
            }
        }
    }
}

//输出log
2019-11-22 21:02:09.342 14705-14705/com.tomorrow.architetest D/MainActivity: zwm, onCreate
2019-11-22 21:02:37.070 14705-14705/com.tomorrow.architetest D/TestService: zwm, onCreate
2019-11-22 21:02:37.071 14705-14705/com.tomorrow.architetest D/TestService: zwm, onStartCommand
2019-11-22 21:02:41.767 14705-14705/com.tomorrow.architetest D/TestService: zwm, onStartCommand
2019-11-22 21:02:45.065 14705-14705/com.tomorrow.architetest D/TestBroadcastReceiver: zwm, onReceive, this: com.tomorrow.architetest.TestBroadcastReceiver@3619b37

通知侦听器

//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tomorrow.architetest">
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".TestBroadcastReceiver">
            <intent-filter>
                <action android:name="com.tomorrow.broadcast" />
            </intent-filter>
        </receiver>
        <service android:name=".TestService"/>
        <service
            android:name=".NotificationCollectorService"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
        </service>
    </application>
</manifest>

//NotificationCollectorService
package com.tomorrow.architetest;

import android.os.Build;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.support.annotation.RequiresApi;
import android.util.Log;

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class NotificationCollectorService extends NotificationListenerService {
    private static final String TAG = "NotificationCollector";

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        Log.d(TAG, "zwm, onNotificationPosted, getPackageName: " + sbn.getPackageName());
        Log.d(TAG, "zwm, tickerText: " + sbn.getNotification().tickerText);
        Log.d(TAG, "zwm, android.title: " + sbn.getNotification().extras.get("android.title"));
        Log.d(TAG, "zwm, android.text: " + sbn.getNotification().extras.get("android.text"));
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
        Log.d(TAG, "zwm, onNotificationRemoved, getPackageName: " + sbn.getPackageName());
    }
}

//MainActivity
package com.tomorrow.architetest;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private static final int NOTIFICATION_ID = 10;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
        setContentView(R.layout.activity_main);

        String string = Settings.Secure.getString(getContentResolver(),
                "enabled_notification_listeners");
        if (!string.contains(NotificationCollectorService.class.getName())) {
            startActivity(new Intent(
                    "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
        }

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                sendNotification();
            }
        }, 20000);
    }

    private void sendNotification() {
        Log.d(TAG, "zwm, sendNotification");
        //创建通知渠道
        NotificationChannelController.createChannels(getApplicationContext());

        Intent intent = new Intent(this, TestService.class);
        PendingIntent actionIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        intent = new Intent(this, TestService.class);
        PendingIntent contentIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        intent = new Intent("com.tomorrow.broadcast");
        intent.setPackage(getPackageName());
        PendingIntent deleteIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NotificationChannelController.CHANNEL_ID_TEST_NOTIFICATION);
        builder.setShowWhen(true)
                .setContentTitle("title")
                .setContentText("content")
                .setLargeIcon(bitmap)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setStyle(new NotificationCompat.BigTextStyle().bigText("content"))
                .setPriority(NotificationCompat.PRIORITY_MIN)
                .setDeleteIntent(deleteIntent)
                .setContentIntent(contentIntent)
                .addAction(0, "action", actionIntent);

        Notification notification = builder.build();
        NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, notification);
    }
}

//输出log
2019-11-22 21:13:42.216 16088-16088/com.tomorrow.architetest D/MainActivity: zwm, onCreate
2019-11-22 21:14:03.265 16088-16088/com.tomorrow.architetest D/MainActivity: zwm, sendNotification
2019-11-22 21:14:03.323 16088-16088/com.tomorrow.architetest D/NotificationCollector: zwm, onNotificationPosted, getPackageName: com.tomorrow.architetest
2019-11-22 21:14:03.323 16088-16088/com.tomorrow.architetest D/NotificationCollector: zwm, tickerText: null
2019-11-22 21:14:03.323 16088-16088/com.tomorrow.architetest D/NotificationCollector: zwm, android.title: title
2019-11-22 21:14:03.324 16088-16088/com.tomorrow.architetest D/NotificationCollector: zwm, android.text: content
2019-11-22 21:14:10.759 16088-16088/com.tomorrow.architetest D/NotificationCollector: zwm, onNotificationRemoved, getPackageName: com.tomorrow.architetest
2019-11-22 21:14:10.762 16088-16088/com.tomorrow.architetest D/TestBroadcastReceiver: zwm, onReceive, this: com.tomorrow.architetest.TestBroadcastReceiver@16408a4

前台服务

build.gradle(module)
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.tomorrow.architetest"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:support-compat:28.0.0'

    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tomorrow.architetest">
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> //需要添加这个权限才能启动前台服务
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".ForegroundService"/>
    </application>
</manifest>

//ForegroundService
public class ForegroundService extends Service {
    private static final String TAG = "ForegroundService";
    private static final int NOTIFICATION_ID = 10;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "zwm, onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "zwm, onStartCommand");
        //创建通知渠道
        NotificationChannelController.createChannels(getApplicationContext());
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NotificationChannelController.CHANNEL_ID_TEST_NOTIFICATION);
        builder.setShowWhen(true)
                .setContentTitle("title")
                .setContentText("content")
                .setLargeIcon(bitmap)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setStyle(new NotificationCompat.BigTextStyle().bigText("content"))
                .setPriority(NotificationCompat.PRIORITY_MIN);
        startForeground(NOTIFICATION_ID, builder.build()); //启动前台服务
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "zwm, onDestroy");
    }
}

//NotificationChannelController
public class NotificationChannelController {
    public static final String CHANNEL_ID_TEST_NOTIFICATION = "CHANNEL_ID_TEST_NOTIFICATION";

    @RequiresApi(api = Build.VERSION_CODES.O)
    private enum Channel {
        TEST_NOTIFICATION(CHANNEL_ID_TEST_NOTIFICATION, R.string.app_name, NotificationManager.IMPORTANCE_LOW, true);

        private final String id;
        private final int nameResId;
        private final int importance;
        private final boolean showBadge;

        Channel(String id, @StringRes int nameResId, int importance, boolean showBadge) {
            this.id = id;
            this.nameResId = nameResId;
            this.importance = importance;
            this.showBadge = showBadge;
        }

        public String getId() {
            return id;
        }

        public int getNameResId() {
            return nameResId;
        }

        public int getImportance() {
            return importance;
        }

        public boolean canShowBadge() {
            return showBadge;
        }
    }

    public static void createChannels(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            List<NotificationChannel> channelList = new ArrayList<>();
            for (Channel channel : Channel.values()) {
                NotificationChannel notificationChannel = new NotificationChannel(channel.getId(), context.getString(channel.getNameResId()), channel.getImportance());
                notificationChannel.setShowBadge(channel.canShowBadge());
                channelList.add(notificationChannel);
            }
            if (notificationManager != null) {
                notificationManager.createNotificationChannels(channelList);
            }
        }
    }
}

//MainActivity
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(this, ForegroundService.class);
        startService(intent);
        Log.d(TAG, "zwm, start ForegroundService");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "zwm, onDestroy");
        Intent intent = new Intent(this, ForegroundService.class);
        stopService(intent);
        Log.d(TAG, "zwm, stop ForegroundService");
    }
}

//输出log
2019-11-26 15:19:26.717 30148-30148/com.tomorrow.architetest D/MainActivity: zwm, onCreate
2019-11-26 15:19:26.879 30148-30148/com.tomorrow.architetest D/MainActivity: zwm, start ForegroundService
2019-11-26 15:19:27.167 30148-30148/com.tomorrow.architetest D/ForegroundService: zwm, onCreate
2019-11-26 15:19:27.167 30148-30148/com.tomorrow.architetest D/ForegroundService: zwm, onStartCommand
2019-11-26 15:19:49.709 30148-30148/com.tomorrow.architetest D/MainActivity: zwm, onDestroy
2019-11-26 15:19:49.720 30148-30148/com.tomorrow.architetest D/MainActivity: zwm, stop ForegroundService
2019-11-26 15:19:49.745 30148-30148/com.tomorrow.architetest D/ForegroundService: zwm, onDestroy

强制执行 FLAG_ACTIVITY_NEW_TASK 要求

//build.gradle(module)
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.tomorrow.architetest"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:support-compat:28.0.0'

    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tomorrow.architetest">
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".TestActivity"/>
    </application>
</manifest>

//TestActivity
public class TestActivity extends AppCompatActivity {
    private static final String TAG = "TestActivity";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
    }
}

//MainActivity
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(this, TestActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //需要添加这个FLAG才能从非Activity环境中启动Activity
        getApplicationContext().startActivity(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "zwm, onDestroy");
    }
}

显示屏缺口支持

//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tomorrow.architetest">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"> //设置主题
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

//styles.xml
<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> //无ActionBar
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="demo_controller_btn">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_weight">1</item>
    </style>
</resources>

//MainActivity
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
        setContentView(R.layout.activity_main);
        //判断4.4以上版本
        if (Build.VERSION.SDK_INT >= 19) { //设置沉浸式全面屏
            //获得DecorView
            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE //来帮助你的app来维持一个稳定的布局
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION //确保appUI的主要部分不会因为被系统导航栏覆盖而结束
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN //确保appUI的主要部分不会因为被系统状态栏覆盖而结束
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //隐藏导航栏
                            | View.SYSTEM_UI_FLAG_FULLSCREEN //表示全屏,会将状态栏隐藏,只会隐藏状态栏
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { //适配刘海屏
            WindowManager.LayoutParams lp = getWindow().getAttributes();
            // 仅当缺口区域完全包含在状态栏之中时,才允许窗口延伸到刘海区域显示
//            lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
            // 永远不允许窗口延伸到刘海区域
//            lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
            // 始终允许窗口延伸到屏幕短边上的刘海区域
            lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            getWindow().setAttributes(lp);
        }
    }
}

//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#9988ff"
    android:fitsSystemWindows="true"> //设置fitsSystemWindows属性
    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>

ImageDecoder

//MainActivity
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
        setContentView(R.layout.activity_main);

        new Thread(new Runnable() {
            @Override
            public void run() {
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
                    ImageDecoder.Source source = ImageDecoder.createSource(getResources(), R.drawable.ic_launcher);
                    Bitmap bitmap = null;
                    try {
                        bitmap = ImageDecoder.decodeBitmap(source);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    Log.d(TAG, "zwm, bitmap: " + bitmap);
                }
            }
        }).start();
    }
}

//输出log
2019-11-26 20:58:40.720 3500-3500/com.tomorrow.architetest D/MainActivity: zwm, onCreate
2019-11-26 20:58:41.418 3500-3631/com.tomorrow.architetest D/MainActivity: zwm, bitmap: android.graphics.Bitmap@4dafd4f

AnimatedImageDrawable

//MainActivity
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
        setContentView(R.layout.activity_main);
        imageView = findViewById(R.id.imageview);

        new Thread(new Runnable() {
            @Override
            public void run() {
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
                    ImageDecoder.Source source = ImageDecoder.createSource(getResources(), R.drawable.gif_image);
                    Drawable drawable = null;
                    try {
                        drawable = ImageDecoder.decodeDrawable(source);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    Log.d(TAG, "zwm, drawable: " + drawable);
                    imageView.setImageDrawable(drawable);
                    if(drawable instanceof AnimatedImageDrawable) {
                        ((AnimatedImageDrawable)drawable).start();
                    }
                }
            }
        }).start();
    }
}

//输出log
2019-11-26 21:14:15.656 4499-4499/com.tomorrow.architetest D/MainActivity: zwm, onCreate
2019-11-26 21:14:15.686 4499-4832/com.tomorrow.architetest D/MainActivity: zwm, drawable: android.graphics.drawable.AnimatedImageDrawable@955f527

Activity后台活动限制

//TestActivity
public class TestActivity extends AppCompatActivity {
    private static final String TAG = "TestActivity";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
    }
}

//MainActivity
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "zwm, onCreate");
        setContentView(R.layout.activity_main);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "zwm, run");
                Intent intent = new Intent(MainActivity.this, TestActivity.class);
                startActivity(intent);
            }
        }, 10000);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "zwm, onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "zwm, onStop");
    }
}

//输出log
2019-11-26 21:23:01.509 7569-7569/com.tomorrow.architetest D/MainActivity: zwm, onCreate
2019-11-26 21:23:01.682 7569-7569/com.tomorrow.architetest D/MainActivity: zwm, onStart
2019-11-26 21:23:03.626 7569-7569/com.tomorrow.architetest D/MainActivity: zwm, onStop
2019-11-26 21:23:11.700 7569-7569/com.tomorrow.architetest D/MainActivity: zwm, run //无启动TestActivity

相关文章

网友评论

      本文标题:新特性与行为变更 -- 代码3

      本文链接:https://www.haomeiwen.com/subject/kqihwctx.html