目录
  • 前言
  • 一、壁纸设置
    • (1)代码壁纸设置
      • 通过WallpaperManager设置
    • (2)adb壁纸设置
    • 二、壁纸验证
      • (1)系统应用代码中验证
        • (2)adb 复制文件验证
          • (3)apk验证,请看附件
          • 三、其他
            • (1)壁纸设置无效
              • (2)壁纸和桌面Launcher的关系
                • (3)壁纸设置的系统代码流程
                  • (4)系统默认壁纸设置失败?

                  前言

                  首先说一下,Android手机壁纸Wallpaper和桌面Launcher是分开的,是两个不同的应用

                  Wallpaper在系统Framework也有相关Manager和Service;

                  Android Launcher默认背景是透明的,覆盖在壁纸之上

                  简单的理解就是Launcher就是一个显示了很多应用图标的apk。

                  Android壁纸设置后会存路径:

                  /data/system/users/0/wallpaper

                  这个wallpaper是一个文件,可以pull到电脑中添加后缀.png查看图片。

                  一、壁纸设置

                  (1)代码壁纸设置

                  AndroidManifest.xml中需要申明权限:

                  <uses-permission android:name = "android.permission.SET_WALLPAPER"/>

                  通过WallpaperManager设置

                  该方法可以直接将图片置为壁纸,对于所有平台的Android系统都使用。

                  设置Bitmap对象

                  try {
                      WallpaperManager wpm = (WallpaperManager) getActivity().getSystemService(Context.WALLPAPER_SERVICE);
                      if (wpm != null) {
                          Bitmap mBitmap = BitmapFactory.decodeFile(path); //path为绝对路径
                          //第一个参数是Bitmap对象,第二个参数是截取图片的大小矩形,第三个参数是是否备份
                          wpm.setBitmap(mBitmap, new Rect(0, 0, right, bottom), true); 
                          Log.i("liwenzhi", "wallpaper not null");
                      }
                  } catch (IOException e) {
                      Log.e(TAG, "Failed to set wallpaper: " + e);
                  }
                  

                  Android 10及以后的版本要注意,普通应用连sdcard文件读取的权限都没有,因为加了沙箱机制了。

                  不过也是有方法解决的

                  1是添加系统签名android.uid.system

                  2是添加WRITE_MEDIA_STORAGE权限

                      <uses-permission android:name = "android.permission.SET_WALLPAPER"/>
                      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
                      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
                      //Android10及以后的版本,需要额外添加的权限
                      <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE"
                          tools:ignore="ProtectedPermissions" />
                  

                  还有一种方法是设置Source对象

                  指的是应用内部的图片文件,比如raw目录或者drawable目录,的文件
                  并且只支持PNG or JPEG格式的图片。

                  try {
                      WallpaperManager wpm = WallpaperManager.getInstance(context);//同getActivity().getSystemService(Context.WALLPAPER_SERVICE);
                      wpm.setResource(getResources().getIdentifier(name, "drawable", context.getPackageName()));
                  } catch (IOException e) {
                      Log.e("TAG","error = " + e.getMessage());
                  }
                  

                  该方式不需要读取权限,只要SET_WALLPAPER权限即可。

                  (2)adb壁纸设置

                  需要root权限!而且需要重启一次,才能看到效果,因为没有调用到系统刷新。

                  //root
                  adb root
                  //拉到电脑的D盘temp目录下,电脑中看
                  adb push D:/temp/wallpaper.png /data/system/users/0/wallpaper 
                  //拉到sdcard根目录,手机应用中看
                  adb push /sdcard/wallpaper.png /data/system/users/0/wallpaper
                  //需要重启才能生效
                  adb root
                  

                  二、壁纸验证

                  需要权限(即系统应用、root权限)!

                  (1)系统应用代码中验证

                  打开壁纸文件

                  //显示壁纸图片,需要系统签名
                      public void showWallpaper(View view) {
                          try {
                              Bitmap bitmap = BitmapFactory.decodeFile("/data/system/users/0/wallpaper");
                              iv_wallpaper.setImageBitmap(bitmap);
                          } catch (Exception e) {
                              Log.e(TAG, "showWallpaper error = " + e.getMessage());
                              tv_info.append("showWallpaper error = " + e.getMessage());
                          }
                      }
                      //把壁纸pull到sdcard目录,需要系统签名
                      public void pullWallpaperToSdcard(View view) {
                          Log.i(TAG, "pullWallpaperToSdcard start");
                          File fromFile = new File("/data/system/users/0/wallpaper");
                          File toFile = new File("/sdcard/" + getTimeString() + "_wallpaper.png");
                          copyFile(fromFile, toFile);
                          Log.i(TAG, "pullWallpaperToSdcard end");
                      }
                      //获取当前时间的完整显示字符串
                      private String getTimeString() {
                          SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
                          return format.format(new Date(System.currentTimeMillis()));
                      }
                      //复制文件操作
                      private void copyFile(File fromFile, File toFile) {
                          try {
                              if (!toFile.getParentFile().exists()) {
                                  toFile.getParentFile().mkdirs();
                              }
                              java.io.FileInputStream fosfrom = new java.io.FileInputStream(fromFile);
                              java.io.FileOutputStream fosto = new FileOutputStream(toFile);
                              byte bt[] = new byte[1024];
                              int c;
                              while ((c = fosfrom.read(bt)) > 0) {
                                  fosto.write(bt, 0, c); //将内容写到新文件当中
                              }
                              fosfrom.close();
                              fosto.close();
                          } catch (Exception e) {
                              Log.e(TAG, e.getMessage());
                              tv_info.append("copyFile error = " + e.getMessage());
                          }
                      }
                  

                  (2)adb 复制文件验证

                  //root权限
                  adb root
                  //拉到电脑的D盘temp目录下,电脑中看
                  adb pull /data/system/users/0/wallpaper D:/temp/wallpaper.png
                  //拉到sdcard根目录,手机应用中看
                  adb pull /data/system/users/0/wallpaper D:/temp/wallpaper.png
                  

                  (3)apk验证,请看附件

                  这个wallpaper.apk只能替换壁纸,若要显示和pull文件需要签名文件,替换项目中的签名文件即可。

                  简单的设置壁纸验证壁纸的apk资源点击下载

                  三、其他

                  (1)壁纸设置无效

                  和Launcher相关,Launcher界面是覆盖在壁纸之上的。

                  (2)壁纸和桌面Launcher的关系

                  没啥关系。但是Launcher可以覆盖壁纸。

                  壁纸是与系统服务,以及SystemUi相关的。

                  你把/data/system/users/0/wallpaper文件删除,会发现,壁纸背景是黑色的。

                  (3)壁纸设置的系统代码流程

                  有兴趣的看:https://www.jb51.net/article/44216.htm

                  (4)系统默认壁纸设置失败?

                  默认壁纸路径:

                  frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.png

                  要注意res同一个目录下有多个drawable文件夹,有的里面也有default_wallpaper.png图片。

                  如果是替换了drawable里面多个default_wallpaper.png图片没用反应

                  那么要看看系统源码哪里出错了,多加一些打印看看进行具体情况分析

                  里面是有读取default_wallpaper.png图片的代码逻辑,比如关键字:

                  R.drawable.default_wallpaper

                  以上就是Android开发壁纸的验证设置和确认功能实现demo的详细内容,更多关于Android开发壁纸验证设置确认的资料请关注其它相关文章!

                  声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。