Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
<uses-permission android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application android:label="@string/app_name"
android:name=".DynamicColorApplication"
Expand Down
9 changes: 7 additions & 2 deletions app/src/main/java/com/tortel/syslog/Result.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class Result {
private boolean success;
private Throwable exceptions;
private int message;
private String stingmessage;
private RunCommand command;
private String archiveName;

Expand Down Expand Up @@ -59,9 +60,13 @@ public void setException(Throwable exception){
public Throwable getException(){
return exceptions;
}

public void setMessage(@StringRes int message){
this.message= message;
this.message= message;
}

public void setStringMessage(String message) {
this.stingmessage = message;
}

@StringRes
Expand Down
41 changes: 41 additions & 0 deletions app/src/main/java/com/tortel/syslog/dialog/RunningDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.fragment.app.DialogFragment;
Expand Down Expand Up @@ -115,17 +117,21 @@ public void onLogResult(Result result){
File zipFile = new File(FileUtils.getZipPath(context) +
"/" + result.getArchiveName());

// Create the share intent
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("application/zip");
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
share.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(context,
"com.tortel.syslog.fileprovider", zipFile));

// Check if a handler is available to share the file
if (Utils.isHandlerAvailable(context, share)) {
startActivity(share);
} else {
// No app can handle the share intent - Save the file to storage instead
result.setMessage(R.string.exception_send);
result.setException(null);
saveLogsToStorage(zipFile);

//Show the error dialog. It will have stacktrace/bugreport disabled
ExceptionDialog dialog = new ExceptionDialog();
Expand All @@ -152,6 +158,41 @@ public void onLogResult(Result result){
}
}

/**
* Saves logs to storage when sharing fails
*/
private void saveLogsToStorage(File zipFile) {
try {
// For Android 11 and above, use the appropriate location for public external storage
File saveDirectory;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// For Android 10 and above, access the 'Downloads' folder or create 'SysLogs' folder there
saveDirectory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "SysLogs");
} else {
// For Android 9 and below, you can use external storage directories directly
saveDirectory = new File(Environment.getExternalStorageDirectory(), "SysLogs");
}

// Create the directory if it doesn't exist
if (!saveDirectory.exists()) {
saveDirectory.mkdirs();
}

// Create a new file in the save directory
File savedLogFile = new File(saveDirectory, zipFile.getName());

// Copy the zipFile to the save directory
FileUtils.copyFile(zipFile, savedLogFile);

// Notify the user with the correct path
Toast.makeText(getActivity(), "Logs saved to: " + savedLogFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getActivity(), "Failed to save logs: " + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}

/**
* Called when the background log grabbing thread has a progress update
* @param update
Expand Down
62 changes: 55 additions & 7 deletions app/src/main/java/com/tortel/syslog/utils/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package com.tortel.syslog.utils;

import android.content.Context;
import android.os.Environment;
import android.os.Build;
import android.os.Handler;
import android.os.StatFs;
import android.widget.Toast;
Expand All @@ -26,6 +28,9 @@

import com.tortel.syslog.R;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;

import eu.chainfire.libsuperuser.Shell;
Expand All @@ -48,19 +53,51 @@ public static void cleanAllLogs(@NonNull final Context context) {
@Override
public void run() {
final double startingSpace = getStorageFreeSpace(context);
String path = getStorageDir(context).getPath();
String path = getRootLogDir(context).getAbsolutePath(); // Use getRootLogDir instead of getStorageDir
path += "/*";
Shell.SH.run("rm -rf " + path);
final double endingSpace = getStorageFreeSpace(context);
Handler mainHandler = new Handler(context.getMainLooper());
String finalPath = path;
mainHandler.post(() -> {
Toast.makeText(context, context.getResources().getString(R.string.space_freed,
endingSpace - startingSpace), Toast.LENGTH_SHORT).show();
// Calculate the space freed
double spaceFreed = endingSpace - startingSpace;
// Format the message for space freed
String formattedMessage = String.format(context.getResources().getString(R.string.space_freed), spaceFreed);
// Combine the space freed message with the storage path
String message = formattedMessage + ", logs stored at: " + finalPath;
// Display the Toast message
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
});
}
}).start();
}

/**
* Copy a file from source to destination
*
* @param sourceFile the source file
* @param destFile the destination file
* @throws IOException if an error occurs during copying
*/
public static void copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.exists()) {
destFile.createNewFile(); // Create destination file if it doesn't exist
}

try (FileInputStream fis = new FileInputStream(sourceFile);
FileOutputStream fos = new FileOutputStream(destFile)) {

byte[] buffer = new byte[1024];
int length;

// Read from source and write to destination
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
}
}

/**
* Clean all uncompressed log files
*/
Expand Down Expand Up @@ -98,11 +135,22 @@ private static File getStorageDir(Context context) {
* @return the working directory. This is a directory that will always exist
*/
public static @NonNull File getRootLogDir(Context context) {
File logDir = new File(getStorageDir(context).getAbsolutePath() + LOG_DIR);
if (!logDir.isDirectory()) {
logDir.mkdir();
// For Android 11 and above, use public directory in scoped storage
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Define the path inside Downloads directory
File publicDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "Syslogs/Logs");
if (!publicDir.exists()) {
publicDir.mkdirs(); // Create the directory if it doesn't exist
}
return publicDir;
} else {
// For Android 10 and below, use traditional external storage access
File publicDir = new File(Environment.getExternalStorageDirectory(), "Syslogs/Logs");
if (!publicDir.exists()) {
publicDir.mkdirs(); // Create the directory if it doesn't exist
}
return publicDir;
}
return logDir;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values/exception-details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
<string name="exception_unknown">There was an unknown exception while running. Please submit a bug report, and include the SU implementation you use.</string>

<!-- No send intent available -->
<string name="exception_send">There was no application available to send a zip file. The logs have been saved, but please install or enable
an email application or cloud storage application to easily send the file.</string>
<string name="exception_send">There was no application available to send a zip file. The logs have been saved at Downloads Folder,
but please install or enable an email application or cloud storage application to easily send the file.</string>

<!-- Low space on primary storage -->
<string name="exception_space">Your primary storage does not have enough free space. You currently have %.1f MB free. SysLog can try to free space by cleaning old log files.</string>
Expand Down