V1.0.1(2)修改bug,添加进度条,优化界面

This commit is contained in:
lihongwei 2025-03-19 15:55:40 +08:00
parent f4b54c5e52
commit abd022ee8b
15 changed files with 254 additions and 81 deletions

View File

@ -13,8 +13,8 @@ android {
applicationId = "com.live.flowlivewallpaper" applicationId = "com.live.flowlivewallpaper"
minSdk = 23 minSdk = 23
targetSdk = 34 targetSdk = 34
versionCode = 1 versionCode = 2
versionName = "1.0.0" versionName = "1.0.1"
setProperty( setProperty(
"archivesBaseName", "archivesBaseName",
"Flow Live Wallpaper_V" + versionName + "(${versionCode})_$timestamp" "Flow Live Wallpaper_V" + versionName + "(${versionCode})_$timestamp"

View File

@ -1,8 +1,13 @@
package com.live.flowlivewallpaper; package com.live.flowlivewallpaper;
import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import androidx.annotation.NonNull;
import com.live.flowlivewallpaper.data.dao.FlowEntityDao; import com.live.flowlivewallpaper.data.dao.FlowEntityDao;
import com.live.flowlivewallpaper.data.database.AppDatabase; import com.live.flowlivewallpaper.data.database.AppDatabase;
@ -26,6 +31,8 @@ public class MyApplication extends Application {
application = this; application = this;
lockScreenOrientation();
SharedPreferences sharedPreferences = getSharedPreferences(PREF_NAME, MODE_PRIVATE); SharedPreferences sharedPreferences = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
boolean isDatabaseInitialized = sharedPreferences.getBoolean(KEY_INIT, false); boolean isDatabaseInitialized = sharedPreferences.getBoolean(KEY_INIT, false);
@ -35,6 +42,45 @@ public class MyApplication extends Application {
} }
} }
private void lockScreenOrientation(){
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
}
});
}
public static Context getContext() { public static Context getContext() {
return application.getApplicationContext(); return application.getApplicationContext();
} }

View File

@ -0,0 +1,9 @@
package com.live.flowlivewallpaper.callback;
import java.io.File;
public interface OnDownloadProgressListener {
void onSuccess(File file);
void onFailure(Exception e);
void onProgress(int progress);
}

View File

