package com.noupoisson;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import java.io.File;
public class Update extends AppCompatActivity {
private Button checkUpdateButton;
private ProgressBar progressBar;
private FirebaseFirestore db;
private FirebaseAuth mAuth; // FirebaseAuth instance
private String latestApkUrl = null;
private int latestVersionCode = -1;
private long downloadID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.update);
checkUpdateButton = findViewById(R.id.check_update_button);
progressBar = findViewById(R.id.update_progress_bar);
db = FirebaseFirestore.getInstance();
mAuth = FirebaseAuth.getInstance(); // Initialize FirebaseAuth
FirebaseFirestore.setLoggingEnabled(true);
// Register the receiver for download completion
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
checkUpdateButton.setOnClickListener(v -> {
checkUserAuthAndFetchUpdates(); // Check user authentication before fetching updates
});
}
private void checkUserAuthAndFetchUpdates() {
FirebaseUser currentUser = mAuth.getCurrentUser(); // Get the current authenticated user
if (currentUser != null) {
// User is authenticated, proceed with checking for updates
checkForUpdates();
} else {
// User is not authenticated, redirect to login or show message
Toast.makeText(this, "Please log in to check for updates.", Toast.LENGTH_SHORT).show();
// startActivity(new Intent(this, LoginActivity.class));
}
}
private void checkForUpdates() {
// Show progress bar while checking for updates
progressBar.setVisibility(View.VISIBLE);
checkUpdateButton.setEnabled(false);
// Fetch the latest version from Firestore
db.collection("Updates")
.orderBy("version_code", Query.Direction.DESCENDING)
.limit(1)
.get()
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Log.i("Update Check:", "Database searched");
for (QueryDocumentSnapshot document : task.getResult()) {
Long versionCodeLong = document.getLong("version_code");
if (versionCodeLong != null) {
latestVersionCode = versionCodeLong.intValue();
} else {
Toast.makeText(this, "Failed to get version code from Firestore.", Toast.LENGTH_SHORT).show();
latestVersionCode = -1;
return;
}
latestApkUrl = document.getString("apk_url");
// Check if the APK URL is valid
if (latestApkUrl == null || latestApkUrl.isEmpty()) {
Toast.makeText(Update.this, "Invalid APK URL.", Toast.LENGTH_SHORT).show();
latestApkUrl = null;
Log.d("Update Check:", "Invalid APK URL");
return;
}
// Compare with the current app version
int currentVersionCode = BuildConfig.VERSION_CODE;
Log.i("Update Check:", "App current version " + currentVersionCode);
if (latestVersionCode > currentVersionCode) {
promptUpdateAvailable();
Log.d("Update Check:", "Update available");
} else {
noUpdateAvailable();
Log.d("Update Check:", "No update available");
}
}
} else {
Toast.makeText(Update.this, "Failed to check for updates.", Toast.LENGTH_SHORT).show();
}
// Hide progress bar
progressBar.setVisibility(View.GONE);
checkUpdateButton.setEnabled(true);
});
}
private void promptUpdateAvailable() {
// Change button text to "Update Now"
checkUpdateButton.setText(getString(R.string.update_now));
// Set a new click listener to download and install the APK
checkUpdateButton.setOnClickListener(v -> downloadAndInstallAPK(latestApkUrl));
}
private void noUpdateAvailable() {
Toast.makeText(Update.this, "No updates available.", Toast.LENGTH_SHORT).show();
// Reset the button in case it was changed
checkUpdateButton.setText(getString(R.string.check_for_updates));
}
private void downloadAndInstallAPK(String apkUrl) {
// Verify apkUrl is not null or empty
if (apkUrl == null || apkUrl.isEmpty()) {
Toast.makeText(this, "Invalid APK URL.", Toast.LENGTH_SHORT).show();
return;
}
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkUrl))
.setTitle(getString(R.string.downloading_update))
.setDescription(getString(R.string.downloading_latest_version))
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "NouPoisson.apk") // Save in Downloads directory
.setAllowedOverMetered(true)
.setAllowedOverRoaming(true);
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
downloadID = downloadManager.enqueue(request); // Start the download
}
// Broadcast receiver to handle download completion
private final BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (downloadID == id) {
installAPK();
}
}
};
// Method to trigger APK installation
private void installAPK() {
File apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/NouPoisson.apk");
if (!apkFile.exists()) {
Toast.makeText(this, "Downloaded APK file not found.", Toast.LENGTH_SHORT).show();
return;
}
Uri apkUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", apkFile);
// Ensure the app has the permission to install APKs from unknown sources
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !getPackageManager().canRequestPackageInstalls()) {
// Redirect user to enable unknown sources installation
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
.setData(Uri.parse(String.format("package:%s", getPackageName())));
startActivity(intent);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(onDownloadComplete); // Clean up the broadcast receiver
}
}
Failed to get service from broker.
java.lang.SecurityException: Unknown calling package name 'com.google.android.gms'.
at android.os.Parcel.createExceptionOrNull(Parcel.java:3069)
at android.os.Parcel.createException(Parcel.java:3053)
at android.os.Parcel.readException(Parcel.java:3036)
at android.os.Parcel.readException(Parcel.java:2978)
at amrz.a(:com.google.android.gms@243834029@24.38.34 (190400-681941525):36)
at amqg.z(:com.google.android.gms@243834029@24.38.34 (190400-681941525):143)
at alxh.run(:com.google.android.gms@243834029@24.38.34 (190400-681941525):54)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.os.HandlerThread.run(HandlerThread.java:67)
У меня уже есть ключ API Google в моем манифесте и в моих локальных свойствах.
Мой SDK Firebase настроен правильно, поскольку я успешно выполняю различные операции Firebase и успешно сопоставляю их во всем своем приложении. Пожалуйста, может кто-нибудь помочь?
Я постоянно получаю эту ошибку, когда нажимаю кнопку «Проверить наличие обновлений». Сообщение об ошибке отображается в конце кода. [code]package com.noupoisson;
// Register the receiver for download completion registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
checkUpdateButton.setOnClickListener(v -> { checkUserAuthAndFetchUpdates(); // Check user authentication before fetching updates }); }
private void checkUserAuthAndFetchUpdates() { FirebaseUser currentUser = mAuth.getCurrentUser(); // Get the current authenticated user
if (currentUser != null) { // User is authenticated, proceed with checking for updates checkForUpdates(); } else { // User is not authenticated, redirect to login or show message Toast.makeText(this, "Please log in to check for updates.", Toast.LENGTH_SHORT).show();
private void checkForUpdates() { // Show progress bar while checking for updates progressBar.setVisibility(View.VISIBLE); checkUpdateButton.setEnabled(false);
// Fetch the latest version from Firestore db.collection("Updates") .orderBy("version_code", Query.Direction.DESCENDING) .limit(1) .get() .addOnCompleteListener(task -> { if (task.isSuccessful()) { Log.i("Update Check:", "Database searched"); for (QueryDocumentSnapshot document : task.getResult()) { Long versionCodeLong = document.getLong("version_code"); if (versionCodeLong != null) { latestVersionCode = versionCodeLong.intValue(); } else { Toast.makeText(this, "Failed to get version code from Firestore.", Toast.LENGTH_SHORT).show(); latestVersionCode = -1; return; } latestApkUrl = document.getString("apk_url");
// Check if the APK URL is valid if (latestApkUrl == null || latestApkUrl.isEmpty()) { Toast.makeText(Update.this, "Invalid APK URL.", Toast.LENGTH_SHORT).show(); latestApkUrl = null; Log.d("Update Check:", "Invalid APK URL"); return; }
// Compare with the current app version int currentVersionCode = BuildConfig.VERSION_CODE; Log.i("Update Check:", "App current version " + currentVersionCode); if (latestVersionCode > currentVersionCode) { promptUpdateAvailable(); Log.d("Update Check:", "Update available"); } else { noUpdateAvailable(); Log.d("Update Check:", "No update available"); } } } else { Toast.makeText(Update.this, "Failed to check for updates.", Toast.LENGTH_SHORT).show(); } // Hide progress bar progressBar.setVisibility(View.GONE); checkUpdateButton.setEnabled(true); }); }
private void promptUpdateAvailable() { // Change button text to "Update Now" checkUpdateButton.setText(getString(R.string.update_now));
// Set a new click listener to download and install the APK checkUpdateButton.setOnClickListener(v -> downloadAndInstallAPK(latestApkUrl)); }
private void noUpdateAvailable() { Toast.makeText(Update.this, "No updates available.", Toast.LENGTH_SHORT).show(); // Reset the button in case it was changed checkUpdateButton.setText(getString(R.string.check_for_updates)); }
private void downloadAndInstallAPK(String apkUrl) { // Verify apkUrl is not null or empty if (apkUrl == null || apkUrl.isEmpty()) { Toast.makeText(this, "Invalid APK URL.", Toast.LENGTH_SHORT).show(); return; }
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkUrl)) .setTitle(getString(R.string.downloading_update)) .setDescription(getString(R.string.downloading_latest_version)) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "NouPoisson.apk") // Save in Downloads directory .setAllowedOverMetered(true) .setAllowedOverRoaming(true);
// Broadcast receiver to handle download completion private final BroadcastReceiver onDownloadComplete = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); if (downloadID == id) { installAPK(); } } };
// Method to trigger APK installation private void installAPK() { File apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/NouPoisson.apk");
if (!apkFile.exists()) { Toast.makeText(this, "Downloaded APK file not found.", Toast.LENGTH_SHORT).show(); return; }
Uri apkUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", apkFile);
// Ensure the app has the permission to install APKs from unknown sources if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !getPackageManager().canRequestPackageInstalls()) { // Redirect user to enable unknown sources installation Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) .setData(Uri.parse(String.format("package:%s", getPackageName()))); startActivity(intent); } else { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent); } }
@Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(onDownloadComplete); // Clean up the broadcast receiver } }
Failed to get service from broker. java.lang.SecurityException: Unknown calling package name 'com.google.android.gms'. at android.os.Parcel.createExceptionOrNull(Parcel.java:3069) at android.os.Parcel.createException(Parcel.java:3053) at android.os.Parcel.readException(Parcel.java:3036) at android.os.Parcel.readException(Parcel.java:2978) at amrz.a(:com.google.android.gms@243834029@24.38.34 (190400-681941525):36) at amqg.z(:com.google.android.gms@243834029@24.38.34 (190400-681941525):143) at alxh.run(:com.google.android.gms@243834029@24.38.34 (190400-681941525):54) at android.os.Handler.handleCallback(Handler.java:958) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:230) at android.os.Looper.loop(Looper.java:319) at android.os.HandlerThread.run(HandlerThread.java:67)
[/code] У меня уже есть ключ API Google в моем манифесте и в моих локальных свойствах. Мой SDK Firebase настроен правильно, поскольку я успешно выполняю различные операции Firebase и успешно сопоставляю их во всем своем приложении. Пожалуйста, может кто-нибудь помочь?