activity中实现Dialog、service中实现系统级Dialog、Android源码自定义一个Dialog

本文介绍了如何在Android 8.1.0以上的Service中实现系统级别的对话框,包括原生Dialog的使用以及自定义Dialog的创建、布局和在Service中的调度。重点展示了如何在Service中定时显示对话框以及一个抽象的SpaceCleanDialog示例。
摘要由CSDN通过智能技术生成

在activity中实现dialog

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {

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

        AlertDialog alertDialog = new AlertDialog.Builder(this)
                .setTitle("标题")
                .setMessage("内容")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this,"我知道了",Toast.LENGTH_SHORT).show();
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this,"取消",Toast.LENGTH_SHORT).show();
                    }
                })
                .create();

        alertDialog.show();

    }
}

系统原生的Dialog在service去实现

此方案的实现是基于 Android 8.1.0,自从Android 6.0 以后,Google 就对一些敏感权限做了收敛,因此我们在系统弹框的时候就需要进行判断。

private void justShowDialog() {
    AlertDialog.Builder builder = new AlertDialog.Builder(getContext()) //这里去获取上下文
            .setIcon(android.R.drawable.ic_dialog_info)
            .setTitle("在此处定义标题")
            .setMessage("此处定义内容")
            .setPositiveButton("确定",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                            int whichButton) {
                        }
                    })
            .setNegativeButton("取消",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                            int whichButton) {
                        }
                    });
    AlertDialog dialog = builder.create();
    dialog.setCancelable(false);
    dialog.setCanceledOnTouchOutside(false);       
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        dialog.getWindow().setType((WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY));
    }else {
        dialog.getWindow().setType((WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
    }
    dialog.show(); //最核心一就是展示 
}

如果没有最后的 dialog.show 那自定义的dialog是无法弹出来的。

在service如何使用
在上面我们定义号之后,下面我们就去使用它。

private final Handler mSpHandler;
mSpHandler.post(new Runnable() {
			@Override
			public void run() {
			        justShowDialog();
			    }
			});

这样我们一个系统级的dialog就在service中实现了,不过它是一直在弹框,如果想定时去弹框,可以根据自己的时间去修改。

安卓源码中自定义一个Dialog

首先在你需要系统dialog的路径下面定义一个dialog文件
然后去实现相关的内容
自定义文件

package com.android.server.storage;

import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.SystemProperties;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Gravity;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.util.Log;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.os.Handler;
import android.os.Message;

/**
 * Created by Administrator on 2022/3/3.
 */
public abstract class SpaceCleanDialog extends AlertDialog implements View.OnClickListener {

    private static final int GONE_TIPS      = 1;
    private static final int TIP_SHOW_TIMES = 3000; // 3s

    public  Context mContext;
    private Button PositiveButton,NegativeButton;
    private String text_content;
    private RelativeLayout shutdown_tips;
    private boolean allowPowerOff = true;
    private Button btn_spaceclean,btn_cancel;
    private TextView tv_spaceclean_low,tv_spaceclean_full;

    protected SpaceCleanDialog(Context context ,String text) {

        //frameworks\base\core\res\res\values\styles
        super(context,com.android.internal.R.style.TipDialogStyle);
        mContext = context;
	    getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
		        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
				);  
        WindowManager.LayoutParams attrs = getWindow().getAttributes();
//		attrs.alpha=0.85f;
//      attrs.dimAmount = 1f;
        attrs.setTitle("shutDownDialogWindow");
		DisplayMetrics dm = new DisplayMetrics();
        dm = mContext.getResources().getDisplayMetrics();
        attrs.width = dm.widthPixels; //设置宽度
        attrs.height = dm.heightPixels; //设置宽度
        getWindow().setAttributes(attrs);
        text_content = text;

    }
     public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState); //保存activity的状态
        allowPowerOff = SystemProperties.getBoolean("persist.sys.allowpoweroff", true);
        Log.d("ShutdownDialog", "onCreate: allowPowerOff="+allowPowerOff);
        //调用dialog时 传进来的 
	    if(text_content != null){
            Log.d("wfsisxtc", "text_content is :"+text_content);
			setContentView(com.android.internal.R.layout.dialog_spaceclean);
            btn_spaceclean = (Button)findViewById(com.android.internal.R.id.dialog_btn_spaceclean);                
            btn_cancel = (Button)findViewById(com.android.internal.R.id.dialog_btn_cancel);
            tv_spaceclean_low = (TextView)findViewById(com.android.internal.R.id.tv_spaceclean_low);
            tv_spaceclean_full = (TextView)findViewById(com.android.internal.R.id.tv_spaceclean_full);
            btn_spaceclean.setOnClickListener(this);
            btn_cancel.setOnClickListener(this);
            if(text_content.equals("Full_Space")) {
                btn_cancel.setVisibility(View.GONE);
                tv_spaceclean_low.setVisibility(View.GONE);
                tv_spaceclean_full.setVisibility(View.VISIBLE);
            } else {
                btn_cancel.setVisibility(View.VISIBLE);
                tv_spaceclean_low.setVisibility(View.VISIBLE);
                tv_spaceclean_full.setVisibility(View.GONE);
            }   
        }      
    }

    public abstract void clickCallBack(View view);

    public abstract void dismissCallBack(View view);

    /**
     *
     *
     * @param width
     * @param height
     */
    public void setDialogSize(int width, int height) {
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.width = width;
        params.height = height;
        this.getWindow().setAttributes(params);
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case GONE_TIPS:
                    break;
            }
        }
    };

    @Override
    public void dismiss() {
        super.dismiss();
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
        }
    }




    @Override
    public void onClick(View view) {
        switch (view.getId()) {                
			case com.android.internal.R.id.dialog_btn_spaceclean:
                //前往清理
                clickCallBack(view);
				//dismiss();
				break;
            case com.android.internal.R.id.dialog_btn_cancel:
                //取消
                dismissCallBack(view);
				dismiss();
                break;
        }
    }

	public void setPositiveButton(int resId, OnClickListener onClick) {
        setButton(BUTTON_POSITIVE, mContext.getString(resId), onClick);
    }

    public void setNegativeButton(int resId, OnClickListener onClick) {
        setButton(BUTTON_NEGATIVE, mContext.getString(resId), onClick);
    }
}

