因为是做盒子,如果没有连接到wifi或者有线网会导致体验差,很多功能没有办法使用的问题。所以本篇我们就来看看如何实现断网弹窗的问题。
一、基本思路
- 监听广播
- 弹窗
- 自定义弹窗
二、实现过程
1、监听广播
采用动态注册的方式,实现广播监听网络变化广播("android.net.conn.CONNECTIVITY_CHANGE")
private void initReceiver(Context context) {
Loger.i(TAG, "initReceiver");
IntentFilter timeFilter = new IntentFilter();
timeFilter.addAction("android.net.ethernet.ETHERNET_STATE_CHANGED");
timeFilter.addAction("android.net.ethernet.STATE_CHANGE");
timeFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
timeFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
timeFilter.addAction("android.net.wifi.STATE_CHANGE");
timeFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
context.registerReceiver(netReceiver, timeFilter);
}
BroadcastReceiver netReceiver =new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Loger.i(TAG, "onReceive:"+action);
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable()) {
int type2 = networkInfo.getType();
isAlerted = false;
String typeName = networkInfo.getTypeName();
switch (type2) {
case 0:
case 1:
case 9:
if(type2 == 0){
Loger.i(TAG, "MOBILE");
}else if(type2 == 1){
Loger.i(TAG, "WIFI");
}else{
Loger.i(TAG, "ETHERNET");
}
doDismissNetworkAlert();
SystemManager.getInstance().onNetWorkOK();
break;
}
} else {
if(!isAlerted){
if ("com.android.settings".equals(SystemManager.getInstance().getTopActivity())) {
return;
}
doNetworkAlert(context);
Loger.i(TAG, "NO NETWORK CONNECT");
}
}
}
}
};
2、弹窗
使用原始的弹窗(AlertDialog.Builder)
private static void doNetworkAlert(final Context context) {
AlertDialog.Builder builder=new AlertDialog.Builder(context);
builder.setPositiveButton(R.string.net_error_text,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int whichButton) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
context.startActivity(intent);
}
});
alertDialog = builder.create();
alertDialog.setTitle(R.string.net_error_title);
alertDialog.setMessage(""+R.string.net_error_message);
alertDialog.setCancelable(true);
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
}
3、自定义弹窗
3.1 实现java
继承Dialog,重写接口
package com.android.vps.basic.manager;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.vps.basic.R;
public class CustomDialog extends Dialog {
private CustomDialog(Context context, int themeResId) {
super(context, themeResId);
}
public static class Builder {
private View mLayout;
private ImageView mIcon;
private TextView mTitle;
private TextView mMessage;
private Button mButton;
private View.OnClickListener mButtonClickListener;
private CustomDialog mDialog;
public Builder(Context context) {
mDialog = new CustomDialog(context, R.style.Theme_AppCompat_Dialog);
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//加载布局文件
mLayout = inflater.inflate(R.layout.custom_dialog, null, false);
//添加布局文件到 Dialog
mDialog.addContentView(mLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
mIcon = mLayout.findViewById(R.id.dialog_icon);
mTitle = mLayout.findViewById(R.id.dialog_title);
mMessage = mLayout.findViewById(R.id.dialog_message);
mButton = mLayout.findViewById(R.id.dialog_button);
}
/**
* 通过 ID 设置 Dialog 图标
*/
public Builder setIcon(int resId) {
mIcon.setImageResource(resId);
return this;
}
/**
* 用 Bitmap 作为 Dialog 图标
*/
public Builder setIcon(Bitmap bitmap) {
mIcon.setImageBitmap(bitmap);
return this;
}
/**
* 设置 Dialog 标题
*/
public Builder setTitle(@NonNull String title) {
mTitle.setText(title);
mTitle.setVisibility(View.VISIBLE);
return this;
}
/**
* 设置 Message
*/
public Builder setMessage(@NonNull String message) {
mMessage.setText(message);
return this;
}
/**
* 设置按钮文字和监听
*/
public Builder setButton(@NonNull String text, View.OnClickListener listener) {
mButton.setText(text);
mButtonClickListener = listener;
return this;
}
public CustomDialog create() {
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mDialog.dismiss();
mButtonClickListener.onClick(view);
}
});
mDialog.setContentView(mLayout);
mDialog.setCancelable(true); //用户可以点击后退键关闭 Dialog
mDialog.setCanceledOnTouchOutside(false); //用户不可以点击外部来关闭 Dialog
return mDialog;
}
}
}
3.2 UI定义
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff">
<!--绿色#7FFF00 白色#ffffff 红色#CD0000-->
<LinearLayout
android:id="@+id/dialog_header"
android:orientation="vertical"
android:layout_width="330dp"
android:layout_height="wrap_content"
android:padding="16dp"
android:gravity="center"
android:background="#CD0000"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- Icon -->
<ImageView
android:contentDescription="@id/dialog_title"
android:id="@+id/dialog_icon"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/net" />
<!-- Title(default is gone) -->
<TextView
android:id="@+id/dialog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textSize="25sp"
android:textStyle="bold"
android:textColor="#ffffff"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:gravity="center"
app:layout_constraintTop_toBottomOf="@+id/dialog_header"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<!-- Dialog Message -->
<TextView
android:id="@+id/dialog_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
tools:text="Dialog Message" />
<Button
android:id="@+id/dialog_button"
android:layout_width="100dp"
android:layout_height="42dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:Color="#ffffff"
android:textColor="#ffffff"
android:text="goto setting">
</Button>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
3.1 使用
private static CustomDialog customDialog;
@SuppressLint("ResourceType")
private static void doNetworkAlert(final Context context) {
customDialog = new CustomDialog.Builder(context)
.setTitle("检测到你的网络已断开")
.setMessage("请您正确设置网络连接")
.setButton("去设置", new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
context.startActivity(intent);
}
}
).create();
customDialog.setCancelable(true);
customDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
customDialog.show();
isAlerted = true;
}
3.4断网图
截图
原图
三、问题
【android应用】Unable to add window -- token null is not for an application
四、结束语
以上就是本次分享的android应用开发中,网络断开弹窗功能---自定义弹窗。最后惯例给大家推介一下我们的技术工作号,欢迎大家来交流技术问题,谢谢!