packageManager.setComponentEnabledSetting
setComponentEnabledSetting方法就是用来禁用Android系统中的四大组件。比如我想禁用一个服务。
/**
* 禁用组件
* @param context 上下文
* @param className 组件类名
*/
private fun disableComponent(context: Context, className: String) {
val componentName = ComponentName(context, className)
if (isComponentDisabled(context, componentName)) return //已经禁用
context.packageManager.setComponentEnabledSetting(
componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP
)
}
如果想重新启用的话,也是上面的方法,只是setComponentEnabledSetting第二个参数值不一样
/**
* 启用组件
* @param context 上下文
* @param className 组件类名
*/
private fun enableComponent(context: Context, className: String) {
val componentName = ComponentName(context, className)
if (isComponentEnabled(context, componentName)) return //已经启用
context.packageManager.setComponentEnabledSetting(
componentName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP
)
}
获取组件状态的方法,getComponentEnabledSetting,具体的代码如下,分别是获取可用状态和禁用状态的方法。
/**
* 组件是否处于可用状态
*/
fun isComponentEnabled(context: Context, componentName: ComponentName): Boolean {
val state: Int = context.packageManager.getComponentEnabledSetting(componentName)
return PackageManager.COMPONENT_ENABLED_STATE_ENABLED == state
}
/**
* 组件是否处于禁用状态
*/
fun isComponentDisabled(context: Context, componentName: ComponentName): Boolean {
val state: Int = context.packageManager.getComponentEnabledSetting(componentName)
return PackageManager.COMPONENT_ENABLED_STATE_DISABLED == state
}
setApplicationEnabledSetting
**setApplicationEnabledSetting()**方法是PackageManager提供的禁用app的方法,一般只能用来禁用自己,不能禁用其他app。
context.packageManager..setApplicationEnabledSetting("com.example.viewtest", PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
- 其他参数介绍:
- COMPONENT_ENABLED_STATE_DEFAULT:恢复组件进入默认的状态
- COMPONENT_ENABLED_STATE_ENABLED:启用组件
- COMPONENT_ENABLED_STATE_DISABLED:禁用组件
- COMPONENT_ENABLED_STATE_DISABLED_USER:由用户禁用app,所以是可以重新启用的,只能setApplicationEnabledSetting()方法使用
- COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:也是禁用app,但是使用者还是可以在界面上看到app,点击之后就会重新启用,状态改为enabled,只能setApplicationEnabledSetting()方法使用
AudioManager探索
AudioManager声音的模式(streamType)如下:
AudioManager.STREAM_MUSIC 媒体声音
AudioManager.STREAM_VOICE_CALL 通话声音
AudioManager.STREAM_SYSTEM 系统声音
AudioManager.STREAM_RING 电话铃声
AudioManager.STREAM_ALARM 闹钟声音
AudioManager.STREAM_NOTIFICATION 通知声音
AudioManager.STREAM_BLUETOOTH_SCO 蓝牙链接声音
AudioManager的附加参数flags如下:
AudioManager.FLAG_SHOW_UI 调整时显示音量条(就是按音量键出现的那个)
AudioManager.FLAG_PLAY_SOUND 改变音量时播放声音
AudioManager.FLAG_VIBRATE 手机铃声进入振动铃声模式是否振动
AudioManager.FLAG_ALLOW_RINGER_MODES 更改音量时是否切换模式,比如响铃音量设置为0时是否开启震动模式
AudioManager.FLAG_SHOW_SILENT_HINT 由于静音模式,无法调整音量,请在用户界面中显示提示。
AudioManager.FLAG_ACTIVE_MEDIA_ONLY 指示仅当媒体正在活动播放时才应处理此问题。
AudioManager.FLAG_SHOW_UI_WARNINGS 就像FLAG_SHOW_UI,但是只有对话框警告和确认,没有滑块。
AudioManager.FLAG_SHOW_VIBRATE_HINT 阻止将音量从振动调低,在用户界面中显示提示。
AudioManager的direction解释:
AudioManager.ADJUST_RAISE 增加铃声音量
AudioManager.ADJUST_LOWER 减小铃声音量。
AudioManager.ADJUST_MUTE 静音
AudioManager.ADJUST_UNMUTE 取消静音
获取当前streamType的音量
getStreamVolume(int streamType);
参数streamType:参考AudioManager的声音模式如:AudioManager.STREAM_MUSIC
设置当前streamType的音量值
设置方法一、直接设置当前音量值
setStreamVolume(int streamType, int index, int flags);
参数streamType:参考AudioManager的声音模式如:AudioManager.STREAM_MUSIC
参数index:音量值
参数flags:附加参数如AudioManager.FLAG_SHOW_UI (调整时显示音量条(就是按音量键出现的那个))
设置方法二、渐进式设置音量值(类似按物理音量键一步一步到指定值)
adjustStreamVolume(int streamType, int direction, int flags);
参数streamType:参考AudioManager的声音模式如:AudioManager.STREAM_MUSIC
参数direction:参考direction解释:如AudioManager.ADJUST_LOWER
参数flags:附加参数如AudioManager.FLAG_SHOW_UI (调整时显示音量条(就是按音量键出现的那个))
设置方法三、渐进式设置音量值
adjustVolume(int direction, int flags);
参数direction:参考direction解释:如AudioManager.ADJUST_LOWER
参数flags:附加参数如AudioManager.FLAG_SHOW_UI (调整时显示音量条(就是按音量键出现的那个))
获取焦点(处理声音重叠问题)
requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)
参数l:焦点切换监听
参数streamType:参考AudioManager的streamType模式如:AudioManager.STREAM_MUSIC
参数durationHint:参考如下
- durationHint参数
AudioManager.AUDIOFOCUS_NONE 用于指示未获得或丢失音频焦点或请求音频焦点。
AudioManager.AUDIOFOCUS_GAIN (效果:重叠播放效果)用于指示未知持续时间的音频聚焦增益或音频聚焦请求。
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT (效果:播放时其他暂停,释放后其他继续播放)用于表示暂时获得或请求音频焦点
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK (效果:类似导航播报,原声音弱化,释放后恢复)用于表示暂时的音频焦点请求,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE (效果:播放时其他暂停,释放后其他继续播放)独占和瞬时音频焦点请求的示例是语音备忘录记录和语音识别,在此期间系统不应播放任何通知和媒体播放应该已暂停
AudioManager.AUDIOFOCUS_LOSS (效果:获取焦点失败,没测出效果)用于指示持续时间未知的音频焦点丢失。
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT (效果:获取焦点失败,没测出效果)用于指示音频焦点暂时丢失。
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK (效果:获取焦点失败,没测出效果)用于指示音频焦点的丢失者可以如果要继续播放(也称为“回避”),请降低输出音量新的焦点所有者不要求其他人保持沉默。
- 是否有媒体声音在播放(也可以处理声音重叠问题的产生)
/**
* Android中判断是否有音频声音在播放(其他第三方应用)
*
* @return
*/
private boolean isFmActive() {
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (am == null) {
return false;
}
return am.isMusicActive();
}
- 强制获取媒体焦点如:正在播放音乐,导航播报,音乐声音弱化或者直接停止,播报结束释放焦点自动播放原音乐
/**
* 强制获取播放焦点
*/
private void focusRequestAudio() {
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (mAudioManager != null) {
// Request audio focus for playback 结束记得释放abandonAudioFocus
int result = mAudioManager.requestAudioFocus(audioFocusChangeListener,
STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE);
//A successful focus change request.
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
//播放自己的音频
} else {
//A failed focus change request.获取焦点失败
Log.e("snow", "=testDemo==获取焦点失败====");
}
}
}
AudioManager.OnAudioFocusChangeListener audioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {//不知为什么只调用了一次
Log.e("snow", "=testDemo==focusChange====" + focusChange);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
//释放声音的焦点
if (mAudioManager != null) {
mAudioManager.abandonAudioFocus(audioFocusChangeListener);
}
}
- 静音模式
/**
* 静音模式
*/
public void silent() {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}
- 震动模式
/**
* 震动模式
*/
public void vibrate() {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
}
- 正常模式
/**
* 正常模式
*/
public void normal() {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
- 获取铃声模式
/**
* 获取铃声模式
*/
public void getRingerMode() {
mAudioManager.getRingerMode();
}
- 获取音频模式
/**
* 获取音频模式
*/
public void getAudioMode() {
mAudioManager.getMode();
}
AtomicInteger类中incrementAndGet与getAndIncrement
- getAndIncrement方法是返回旧值(即加1前的原始值)
- incrementAndGet返回的是新值(即加1后的值)
Android 中 SystemProperties 类使用方法
Android 系统可以通过读取 /system/build.prop 文件查看系统属性。 Systemproperties 类在 android.os 下,路径为:/frameworks/base/core/java/android/os/SystemProperties.java
方法详解:
-
返回字符(String): android.os.SystemProperties.get(String key, String def); 参数:key -- 键值 , def -- 默认值 返回值:有相应的键值,返回键值对应的字符,否则返回默认值 抛出异常:键值超过32位
-
返回整型(int): android.os.SystemProperties.getInt(String key, int def); 参数:key -- 键值 , def -- 默认值 返回值:有相应的键值,返回键值对应的整型,否则返回默认值 抛出异常:键值超过32位
-
返回布尔型(boolean): android.os.SystemProperties.getBoolean(String key, boolean def); 参数:key -- 键值 , def -- 默认值 返回值:有相应的键值,返回键值对应的布尔型,否则返回默认值 抛出异常:键值超过32位
Android之ViewFlipper使用
ViewFlipper的介绍和使用
常用属性
android:inAnimation //设置View或ImageView进入屏幕时使用的动画
android:outAnimation //设置View或ImageView退出屏幕时使用的动画
android:flipInterval //设置View或ImageView之间切换的时间间隔
常用方法
setInAnimation:设置View或ImageView进入屏幕时使用的动画
setOutAnimation:设置View或ImageView退出屏幕时使用的动画
showNext:调用该方法来显示ViewFlipper里的下一个View或ImageView
showPrevious:调用该方法来显示ViewFlipper的上一个View或ImageView
setFilpInterval:设置View或ImageView之间切换的时间间隔
startFlipping:使用上面设置的时间间隔来开始切换所有的View或ImageView,切换会循环进行
stopFlipping:停止View或ImageView切换
静态导入代码如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewFlipper
android:id="@+id/flipper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:flipInterval="2000">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="@drawable/tx1"/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="@drawable/tx2"/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="@drawable/tx3"/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="@drawable/tx4"/>
</ViewFlipper>
</LinearLayout>
Activity代码
public class ViewpFilper extends AppCompatActivity {
private ViewFlipper mFilper;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpfilper);
mFilper=findViewById(R.id.flipper);
mFilper.startFlipping();
}
}
在res目录下新建一个anim文件夹,然后新建right_in.xml、right_out.xml存放动画 right_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1500"
android:fromXDelta="100%p"
android:toXDelta="0" />
</set>
right_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1500"
android:fromXDelta="0"
android:toXDelta="-100%p" />
</set>
最后在viewpfilper.xml布局文件中引用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewFlipper
android:id="@+id/flipper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:flipInterval="2000">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="@drawable/tx1"/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="@drawable/tx2"/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="@drawable/tx3"/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="@drawable/tx4"/>
</ViewFlipper>
</LinearLayout>
动态导入 在anim文件下再添加left_in.xml、left_out.xml。 left_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromXDelta="-100%p"
android:toXDelta="0" />
</set>
left_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromXDelta="0"
android:toXDelta="100%p" />
</set>
GestureDetector手势检测器,监听我们的手势动作 修改ViewFliper Activity
public class ViewpFilper extends AppCompatActivity {
private ViewFlipper mFilper;
private GestureDetector mDetector;//手势探测器
private MyGestureListener mMyGestureListener;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpfilper);
mFilper=findViewById(R.id.flipper);
//实例化SimpleOnGestureListener与GestureDetector对象
mMyGestureListener=new MyGestureListener();
mDetector=new GestureDetector(this,mMyGestureListener);
mFilper.startFlipping();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mDetector.onTouchEvent(event);
}
private class MyGestureListener extends GestureDetector.SimpleOnGestureListener{
private final static int MIN_MOVE = 200; //最小距离
//OnFling中根据X轴方向移动的距离和速度来判断当前用户是向左滑还是向右滑,
// 从而利用showPrevious()或者showNext()来显示上一张或者下一张图片
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if(e1.getX() - e2.getX() > MIN_MOVE){
mFilper.setInAnimation(getApplicationContext(),R.anim.right_in);
mFilper.setOutAnimation(getApplicationContext(), R.anim.right_out);
mFilper.showNext();
}else if(e2.getX() - e1.getX() > MIN_MOVE){
mFilper.setInAnimation(getApplicationContext(),R.anim.left_in);
mFilper.setOutAnimation(getApplicationContext(), R.anim.left_out);
mFilper.showPrevious();
}
return true;
}
}
}
Android 修改屏幕亮度
- 获取系统Settings 中的亮度 系统屏幕亮度值在(0~255)之间,只需要调用以下方法即可。
/**
* 1.获取系统默认屏幕亮度值 屏幕亮度值范围(0-255)
* **/
private int getScreenBrightness(Context context) {
ContentResolver contentResolver = context.getContentResolver();
int defVal = 125;
return Settings.System.getInt(contentResolver,
Settings.System.SCREEN_BRIGHTNESS, defVal);
}
- 修改APP界面屏幕亮度,不会影响其他APP 修改自身 APP 亮度,只需要在Activity OnCreate 方法调用如下代码即可。
/**
* 2.设置 APP界面屏幕亮度值方法
* **/
private void setAppScreenBrightness(int birghtessValue) {
Window window = getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
lp.screenBrightness = birghtessValue / 255.0f;
window.setAttributes(lp);
}
- 修改系统Settings 中屏幕亮度,影响所有APP 修改系统 Settings 中的屏幕亮度,由于会影响到所有APP,需要申请修改Settings 的权限android.permission.WRITE_SETTINGS如果非系统签名的APP,需要用户手动授权后才可以修改背光亮度。
/**
* 5.修改Setting 中屏幕亮度值
*
* 修改Setting的值需要动态申请权限 <uses-permission
* android:name="android.permission.WRITE_SETTINGS"/>
* **/
private void ModifySettingsScreenBrightness(Context context,
int birghtessValue) {
// 首先需要设置为手动调节屏幕亮度模式
setScreenManualMode(context);
ContentResolver contentResolver = context.getContentResolver();
Settings.System.putInt(contentResolver,
Settings.System.SCREEN_BRIGHTNESS, birghtessValue);
}
AIDL中的 in / out
类比java中的数据流的输出流和输入流。 java中的输出输入是以内存为主体。 Android aidl中的in out主体是以方法实现类为主体。
AndroidStudio编译单个Module
gradlew :your_module_name:task_name
举例:
gradlew :app:assembleRelease
adb install 报错大全以及解决方法
我们可以通过查看android源码来确认报错种类,查看android源码,进入frameworks/base/core/java/android/content/pm目录,打开PackageManager.java。文件中声明了各种报错的类型以及Error code。 本文对adb install的报错类型全部列举出来
INSTALL_FAILED_ALREADY_EXISTS = -1; 解释:apk已经存在。 解决:adb install -r 强制安装
INSTALL_FAILED_INVALID_APK = -2; 解释: 无效的apk 解决: 排查方式与INSTALL_FAILED_INVALID_URI 类似
INSTALL_FAILED_INVALID_URI = -3; 解释:无效的apk uri路径 解决:可能的原因 1. 2. 文件权限问题,chmod更改文件权限。
INSTALL_FAILED_INSUFFICIENT_STORAGE = -4; 解释:系统空间不足,无法安装apk 解决:清理系统空间
INSTALL_FAILED_DUPLICATE_PACKAGE = -5; 解释: 重复报名,表示系统中已存在相同的报名apk 解决: 卸载系统中重复包名,或者更改自己的apk包名
INSTALL_FAILED_NO_SHARED_USER = -6; 解释:缺少shareduserdid
INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7; 解释:安装的apk与系统中已存在的apk签名不兼容 解决:重新给apk进行签名,或者卸载掉系统中的签名冲突的apk。
INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8; 解释:安装apk的sharedUserId系统中已存在的apk不同,导致不能兼容覆盖安装 解决: 方法1:查看Androidmanifest中android:sharedUserId信息,修改与之前app的sharedUserId相同。 方法2:卸载系统中的apk,再安装。
INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9; 解释:打包的apk缺少shared library库 解决:在AndroidManifest中添加 <uses-library android:name="xxx"android:required="false"/> 将如下的文件xml拷贝到/system/permission/下,注意文件权限
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<library name="xxx"
file="/system/framework/xxx.jar"/>
</permissions>
INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10; 解释:library库替换时无法删除
INSTALL_FAILED_DEXOPT = -11; 解释:apk预编译错误,缺少dex或者是空间不足导致 解决:多存在源码编译apk出现,源码编译apk选择了预编译,优化dex,导致apk里面没有dex。需要去除apk的预编译。
INSTALL_FAILED_OLDER_SDK = -12; 解释:系统的Android版本过低了,apk不支持 解决:修改app目录下的“build.gradle”文件,将其中的minSdkVersion 、targetSdkVersion 修改后保持跟设备的android API版本一致。
INSTALL_FAILED_CONFLICTING_PROVIDER = -13; 解释:检查应用的provider的唯authority属性与系统中其他应用provider authority属性命令相同,产生冲突并且安装失败。 解决:修改provider的authority命名
INSTALL_FAILED_NEWER_SDK = -14; 解释:系统的Android版本过高,apk不支持 解决:apk需要适配高版本的Android设备
INSTALL_FAILED_TEST_ONLY = -15; 解释:apk为测试版本 解决:安装加 -t 参数,adb install -t *.apk
INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16; 解释:安装的APK文件arm指令格式与模拟器/真机的CPU架构上不兼容 解决:安装到兼容的cpu模拟器/真机,或者apk的so库适配对应的cpu arm架构。
INSTALL_FAILED_MISSING_FEATURE = -17; 使用了一个无效的特性
INSTALL_FAILED_CONTAINER_ERROR = -18; 解释:SD卡访问失败,早期的 android设备版本会出现类似问题。
INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19; 解释:无效的安装路径
INSTALL_FAILED_MEDIA_UNAVAILABLE = -20; 解释:Android应用安装位置当前不可用,早期android设备会出现类似问题
INSTALL_FAILED_VERIFICATION_TIMEOUT = -21; 解释:apk 安装验证超时
INSTALL_FAILED_VERIFICATION_FAILURE = -22; 解释:安装验证失败 解决:打开android设备的未知来源应用安装开关。
INSTALL_FAILED_PACKAGE_CHANGED = -23; 解释:应用被改变了,检测到应用的codePath或者ResourcePath改变了
INSTALL_FAILED_UID_CHANGED = -24; 解释:新安装的包分配了一个不同的UID 解决:卸载app,并删除系统中的残留文件和文件夹,如/data/data,/data/app/, system/app/等目录中包含app残留文件。
INSTALL_FAILED_VERSION_DOWNGRADE = -25; 解释:安装apk的VersionCode低于系统内的 解决:更改VersionCode
INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE = -26; 解释:新安装的apk target SDK 较之前的apk低。 解决:修改targetSdkVersion
INSTALL_PARSE_FAILED_NOT_APK = -100; 解释:非apk文件
INSTALL_PARSE_FAILED_BAD_MANIFEST = -101; 解释:无法解析的 AndroidManifest.xml 文件
INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102; 解释:apk安装异常错误
INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103; 解释:缺少签名或者签名方式有问题 解决:打开应用,查看META-INF 目录下查看是否有CERT.RSA文件。修改build.gradle重新签名。 另外一种情况:Android N后apk增加了v2签名,查看apk是否v1,V2签名都有。android N以下设备如果安装只有V2签名的apk,则会报该错,需要将apk,V1,V2都签名。
INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104; 解释:签名冲突 解决:卸载系统中的apk,再重新安装。
INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105; 解释:签名编码问题 解决:查看签名格式是否合法正确
INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106; 解释:apk里使用了无效的包名 解决:检查包名命令是否合法,比如多余的空格,下划线等。
INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107; 解释:无效的shareduserId,shareduserid值有问题。 解决:查看Androidmanifest中usersharedid的定义是否有问题。
INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108; 解释:MALFORMED,畸形的。Manifest是无效的文件 解决:查看AndroidManifest是否有问题。检查manifest的元素和属性的命令是否规范
INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109; 解释:Manifest是空的
INSTALL_FAILED_INTERNAL_ERROR = -110; 解释:系统问题导致安装失败 解决:模拟器空间不足
INSTALL_FAILED_USER_RESTRICTED = -111; 解释:用户权限问题,无法安装 解决:android手机的调试权限问题,把usb调试权限打开。一般手机的usb调试权限在隐藏的开发者模式菜单项目里面。
INSTALL_FAILED_DUPLICATE_PERMISSION = -112; 解释:androidmanifest存在重复定义的permission
INSTALL_FAILED_NO_MATCHING_ABIS = -113; 解释:应用的so库,没有匹配的CPU指令集架构 解决:build.gradle中添加不同的cpu abi体系。
Android 系统签名实现的三种方式
无论采用何种签名方式,如果想实现具有系统权限的应用,在APK生成时,都需要在AndroidManifest.xml中配置android:sharedUserId=“android.uid.system”,如下所示
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxxx.xxxx"
android:sharedUserId="android.uid.system">
</manifest>
- ubuntu环境编译 该方式需要在安卓源码编译的环境下,在将APK打包至安卓系统升级包时,需要配置Android.mk文件,通过在配置LOCAL_CERTIFICATE 参数时,将其设置为PRESIGNED,如果需要改APK具有系统权限,使用系统签名,则需要设置为platform
LOCAL_CERTIFICATE := platform 或 shared 或 media
Android TV的一些术语
-
Android TV:带有GTVS packages
-
Google TV:带有GTVS-GTV packages
-
CDD:Compatibility Definition Document
-
VSR:Vendor Software Requirements
一 显示方面
- 亮度
- 对比度
- 饱和度
- 清晰度
- 色域空间sRGB/BT709/NTSC/DCI-P3
- 色准
- HDR/HDR10/Dolby Vision
- LCD/LED/MiniLED/MicroLED/OLED
二 存储方面
- 内存
- DDR
三 接口方面
- HDMI1.4/2.0/2.1
- 数字DTMB
- 模拟ATV
- VGA
- Ypbpr
- AV
- USB2.0/3.0
- Camera
四 外围
- Wifi
- 蓝牙
- 遥控语音/远场语音
Dialog、AlertDialog如何实现全屏
1、全屏Dialog实现方式
public class FullScrreenDialog extends Dialog {
public FullScrreenDialog(Context context) {
super(context);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
<!--关键点1-->
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_full_screen, null);
<!--关键点2-->
setContentView(view);
<!--关键点3-->
getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000));
<!--关键点4-->
getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
}
}
android 修改系统wifi默认状态
wifi开关默认值
android 系统默认wifi 开关状态是 关,对应的初始值在 frameworks/base/packages/SettingsProvider/res/values/defaults.xml 文件中,对应字段
<bool name="def_wifi_on">false</bool>
将值修改为true即可默认打开wifi状态 AndroidTv 添加假待机
android 系统复位(Reset 恢复出厂设置)9.0源码分析
Android 9.0 开机后打开Wifi流程和Wifi状态值的保存
Android 12.0源码系列之IMS(一)InputManagerService
最后我在公司服务器上添加hidl失败了,在网上找了很多文章都没有成功。有没有大佬会添加hidl的。教教孩子一个hellword呗~~