@ -31,7 +31,7 @@ public class LiveService extends WallpaperService {
private void initExoPlayer() { private void initExoPlayer() {
exoPlayer = new ExoPlayer.Builder(LiveService.this).build(); exoPlayer = new ExoPlayer.Builder(LiveService.this).build();
exoPlayer.setRepeatMode(ExoPlayer.REPEAT_MODE_ALL); exoPlayer.setRepeatMode(ExoPlayer.REPEAT_MODE_ONE);
update(); update();
} }

View File

@ -1,5 +1,6 @@
package com.live.flowlivewallpaper.ui.activity; package com.live.flowlivewallpaper.ui.activity;
import android.animation.ObjectAnimator;
import android.app.WallpaperManager; import android.app.WallpaperManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
@ -7,6 +8,7 @@ import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Toast;
import androidx.activity.EdgeToEdge; import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
@ -16,6 +18,7 @@ import androidx.core.view.WindowInsetsCompat;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import com.live.flowlivewallpaper.R; import com.live.flowlivewallpaper.R;
import com.live.flowlivewallpaper.callback.OnDownloadProgressListener;
import com.live.flowlivewallpaper.data.entity.FlowEntity; import com.live.flowlivewallpaper.data.entity.FlowEntity;
import com.live.flowlivewallpaper.databinding.ActivityLiveBinding; import com.live.flowlivewallpaper.databinding.ActivityLiveBinding;
import com.live.flowlivewallpaper.service.LiveService; import com.live.flowlivewallpaper.service.LiveService;
@ -29,8 +32,7 @@ public class LiveActivity extends AppCompatActivity {
private ActivityLiveBinding binding; private ActivityLiveBinding binding;
private FlowEntity flowEntity; private FlowEntity flowEntity;
private FlowViewModel flowViewModel; private FlowViewModel flowViewModel;
private int flowId; private WallpaperDownloader downloader;
private String image;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -40,38 +42,38 @@ public class LiveActivity extends AppCompatActivity {
setContentView(binding.getRoot()); setContentView(binding.getRoot());
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); // v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets; return insets;
}); });
downloader = new WallpaperDownloader();
initData(); initData();
initEvent(); initEvent();
} }
private void initData() { private void initData() {
flowEntity = (FlowEntity) getIntent().getSerializableExtra("flowEntity"); flowEntity = (FlowEntity) getIntent().getSerializableExtra("flowEntity");
int flowId;
String image;
if (flowEntity != null) { if (flowEntity != null) {
flowId = flowEntity.getFlowId(); flowId = flowEntity.getFlowId();
image = flowEntity.getImage(); image = flowEntity.getImage();
} else { } else {
finish(); finish();
return;
} }
showProgress(); showProgress();
flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class); flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class);
String quality; String quality = flowEntity.getWallpaperType() == 2 ? "ViewShiftLive" : "ViewLive";
if (flowEntity.getWallpaperType() == 2) {
quality = "ViewShiftLive";
} else {
quality = "ViewLive";
}
if (Objects.equals(flowEntity.getWallpaperPath(), "")) { if (Objects.equals(flowEntity.getWallpaperPath(), "")) {
WallpaperDownloader.downloadMp4FileAsync(this, flowId, image, quality, new WallpaperDownloader.OnDownloadCompleteListener() { downloader.downloadMp4FileAsync(this, flowId, image, quality, new OnDownloadProgressListener() {
@Override @Override
public void onSuccess(File file) { public void onSuccess(File file) {
if (binding == null) return;
flowEntity.setWallpaperPath(file.getAbsolutePath()); flowEntity.setWallpaperPath(file.getAbsolutePath());
flowViewModel.update(flowEntity); flowViewModel.update(flowEntity);
loadVideoSuccess(); loadVideoSuccess();
@ -80,18 +82,26 @@ public class LiveActivity extends AppCompatActivity {
@Override @Override
public void onFailure(Exception e) { public void onFailure(Exception e) {
Log.d("onFailure", e.getMessage()); if (binding == null) return;
Log.d("onFailure", flowId + " " + image);
hideProgress(); hideProgress();
Toast.makeText(LiveActivity.this, "Download failed", Toast.LENGTH_SHORT).show();
Log.e("LiveActivity", "Download failed", e);
} }
@Override
public void onProgress(int progress) {
if (!isFinishing() && !isDestroyed() && binding != null && progress >= 0 && progress <= 100) {
binding.downloadProgressBar.setProgress(progress);
binding.progressText.setText(progress + "%");
}
}
}); });
} else { } else {
loadVideoSuccess(); loadVideoSuccess();
hideProgress(); hideProgress();
} }
loadFavorite(); loadLike();
} }
private void initEvent() { private void initEvent() {
@ -111,9 +121,10 @@ public class LiveActivity extends AppCompatActivity {
File videoFile = new File(flowEntity.getWallpaperPath()); File videoFile = new File(flowEntity.getWallpaperPath());
if (videoFile.exists()) { if (videoFile.exists()) {
binding.videoView.setVideoPath(flowEntity.getWallpaperPath()); binding.videoView.setVideoPath(flowEntity.getWallpaperPath());
Log.d("VideoPath", flowEntity.getWallpaperPath());
binding.videoView.start(); binding.videoView.start();
binding.videoView.setOnPreparedListener(mp -> mp.setLooping(true)); binding.videoView.setOnPreparedListener(mp -> mp.setLooping(true));
} else {
Log.e("LiveActivity", "Video file missing: " + flowEntity.getWallpaperPath());
} }
} }
} }
@ -122,6 +133,12 @@ public class LiveActivity extends AppCompatActivity {
SharedPreferences prefs = getSharedPreferences("WallpaperPrefs", MODE_PRIVATE); SharedPreferences prefs = getSharedPreferences("WallpaperPrefs", MODE_PRIVATE);
prefs.edit().putString("video_path", flowEntity.getWallpaperPath()).apply(); prefs.edit().putString("video_path", flowEntity.getWallpaperPath()).apply();
WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
try {
wallpaperManager.clear();
} catch (Exception ignored) {
}
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER); Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
new ComponentName(this, LiveService.class)); new ComponentName(this, LiveService.class));
@ -129,24 +146,34 @@ public class LiveActivity extends AppCompatActivity {
finish(); finish();
} }
private void loadFavorite() { private void loadLike() {
flowViewModel.getLike(flowEntity.getWallpaperType(), flowEntity.getFlowId()).observe(this, wallpaper -> setLike()); flowViewModel.getLike(flowEntity.getWallpaperType(), flowEntity.getFlowId()).observe(this, wallpaper -> setLike());
} }
private void setLike() { private void setLike() {
binding.like.setImageResource( if (binding != null) {
flowEntity.isFavorite() ? R.drawable.like : R.drawable.dislike binding.like.setImageResource(flowEntity.isFavorite() ? R.drawable.like : R.drawable.dislike);
); }
}
private void hideProgress() {
binding.progressBar.setVisibility(View.GONE);
binding.view.setVisibility(View.GONE);
} }
private void showProgress() { private void showProgress() {
binding.progressBar.setVisibility(View.VISIBLE); if (binding != null) {
binding.view.setVisibility(View.VISIBLE); binding.downloadProgressBar.setVisibility(View.VISIBLE);
binding.progressTip.setVisibility(View.VISIBLE);
binding.progressText.setVisibility(View.VISIBLE);
binding.loadingSpinner.setVisibility(View.VISIBLE);
binding.view.setVisibility(View.VISIBLE);
}
}
private void hideProgress() {
if (!isFinishing() && !isDestroyed() && binding != null) {
binding.downloadProgressBar.setVisibility(View.GONE);
binding.progressTip.setVisibility(View.GONE);
binding.progressText.setVisibility(View.GONE);
binding.loadingSpinner.setVisibility(View.GONE);
binding.view.setVisibility(View.GONE);
}
} }
@Override @Override
@ -160,6 +187,7 @@ public class LiveActivity extends AppCompatActivity {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
downloader.cancelDownload();
binding = null; binding = null;
} }
} }

