diff --git a/app/build.gradle b/app/build.gradle index 11d57adb7..7de6fd686 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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"] diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java index 688e8d156..901fc5af2 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java @@ -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() { diff --git a/app/src/main/java/com/fongmi/android/tv/api/config/WallConfig.java b/app/src/main/java/com/fongmi/android/tv/api/config/WallConfig.java index b85c62775..7b79d16ae 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/config/WallConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/config/WallConfig.java @@ -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()); } diff --git a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWallView.java b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWallView.java index d6ed05301..c40812211 100644 --- a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWallView.java +++ b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWallView.java @@ -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; } } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java index 3deb9f327..5bd271b7e 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java @@ -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); diff --git a/app/src/main/java/com/fongmi/android/tv/utils/ImgUtil.java b/app/src/main/java/com/fongmi/android/tv/utils/ImgUtil.java index 396443ba4..251a3bdd4 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/ImgUtil.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/ImgUtil.java @@ -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(ResUtil.getScreenWidth(), ResUtil.getScreenHeight()) { - @Override - public void onResourceReady(@NonNull Drawable resource, @Nullable Transition 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); diff --git a/app/src/main/res/layout/view_wall.xml b/app/src/main/res/layout/view_wall.xml new file mode 100644 index 000000000..347310e32 --- /dev/null +++ b/app/src/main/res/layout/view_wall.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 43a2cb4b1..32ce72e7a 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -28,7 +28,6 @@ fit true false - false