因为我的项目大部分是在工业机运行,而工业机的Rom相对版本比较低,权限也都给的很足。因此也不需要过多的设置,就将最基本的代码贴一下。
一、开机启动
1.创建一个广播接受者BroadcastReceiver类
这个类是被创建在了.receiver包中的 ,在 下一步的 广播注册 部分会被使用
public class AutoStartBroadReceiver extends BroadcastReceiver {
private static final String ACTION = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceive(Context context, Intent intent) {
Log.e("接收广播", "onReceive: ");
Log.e("接收广播", "onReceive: " + intent.getAction());
//开机启动
if (ACTION.equals(intent.getAction())) {
Log.e("接收广播", "onReceive: 启动了。。。");
//第一种方式:根据包名
// PackageManager packageManager = context.getPackageManager();
// Intent mainIntent = packageManager.getLaunchIntentForPackage("com.harry.martin");
// mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// context.startActivity(mainIntent);
// context.startService(mainIntent);
//第二种方式:指定class类,跳转到相应的Acitivity
Intent mainIntent = new Intent(context, LoginActivity.class);
/**
* Intent.FLAG_ACTIVITY_NEW_TASK
* Intent.FLAG_ACTIVITY_CLEAR_TOP
*/
mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mainIntent);
// context.startService(mainIntent);
}
}
}
版权声明:本文为优快云博主「拉莫帅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/chen_md/article/details/123370779
上面的代码中 定义的常量 建议使用 甚至不用定义,直接使用 Intent.ACTION_BOOT_COMPLETED;
就好。
private static final String ACTION = Intent.ACTION_BOOT_COMPLETED;
上面是转来的代码,代码的运行逻辑大致如下:
创建一个类→这个类继承自BroadcastReceiver类→重写了onReceive方法→系统有广播生成就会调用该方法→用if判断是否是一个BOOT_COMPLETED广播(系统启动完毕)→使用Intent 调起我们的目标Activity。
上面的代码中 还提到了 使用包名调起Activity的方法,这个只是Intent各种调起Activity方式的一种,可以搜索Intent来了解。
上面的代码中,对intent都setFlags了,这也是Intent的能力,是关于Android对于Activity的一种装载形式,略微复杂,我用不上,也没怎么研究。我粗浅的理解,主要区别就是用户点击后退按钮时候的表现不同。
2.配置权限
在manifests中加入广播接收权限 用来接收系统的开机广播
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
3.注册广播
同样是在manifests中完成(原文的顺序有一点点问题)
<receiver
android:name=".receiver.AutoStartBroadReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
<activity
android:name=".mvp.view.Activity.LoginActivity"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
版权声明:本文为优快云博主「拉莫帅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/chen_md/article/details/123370779
上面的代码是加入到<application>
标签下的,作用就是告诉系统,我这个APP里有一个广播接收者,因此系统如果产生广播了,不管是啥类型的广播,都会给这个APP推送。
App收到推送后,就会调起name属性中定义的类,来处理这个广播:见前面的部分。
另外这里边还有一个intent-filter
子标签,我的理解:第一个action是声明了一个事件,第二个category是声明了一个动作类别,让调起的Activity作为主屏。不一定对。具体没研究,就这么用即可。
最后的acitivty标签就是普通activity声明,并标记为启动项。
4.简单完成开机启动
之所以说是简单完成,是因为这对低版本的近乎原版的安卓已经够用了,但是如果是开发手机端的App,要考虑新版本的动态授权问题,以及基于国内手机对Android的修改,要做一些响应的处理。这部分可以看我参考的文件:https://blog.youkuaiyun.com/chen_md/article/details/123370779
有个问题就是正常手机谁让你开机启动呢?
二.全屏显示和控制Dialog尺寸
所谓的全屏显示就隐藏状态栏和导航按钮
1. 写一个全屏方法
随便找个地方写一个全屏方法,以便被各种调用,我是将其写到.utils
包中的BaseUtil
类中的。我的每个项目里都会有这么个类,来提供一些小的能力。
/**
* 隐藏 状态栏 和 导航栏
* @param activity
*/
public static void hideBottomUIMenu(Activity activity){
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = activity.getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView = activity.getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
上面的代码对Android版本做了一些处理识别 19就是android4.4。这个对照表一搜一大堆,通过Android studio的SDK Manager也能看到。
2.在Activity中调用
在想要实现全屏的Activity中调用这个方法即可。建议是写到onStart()
中
@Override
protected void onStart() {
super.onStart();
BaseUtil.hideBottomUIMenu(this);
}
这样,每次这个Activity显示都会调用这个全屏方法。
3.处理Dialog弹出的问题
上面两步已经能够完成普通的Activity全屏了,但是当弹出Dialog的时候,状态栏和导航栏又会带出来,这是因为,Dialog有一个自己的Widnow容器。这个容器是没有被HideBottomUIMenu方法修饰过的。因此状态栏和导航栏又会出现。因此我们要对弹出的Dialog进行修饰。
tvNumber.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// 这是我自己写的一个数字键盘的Dialog 后续再单独写一篇
NumberKeyboard numberKeyboard = new NumberKeyboard(mContext);
numberKeyboard.setKeyboardTitle(tvNumber.getHint().toString());
numberKeyboard.setKeyboardNumber(tvNumber.getText().toString());
numberKeyboard.setMaxLength(mMax);
// 显示
numberKeyboard.show();
// 显示后获得这个Dialog的window对象 只有显示出来才能拿到这个对象
Window numberKeyboardWindow = numberKeyboard.getWindow();
// 下面是修改Dialog的尺寸 这个像素映射尺寸计算啥的 也有专门的文章来写,但是我没找到管用的
// 因为我是在固定的设备上使用,所以我这个就是自己试的,不考虑兼容性
WindowManager.LayoutParams numberKeyboardWindowLayoutParams = numberKeyboardWindow.getAttributes();
numberKeyboardWindowLayoutParams.width = 272; //240 32 / 16
numberKeyboardWindowLayoutParams.height = 346; //320 26 / 13
numberKeyboardWindow.setAttributes(numberKeyboardWindowLayoutParams);
// 用全屏方法来修饰这个Dialog的Activity 这一步也不知道有没有用
BaseUtil.hideBottomUIMenu((Activity) mContext);
// 最后是数字键盘的回调事件 把输入的数字读出来
numberKeyboard.setIOnEnterListener(new NumberKeyboard.IOnEnterListener() {
@Override
public void onEnter(String value) {
if (value != null) {
tvNumber.setText((value));
}else{
tvNumber.setText("");
}
}
});
}
});
上面的代码,我是写在一个按钮事件里,弹出了一个自定义的Dialog,并且修改了Dialog的尺寸,修饰了全屏。具体的内容写到注释里了。
4.对Dialog本身的修改
在自定义的Dialog里重写一下Show方法
@Override
public void show() {
// 强制全屏
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
super.show();
fullScreenImmersive(getWindow().getDecorView());
this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}
这个不知道有没有用,在前面部分的代码里调用了全屏方法,做的事情其实差不多,问题在于写到show方法里是否能够获取到getWidnow() ,应该是可以的,否则会报异常。
5.上升空间
根据对第4部分的理解,既然在show方法中能够getWindow(),那么在第3部分中,修改Dialog尺寸的部分,可以写到show方法中。回头测试一下看看。