View File

@ -14,6 +14,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.live.flowlivewallpaper.R; import com.live.flowlivewallpaper.R;
import com.live.flowlivewallpaper.data.entity.FlowEntity; import com.live.flowlivewallpaper.data.entity.FlowEntity;
@ -51,10 +52,6 @@ public class FlowAdapter extends RecyclerView.Adapter<FlowAdapter.ViewHolder> {
public void onBindViewHolder(ViewHolder holder, int position) { public void onBindViewHolder(ViewHolder holder, int position) {
FlowEntity flowEntity = flowEntities.get(position); FlowEntity flowEntity = flowEntities.get(position);
holder.bind(flowEntity); holder.bind(flowEntity);
int randomHeight = (position % 2 == 0) ? 800 : 1000;
ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
params.height = randomHeight;
holder.itemView.setLayoutParams(params);
} }
@Override @Override
@ -83,7 +80,7 @@ public class FlowAdapter extends RecyclerView.Adapter<FlowAdapter.ViewHolder> {
private void loadImage(String imagePath) { private void loadImage(String imagePath) {
Glide.with(context) Glide.with(context)
.load(imagePath) .load(imagePath)
.transform(new RoundedCorners(32)) .transform(new CenterCrop(),new RoundedCorners(32))
.error(R.mipmap.placeholder) .error(R.mipmap.placeholder)
.placeholder(R.mipmap.placeholder) .placeholder(R.mipmap.placeholder)
.into(imageView); .into(imageView);

View File

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.StaggeredGridLayoutManager; import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -38,7 +39,7 @@ public class ExploreFragment extends Fragment {
private void initData() { private void initData() {
flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class); flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class);
binding.recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)); binding.recyclerView.setLayoutManager(new GridLayoutManager(requireContext(),2));
adapter = new FlowAdapter(flowViewModel, requireContext(), new ArrayList<>(), requireActivity()); adapter = new FlowAdapter(flowViewModel, requireContext(), new ArrayList<>(), requireActivity());
binding.recyclerView.setAdapter(adapter); binding.recyclerView.setAdapter(adapter);

View File

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.StaggeredGridLayoutManager; import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -38,7 +39,7 @@ public class FavoriteFragment extends Fragment {
private void initData() { private void initData() {
flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class); flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class);
binding.recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)); binding.recyclerView.setLayoutManager(new GridLayoutManager(requireContext(),2));
adapter = new FlowAdapter(flowViewModel, requireContext(), new ArrayList<>(), requireActivity()); adapter = new FlowAdapter(flowViewModel, requireContext(), new ArrayList<>(), requireActivity());
binding.recyclerView.setAdapter(adapter); binding.recyclerView.setAdapter(adapter);

View File

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.StaggeredGridLayoutManager; import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -38,7 +39,7 @@ public class ShiftFragment extends Fragment {
private void initData() { private void initData() {
flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class); flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class);
binding.recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)); binding.recyclerView.setLayoutManager(new GridLayoutManager(requireContext(),2));
adapter = new FlowAdapter(flowViewModel, requireContext(), new ArrayList<>(), requireActivity()); adapter = new FlowAdapter(flowViewModel, requireContext(), new ArrayList<>(), requireActivity());
binding.recyclerView.setAdapter(adapter); binding.recyclerView.setAdapter(adapter);

View File

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.StaggeredGridLayoutManager; import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -39,7 +40,7 @@ public class TrendingFragment extends Fragment {
private void initData() { private void initData() {
flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class); flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class);
binding.recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)); binding.recyclerView.setLayoutManager(new GridLayoutManager(requireContext(),2));
adapter = new FlowAdapter(flowViewModel, requireContext(), new ArrayList<>(), requireActivity()); adapter = new FlowAdapter(flowViewModel, requireContext(), new ArrayList<>(), requireActivity());
binding.recyclerView.setAdapter(adapter); binding.recyclerView.setAdapter(adapter);

