Optimize wallpaper

pull/594/head
jhengazuki 6 months ago
parent cf7d522572
commit eb3df300f3
  1. 4
      app/build.gradle
  2. 2
      app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java
  3. 12
      app/src/main/java/com/fongmi/android/tv/api/config/WallConfig.java
  4. 96
      app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWallView.java
  5. 4
      app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java
  6. 15
      app/src/main/java/com/fongmi/android/tv/utils/ImgUtil.java
  7. 23
      app/src/main/res/layout/view_wall.xml
  8. 1
      app/src/main/res/values/styles.xml
  9. 2
      app/src/mobile/java/com/fongmi/android/tv/ui/base/BaseActivity.java
  10. 2
      app/src/mobile/res/drawable/shape_control.xml

@ -13,8 +13,8 @@ android {
applicationId "com.fongmi.android.tv"
minSdk 24
targetSdk 36
versionCode 431
versionName "4.3.1"
versionCode 432
versionName "4.3.2"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString(), "eventBusIndex": "com.fongmi.android.tv.event.EventIndex"]

@ -49,7 +49,7 @@ public abstract class BaseActivity extends AppCompatActivity {
public void setContentView(View view) {
super.setContentView(view);
if (!customWall()) return;
((ViewGroup) findViewById(android.R.id.content)).addView(new CustomWallView(this), 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
((ViewGroup) findViewById(android.R.id.content)).addView(new CustomWallView(this, null), 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
protected Activity getActivity() {

@ -1,7 +1,10 @@
package com.fongmi.android.tv.api.config;
import android.graphics.Bitmap;
import android.text.TextUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.Setting;
@ -10,10 +13,12 @@ import com.fongmi.android.tv.event.RefreshEvent;
import com.fongmi.android.tv.impl.Callback;
import com.fongmi.android.tv.utils.FileUtil;
import com.fongmi.android.tv.utils.Notify;
import com.fongmi.android.tv.utils.ResUtil;
import com.fongmi.android.tv.utils.UrlUtil;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Path;
import java.io.FileOutputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -77,6 +82,7 @@ public class WallConfig {
Path.write(FileUtil.getWall(0), data);
App.post(callback::success);
config.update();
writeCache();
refresh(0);
} catch (Throwable e) {
if (TextUtils.isEmpty(config.getUrl())) App.post(() -> callback.error(""));
@ -85,6 +91,12 @@ public class WallConfig {
}
}
private void writeCache() throws Exception {
Bitmap bitmap = Glide.with(App.get()).asBitmap().load(FileUtil.getWall(0)).diskCacheStrategy(DiskCacheStrategy.NONE).override(ResUtil.getScreenWidth(), ResUtil.getScreenHeight()).submit().get();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(FileUtil.getWallCache()));
bitmap.recycle();
}
public boolean needSync(String url) {
return sync || TextUtils.isEmpty(config.getUrl()) || url.equals(config.getUrl());
}

@ -1,29 +1,32 @@
package com.fongmi.android.tv.ui.custom;
import static android.widget.ImageView.ScaleType.CENTER_CROP;
import static androidx.media3.exoplayer.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.activity.ComponentActivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.media3.common.MediaItem;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.ui.AspectRatioFrameLayout;
import androidx.media3.ui.PlayerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.Setting;
import com.fongmi.android.tv.databinding.ViewWallBinding;
import com.fongmi.android.tv.event.RefreshEvent;
import com.fongmi.android.tv.player.exo.ExoUtil;
import com.fongmi.android.tv.utils.FileUtil;
import com.fongmi.android.tv.utils.ImgUtil;
import com.fongmi.android.tv.utils.ResUtil;
import org.greenrobot.eventbus.EventBus;
@ -34,20 +37,24 @@ import java.io.File;
public class CustomWallView extends FrameLayout implements DefaultLifecycleObserver {
private ImageView image;
private ViewWallBinding binding;
private ExoPlayer player;
private PlayerView video;
private Drawable cache;
public CustomWallView(@NonNull Context context) {
super(context);
init(context);
public CustomWallView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
private void init(Context context) {
((ComponentActivity) context).getLifecycle().addObserver(this);
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!isInEditMode()) init();
}
private void init() {
binding = ViewWallBinding.inflate(LayoutInflater.from(getContext()), this);
((ComponentActivity) getContext()).getLifecycle().addObserver(this);
createPlayer();
addImageView();
addVideoView();
refresh();
}
@ -58,20 +65,6 @@ public class CustomWallView extends FrameLayout implements DefaultLifecycleObser
player.setVolume(0);
}
private void addImageView() {
image = new ImageView(getContext());
image.setScaleType(CENTER_CROP);
addView(image, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
private void addVideoView() {
video = new PlayerView(getContext());
video.setUseController(false);
video.setKeepContentOnPlayerReset(true);
video.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM);
addView(video, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
private boolean isVideo(File file) {
try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
retriever.setDataSource(file.getAbsolutePath());
@ -81,42 +74,59 @@ public class CustomWallView extends FrameLayout implements DefaultLifecycleObser
}
}
private boolean isGif(File file) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
return "image/gif".equals(options.outMimeType);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onRefreshEvent(RefreshEvent event) {
if (event.getType() == RefreshEvent.Type.WALL) refresh();
}
private void refresh() {
cache = Drawable.createFromPath(FileUtil.getWallCache().getAbsolutePath());
load(FileUtil.getWall(Setting.getWall()));
}
private void load(File file) {
if (!file.getName().endsWith("0")) loadRes(ResUtil.getDrawable(file.getName()));
else if (isVideo(file)) loadVideo(file);
else loadImage(file);
else if (isGif(file)) loadGif(file);
else loadImage();
}
private void loadRes(int resId) {
video.setPlayer(null);
player.clearMediaItems();
video.setVisibility(GONE);
image.setImageResource(resId);
}
private void loadImage(File file) {
video.setPlayer(null);
player.clearMediaItems();
video.setVisibility(GONE);
ImgUtil.load(file, image);
binding.video.setPlayer(null);
binding.video.setVisibility(GONE);
binding.image.setImageResource(resId);
}
private void loadVideo(File file) {
binding.video.setPlayer(player);
binding.video.setVisibility(VISIBLE);
binding.image.setImageDrawable(cache);
player.setMediaItem(MediaItem.fromUri(Uri.fromFile(file)));
video.setVisibility(VISIBLE);
video.setPlayer(player);
player.prepare();
}
private void loadGif(File file) {
player.clearMediaItems();
binding.video.setPlayer(null);
binding.video.setVisibility(GONE);
Glide.with(binding.image).asGif().load(file).placeholder(cache).error(cache).diskCacheStrategy(DiskCacheStrategy.NONE).override(ResUtil.getScreenWidth(), ResUtil.getScreenHeight()).into(binding.image);
}
private void loadImage() {
player.clearMediaItems();
binding.video.setPlayer(null);
binding.video.setVisibility(GONE);
binding.image.setImageDrawable(cache);
}
@Override
public void onCreate(@NonNull LifecycleOwner owner) {
EventBus.getDefault().register(this);
@ -125,8 +135,10 @@ public class CustomWallView extends FrameLayout implements DefaultLifecycleObser
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
EventBus.getDefault().unregister(this);
video.setPlayer(null);
binding.video.setPlayer(null);
player.release();
binding = null;
player = null;
cache = null;
}
}

@ -33,6 +33,10 @@ public class FileUtil {
return Path.files("wallpaper_" + index);
}
public static File getWallCache() {
return Path.files("wallpaper_cache");
}
public static void openFile(File file) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

@ -53,21 +53,6 @@ public class ImgUtil {
else view.post(() -> Glide.with(view).load(getUrl(url)).override(view.getWidth(), view.getHeight()).listener(getListener(text, url, view, vod)).into(view));
}
public static void load(File file, ImageView view) {
Glide.with(view).load(file).diskCacheStrategy(DiskCacheStrategy.NONE).error(R.drawable.wallpaper_1).signature(new ObjectKey(file.lastModified())).into(new CustomTarget<Drawable>(ResUtil.getScreenWidth(), ResUtil.getScreenHeight()) {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
if (resource instanceof GifDrawable) ((GifDrawable) resource).start();
view.setImageDrawable(resource);
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
view.setImageDrawable(errorDrawable);
}
});
}
public static Object getUrl(String url) {
String param = null;
url = UrlUtil.convert(url);

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<androidx.media3.ui.PlayerView
android:id="@+id/video"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:keep_content_on_player_reset="true"
app:resize_mode="zoom"
app:shutter_background_color="@color/transparent"
app:surface_type="texture_view"
app:use_controller="false" />
</merge>

@ -28,7 +28,6 @@
<item name="resize_mode">fit</item>
<item name="use_artwork">true</item>
<item name="use_controller">false</item>
<item name="animation_enabled">false</item>
</style>
<style name="Player.Vod">

@ -46,7 +46,7 @@ public abstract class BaseActivity extends AppCompatActivity {
public void setContentView(View view) {
super.setContentView(view);
if (!customWall()) return;
((ViewGroup) findViewById(android.R.id.content)).addView(new CustomWallView(this), 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
((ViewGroup) findViewById(android.R.id.content)).addView(new CustomWallView(this, null), 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
protected Activity getActivity() {

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/white">
android:color="@color/white_60">
<item>
<shape android:shape="oval">
<solid android:color="@color/black_30" />

Loading…
Cancel
Save