Further setps to move to sdk >= 33 (storage permission + foreground service with toast message to activate notifications if denied)

This commit is contained in:
Arne 2023-10-19 13:49:46 +02:00
parent 0d6bd40175
commit e72bb99a62
12 changed files with 74 additions and 24 deletions

View file

@ -133,8 +133,7 @@ dependencies {
implementation "androidx.core:core-ktx:1.12.0"
implementation 'com.github.bumptech.glide:glide:4.16.0'
implementation "androidx.emoji2:emoji2-emojipicker:1.4.0"
//implementation "androidx.compose.material3:material3:1.1.2"
implementation "androidx.compose.material3:material3-android:1.2.0-alpha09"
implementation "androidx.compose.material3:material3-android:1.2.0-alpha10"
}
ext {
@ -149,13 +148,13 @@ def tags = grgit.tag.list().findAll { it.dateTime != null }.sort { it.dateTime }
android {
namespace 'eu.siacs.conversations'
//noinspection GradleCompatible
compileSdkVersion 34
compileSdk 34
defaultConfig {
minSdkVersion 21
targetSdkVersion 34
versionNameSuffix " Experimental_(2023-10-18)" // " beta_(XXXX-XX-XX)" // activate for beta versions
versionNameSuffix " Experimental_(2023-10-19)" // " beta_(XXXX-XX-XX)" // activate for beta versions
versionCode 138
versionName "1.8"
//resConfigs "en"

View file

@ -82,7 +82,7 @@ public class PermissionsActivity extends AppCompatActivity
public static String[] permissions() {
String[] p;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (Compatibility.runsThirtyThree()) {
p = storage_permissions_33;
} else {
p = storage_permissions;

View file

@ -24,6 +24,7 @@ import java.util.regex.Pattern;
import javax.net.ssl.SSLHandshakeException;
import eu.siacs.conversations.services.AttachFileToConversationRunnable;
import eu.siacs.conversations.utils.Compatibility;
import eu.siacs.conversations.utils.Consumer;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
@ -358,7 +359,7 @@ public class HttpDownloadConnection implements Transferable {
mXmppConnectionService.databaseBackend.updateMessage(message, true);
file.setExpectedSize(size);
message.resetFileParams();
if ((mHttpConnectionManager.hasStoragePermission() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
if ((mHttpConnectionManager.hasStoragePermission() || Compatibility.runsThirtyThree())
&& size <= mHttpConnectionManager.getAutoAcceptFileSize()
&& mXmppConnectionService.isDataSaverDisabled()) {
HttpDownloadConnection.this.acceptedAutomatically = true;

View file

@ -27,6 +27,9 @@ import eu.siacs.conversations.utils.Consumer;
import static eu.siacs.conversations.utils.Compatibility.s;
import android.Manifest;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.RequiresApi;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
@ -1060,8 +1063,8 @@ public class XmppConnectionService extends Service {
deleteWebpreviewCache();
}
// move files from /monocles chat/ --> /Android/data/ for Android >= 30
if (Compatibility.runsThirty() && (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) {
if ((Compatibility.runsThirty() && (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) || Compatibility.runsThirtyThree()) {
StorageHelper.migrateStorage(this);
}
return START_STICKY;
@ -1649,7 +1652,7 @@ public class XmppConnectionService extends Service {
}
FileBackend.switchStorage(usingInnerStorage());
FILE_OBSERVER_EXECUTOR.execute(fileBackend::deleteHistoricAvatarPath);
if (Compatibility.hasStoragePermission(this) || Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (Compatibility.hasStoragePermission(this) || Compatibility.runsThirtyThree()) {
Log.d(Config.LOGTAG, "starting file observer");
FILE_OBSERVER_EXECUTOR.execute(this.fileObserver::startWatching);
FILE_OBSERVER_EXECUTOR.execute(this::checkForDeletedFiles);
@ -1825,7 +1828,7 @@ public class XmppConnectionService extends Service {
toggleForegroundService(false);
}
private void toggleForegroundService(boolean force) {
public void toggleForegroundService(boolean force) {
final boolean status;
final OngoingCall ongoing = ongoingCall.get();
final boolean showOngoing = ongoing != null && !diallerIntegrationActive.get();
@ -1940,7 +1943,7 @@ public class XmppConnectionService extends Service {
} else {
pendingIntent =
PendingIntent.getBroadcast(
this, requestCode, intent, PendingIntent.FLAG_MUTABLE); //TODO: Check whether mutable or immutable flag
this, requestCode, intent, PendingIntent.FLAG_MUTABLE); // TODO: Check whether mutable or immutable flag
}
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, pendingIntent);
} catch (RuntimeException e) {

View file

@ -531,7 +531,7 @@ public class ConversationFragment extends XmppFragment
return false;
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU || hasPermissions(REQUEST_ADD_EDITOR_CONTENT, Manifest.permission.WRITE_EXTERNAL_STORAGE) && hasPermissions(REQUEST_ADD_EDITOR_CONTENT, Manifest.permission.READ_EXTERNAL_STORAGE)) {
if (Compatibility.runsThirtyThree() || (hasPermissions(REQUEST_ADD_EDITOR_CONTENT, Manifest.permission.WRITE_EXTERNAL_STORAGE) && hasPermissions(REQUEST_ADD_EDITOR_CONTENT, Manifest.permission.READ_EXTERNAL_STORAGE))) {
attachEditorContentToConversation(inputContentInfo.getContentUri());
} else {
mPendingEditorContent = inputContentInfo.getContentUri();
@ -1355,7 +1355,7 @@ public class ConversationFragment extends XmppFragment
private void commitAttachments() {
final List<Attachment> attachments = mediaPreviewAdapter.getAttachments();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU && anyNeedsExternalStoragePermission(attachments) && !hasPermissions(REQUEST_COMMIT_ATTACHMENTS, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
if (!Compatibility.runsThirtyThree() && anyNeedsExternalStoragePermission(attachments) && !hasPermissions(REQUEST_COMMIT_ATTACHMENTS, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
return;
}
if (trustKeysIfNeeded(conversation, REQUEST_TRUST_KEYS_ATTACHMENTS)) {
@ -2715,8 +2715,9 @@ public class ConversationFragment extends XmppFragment
}
public void startDownloadable(Message message) {
if (!hasPermissions(REQUEST_START_DOWNLOAD, Manifest.permission.WRITE_EXTERNAL_STORAGE) && !hasPermissions(REQUEST_START_DOWNLOAD, Manifest.permission.READ_EXTERNAL_STORAGE)) {
if (!hasPermissions(REQUEST_START_DOWNLOAD, Manifest.permission.WRITE_EXTERNAL_STORAGE) && !hasPermissions(REQUEST_START_DOWNLOAD, Manifest.permission.READ_EXTERNAL_STORAGE) && !Compatibility.runsThirtyThree()) {
this.mPendingDownloadableMessage = message;
ToastCompat.makeText(getActivity(), R.string.no_storage_permission, ToastCompat.LENGTH_SHORT).show();
return;
}
Transferable transferable = message.getTransferable();
@ -2822,7 +2823,7 @@ public class ConversationFragment extends XmppFragment
}
private boolean hasPermissions(int requestCode, List<String> permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Compatibility.runsThirtyThree()) {
final List<String> missingPermissions = new ArrayList<>();
for (String permission : permissions) {
if (Config.ONLY_INTERNAL_STORAGE
@ -2845,6 +2846,7 @@ public class ConversationFragment extends XmppFragment
return true;
}
}
private boolean hasPermissions(int requestCode, String... permissions) {
return hasPermissions(requestCode, ImmutableList.copyOf(permissions));
}

View file

@ -62,6 +62,9 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.core.content.ContextCompat;
import de.monocles.chat.DownloadDefaultStickers;
@ -79,6 +82,7 @@ import androidx.databinding.DataBindingUtil;
import org.openintents.openpgp.util.OpenPgpApi;
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
import eu.siacs.conversations.utils.Compatibility;
import io.michaelrocks.libphonenumber.android.NumberParseException;
import java.io.File;
@ -697,6 +701,25 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
setIntent(createLauncherIntent(this));
}
UpdateHelper.showPopup(this);
// SDK >= 33 Foreground service
if (Compatibility.runsThirtyThree()) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NOTIFICATION_POLICY) == PackageManager.PERMISSION_GRANTED)
return;
ActivityResultLauncher<String> launcher = registerForActivityResult(
new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
Log.d("Notfications enabled", getString(R.string.notifications_enabled));
} else {
Log.d("Notfications disabled", getString(R.string.notifications_disabled));
ToastCompat.makeText(this, R.string.notifications_disabled, ToastCompat.LENGTH_SHORT).show();
}
}
);
launcher.launch(Manifest.permission.POST_NOTIFICATIONS);
}
}
@Override

View file

@ -134,7 +134,7 @@ public class ImportBackupActivity extends XmppActivity implements ServiceConnect
backupFileAdapter.setFiles(files);
} else {
this.binding.hint.setVisibility(View.VISIBLE);
if (Compatibility.runsThirty() && !Compatibility.runsThirtyThree()) {
if (Compatibility.runsThirty()) {
this.binding.hint.setText(getString(R.string.import_backup_description));
} else {
this.binding.hint.setText(getString(R.string.no_backup_available));

View file

@ -162,15 +162,11 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
Intent openIntent = new Intent(Intent.ACTION_VIEW);
openIntent.setDataAndType(uri, mime);
openIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU){
PackageManager manager = this.getPackageManager();
List<ResolveInfo> info = manager.queryIntentActivities(openIntent, 0);
if (info.size() == 0) {
openIntent.setDataAndType(uri, "*/*");
}
} else {
openIntent.setDataAndType(uri, "*/*");
}
if (player != null && isVideo) {
openIntent.putExtra("position", player.getCurrentPosition());
}

View file

@ -8,6 +8,7 @@ import android.Manifest;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -18,9 +19,12 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import java.util.Arrays;
@ -97,6 +101,23 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
recreate();
}
new InstallReferrerUtils(this);
// SDK >= 33 Foreground service
if (Compatibility.runsThirtyThree()) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NOTIFICATION_POLICY) == PackageManager.PERMISSION_GRANTED)
return;
ActivityResultLauncher<String> launcher = registerForActivityResult(
new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
ToastCompat.makeText(this, R.string.notifications_enabled, ToastCompat.LENGTH_SHORT).show();
} else {
ToastCompat.makeText(this, R.string.notifications_disabled, ToastCompat.LENGTH_SHORT).show();
}
}
);
launcher.launch(Manifest.permission.POST_NOTIFICATIONS);
}
}
@Override
@ -115,7 +136,7 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
@Override
protected void onCreate(final Bundle savedInstanceState) {
if (getResources().getBoolean(R.bool.portrait_only)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
super.onCreate(savedInstanceState);
getPreferences().edit().putStringSet("pstn_gateways", new HashSet<>()).apply();
@ -128,7 +149,7 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
}
IntroHelper.showIntro(this, false);
UpdateHelper.showPopup(this);
if (hasStoragePermission(REQUEST_IMPORT_BACKUP) || Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (hasStoragePermission(REQUEST_IMPORT_BACKUP) || Compatibility.runsThirtyThree()) {
binding.importDatabase.setVisibility(View.VISIBLE);
binding.importText.setVisibility(View.VISIBLE);
}

View file

@ -5,6 +5,9 @@ import static eu.siacs.conversations.ui.SettingsActivity.USE_INTERNAL_UPDATER;
import android.graphics.drawable.AnimatedImageDrawable;
import android.telephony.TelephonyManager;
import eu.siacs.conversations.utils.Compatibility;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.RequiresApi;
import android.Manifest;
import android.annotation.SuppressLint;
@ -284,6 +287,7 @@ public abstract class XmppActivity extends ActionBarActivity {
this.mUsingEnterKey = usingEnterKey();
this.mUseTor = useTor();
this.mUseI2P = useI2P();
}
public void connectToBackend() {
@ -962,7 +966,7 @@ public abstract class XmppActivity extends ActionBarActivity {
}
protected boolean hasStoragePermission(int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Compatibility.runsThirtyThree()) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, requestCode);
return false;

View file

@ -1506,7 +1506,6 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} else if (type == RTP_SESSION) {
final boolean isDarkTheme = activity.isDarkTheme();
final boolean received = message.getStatus() <= Message.STATUS_RECEIVED;
final String formattedTime = UIHelper.readableTimeDifferenceFull(activity, message.getMergedTimeSent());
final RtpSessionStatus rtpSessionStatus = RtpSessionStatus.of(message.getBody());
final long duration = rtpSessionStatus.duration;
if (received) {

View file

@ -1338,4 +1338,6 @@
<string name="enter_user_name">Enter a name</string>
<string name="account_color">Account Color</string>
<string name="account_color_summary">Used on conversation and contact lists, and notifications</string>
<string name="notifications_enabled">Notifications enabled</string>
<string name="notifications_disabled">Notifications disabled. Please activate them in your android settings.</string>
</resources>