View File

@ -1,36 +1,19 @@
package com.live.flowlivewallpaper.util; package com.live.flowlivewallpaper.util;
import android.content.Context;
import android.os.Environment;
import androidx.annotation.NonNull;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import android.content.Context; import android.content.Context;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.live.flowlivewallpaper.callback.OnDownloadProgressListener;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import okhttp3.Call; import okhttp3.Call;
@ -44,17 +27,23 @@ import okhttp3.Response;
public class WallpaperDownloader { public class WallpaperDownloader {
private static final String SERVER_URL = "https://neutrolabgames.com/LiveLoop/AppData/jmywall.php"; private static final String SERVER_URL = "https://neutrolabgames.com/LiveLoop/AppData/jmywall.php";
private static final OkHttpClient client = new OkHttpClient.Builder() private static final OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS)
.build(); .build();
private static final Handler mainHandler = new Handler(Looper.getMainLooper()); private static final Handler mainHandler = new Handler(Looper.getMainLooper());
public static void downloadMp4FileAsync(Context context, int pi, String image,String quality, OnDownloadCompleteListener listener) { private Call currentCall;
public WallpaperDownloader() {
this.currentCall = null;
}
public void downloadMp4FileAsync(Context context, int pi, String image, String quality, OnDownloadProgressListener listener) {
RequestBody requestBody = new FormBody.Builder() RequestBody requestBody = new FormBody.Builder()
.add("pi", String.valueOf(pi)) .add("pi", String.valueOf(pi))
.add("medium", "5eV6snEwfY7Yv6Ub") .add("medium", "5eV6snEwfY7Yv6Ub")
.add("alpha", image) .add("alpha", image != null ? image : "")
.add("version", "DL8") .add("version", "DL8")
.add("quality", quality) .add("quality", quality)
.build(); .build();
@ -64,27 +53,59 @@ public class WallpaperDownloader {
.post(requestBody) .post(requestBody)
.build(); .build();
client.newCall(request).enqueue(new Callback() { WeakReference<Context> weakContext = new WeakReference<>(context);
currentCall = client.newCall(request);
currentCall.enqueue(new Callback() {
@Override @Override
public void onFailure(@NonNull Call call, @NonNull IOException e) { public void onFailure(@NonNull Call call, @NonNull IOException e) {
mainHandler.post(() -> listener.onFailure(e)); mainHandler.post(() -> {
if (listener != null) {
listener.onFailure(e);
}
});
} }
@Override @Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
if (!response.isSuccessful()) { if (!response.isSuccessful()) {
mainHandler.post(() -> listener.onFailure(new IOException("Download failure: " + response.code()))); mainHandler.post(() -> {
if (listener != null) {
listener.onFailure(new IOException("Download failure: " + response.code()));
}
});
return; return;
} }
if (response.body() == null) { if (response.body() == null) {
mainHandler.post(() -> listener.onFailure(new IOException("The response body is empty"))); mainHandler.post(() -> {
if (listener != null) {
listener.onFailure(new IOException("The response body is empty"));
}
});
return; return;
} }
String fileName = "wallpaper_" + System.currentTimeMillis() + pi + image + ".mp4"; String fileLengthStr = response.header("File-Length");
File dir = context.getExternalFilesDir(Environment.DIRECTORY_MOVIES); long totalBytes = -1;
if (fileLengthStr != null) {
try {
totalBytes = Long.parseLong(fileLengthStr);
} catch (NumberFormatException ignored) {
}
}
if (totalBytes <= 0) {
totalBytes = response.body().contentLength();
}
Context ctx = weakContext.get();
if (ctx == null) {
return;
}
String fileName = "wallpaper_" + System.currentTimeMillis() + pi + (image != null ? image : "") + ".mp4";
File dir = ctx.getExternalFilesDir(Environment.DIRECTORY_MOVIES);
File file = new File(dir, fileName); File file = new File(dir, fileName);
long downloadedBytes = 0;
try (InputStream inputStream = response.body().byteStream(); try (InputStream inputStream = response.body().byteStream();
FileOutputStream outputStream = new FileOutputStream(file)) { FileOutputStream outputStream = new FileOutputStream(file)) {
@ -92,19 +113,43 @@ public class WallpaperDownloader {
int bytesRead; int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) { while ((bytesRead = inputStream.read(buffer)) != -1) {
if (call.isCanceled()) {
file.delete();
return;
}
outputStream.write(buffer, 0, bytesRead); outputStream.write(buffer, 0, bytesRead);
downloadedBytes += bytesRead;
if (totalBytes > 0) {
int progress = (int) (downloadedBytes * 100 / totalBytes);
mainHandler.post(() -> {
if (listener != null) {
listener.onProgress(progress);
}
});
}
} }
mainHandler.post(() -> listener.onSuccess(file)); mainHandler.post(() -> {
if (listener != null) {
listener.onSuccess(file);
}
});
} catch (IOException e) { } catch (IOException e) {
mainHandler.post(() -> listener.onFailure(e)); mainHandler.post(() -> {
if (listener != null) {
listener.onFailure(e);
}
});
} }
} }
}); });
} }
public interface OnDownloadCompleteListener { public void cancelDownload() {
void onSuccess(File file); if (currentCall != null && !currentCall.isCanceled()) {
currentCall.cancel();
void onFailure(Exception e); currentCall = null;
}
mainHandler.removeCallbacksAndMessages(null);
} }
} }