布局文件

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="none"
    android:id="@+id/rl_dialog_parent">

    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="温馨提示"
            android:layout_marginTop="6dp"
            android:textSize="24sp"
            android:gravity="center"/>

        <TextView
			android:id="@+id/tv_spaceclean_low"
            android:layout_width="149dp"
            android:layout_height="77dp"
            android:layout_marginTop="9dp"
            android:layout_marginLeft="12dp"
            android:textSize="15sp"
            android:gravity="left"
			android:visibility="visible"
            android:text="@string/space_clean" />
			
		<TextView
			android:id="@+id/tv_spaceclean_full"
            android:layout_width="149dp"
            android:layout_height="77dp"
            android:layout_marginTop="9dp"
            android:layout_marginLeft="12dp"
            android:textSize="15sp"
            android:gravity="left"
			android:visibility="gone"
            android:text="@string/space_clean_full" />

        <Button
            android:id="@+id/dialog_btn_spaceclean"
            android:layout_width="150dp"
            android:layout_height="40dp"
            android:layout_marginTop="14dp"
            android:layout_marginLeft="5dp"
            android:textSize="17sp"
            android:background="@drawable/bg_dialog_spaceclean"
            android:text="@string/gotospace"/>

        <Button
            android:id="@+id/dialog_btn_cancel"
            android:layout_width="150dp"
            android:layout_height="40dp"
            android:layout_marginTop="3dp"
            android:layout_marginLeft="5dp"
            android:textSize="17sp"
            android:background="@drawable/bg_dialog_cancel"
			android:visibility="visible"
            android:text="@string/nexttime"/>

    </LinearLayout>
</ScrollView>

当然定义的这些命名 都需要在系统文件去添加。
以及在service中如何使用:
把它封装成一个函数,减少耦合性,方便其他文件去调用。

    private static String fullspaceButtonText = "Full_Space";
    
	private static class CloseDialogReceiver extends BroadcastReceiver
		implements DialogInterface.OnDismissListener {
		private Context mContext;
		public Dialog dialog;
    
        CloseDialogReceiver(Context context) {
            mContext = context;
            IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
            context.registerReceiver(this, filter);
        }
 
        @Override
        public void onReceive(Context context, Intent intent) {
            dialog.cancel();
        }
 
        public void onDismiss(DialogInterface unused) {
            mContext.unregisterReceiver(this);
        }
    }

    private void scheduledSpaceClean(String text) {
        final StorageManager storage = getContext().getSystemService(StorageManager.class);
        final CloseDialogReceiver closer = new CloseDialogReceiver(getContext());
        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
            if(scdialog != null)
            {
                scdialog.dismiss();
            }
            final File file = vol.getPath();
            final UUID uuid = StorageManager.convert(vol.getFsUuid());
            final State state = findOrCreateState(uuid);
            //这里传入的是上下文,和想要修改时区分的参数
            SpaceCleanDialog  spacecleanDialog = new SpaceCleanDialog(getContext(),text) {
                @Override
    		    public void clickCallBack(View view) {  
    		        switch (view.getId()){
    				    case com.android.internal.R.id.dialog_btn_spaceclean:
    						Slog.v(TAG, "go to clean up>>>>>>>>>>");
                            Intent intent = new Intent("android.intent.action.fullMem.xtc");
                            intent.putExtra("memory", state.lastUsableBytes);
                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            getContext().startActivity(intent);
                            dismiss();
    						break;
                        }
                    }
                    @Override
                    public void dismissCallBack(View view) {
    				Slog.v(TAG, "dismissCallBack");
    			}
            };
            closer.dialog = spacecleanDialog;
            spacecleanDialog.getWindow().addFlags(
    			WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON|WindowManager.LayoutParams.FLAG_SECURE);
    		spacecleanDialog.show();
            scdialog=spacecleanDialog;//此处是为了 当系统弹框未取消时,不再多次弹框,仅保持一次弹框
        }
    }

	//使用时就非常简单
	scheduledSpaceClean(fullspaceButtonText);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值