View File

@ -3,7 +3,7 @@
<item android:id="@android:id/background"> <item android:id="@android:id/background">
<shape> <shape>
<corners android:radius="5dp" /> <corners android:radius="5dp" />
<solid android:color="#D3D3D3" /> <!-- 背景颜色 --> <solid android:color="#D3D3D3" />
</shape> </shape>
</item> </item>
@ -11,7 +11,7 @@
<clip> <clip>
<shape> <shape>
<corners android:radius="5dp" /> <corners android:radius="5dp" />
<solid android:color="#FFD700" /> <!-- 次级进度颜色 --> <solid android:color="#FFD700" />
</shape> </shape>
</clip> </clip>
</item> </item>

View File

@ -68,10 +68,55 @@
android:focusable="true" android:focusable="true"
android:visibility="gone" /> android:visibility="gone" />
<ProgressBar <TextView
android:id="@+id/progress_bar" android:id="@+id/progress_tip"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginBottom="32dp"
android:padding="4dp"
android:text="Please wait, downloading"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/downloadProgressBar"
app:layout_constraintStart_toStartOf="@id/downloadProgressBar" />
<TextView
android:id="@+id/progressText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:padding="4dp"
android:text="0%"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/progress_tip"
app:layout_constraintStart_toEndOf="@+id/progress_tip"
app:layout_constraintTop_toTopOf="@id/progress_tip" />
<ProgressBar
android:id="@+id/loadingSpinner"
style="?android:attr/progressBarStyle"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="16dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/progress_tip"
app:layout_constraintStart_toEndOf="@id/progressText"
app:layout_constraintTop_toTopOf="@id/progress_tip" />
<ProgressBar
android:id="@+id/downloadProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="12dp"
android:layout_margin="48dp"
android:elevation="4dp"
android:max="100"
android:progress="0"
android:progressDrawable="@drawable/progress_bar_color"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

View File

@ -40,7 +40,7 @@
android:layout_marginBottom="80dp" android:layout_marginBottom="80dp"
android:max="100" android:max="100"
android:progress="0" android:progress="0"
android:progressDrawable="@drawable/seek_bar_color" android:progressDrawable="@drawable/progress_bar_color"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />

View File

@ -6,8 +6,7 @@
<ImageView <ImageView
android:id="@+id/item_image_view" android:id="@+id/item_image_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent" />
android:scaleType="centerCrop" />
<ImageView <ImageView
android:id="@+id/item_like" android:id="@+id/item_like"