4 Unstrukturierte Notizen
Tristan edited this page 2025-06-11 20:31:44 +02:00

Wenn eine eigene Application Class Implementierung benötigt wird

public class PiratXApplication extends eu.siacs.conversations.Conversations {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(Config.LOGTAG, "init piratx application");
    }
}

in src/piratx/AndroidManifest.xml change <application> to <application android:name="de.thedevstack.piratx.PiratXApplication" tools:replace="android:name"> and add xmlns:tools="http://schemas.android.com/tools" to <manifest>

Um nach Leaks zu schauen

In die Application Implementierung folgenden Block in die onCreate Methode

if (BuildConfig.DEBUG) {
            Log.d(Config.LOGTAG, "enable strict mode");
            // VM Policy für Resource Leaks
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                    .detectLeakedClosableObjects()      // Nicht geschlossene Closeable-Objekte
                    .detectLeakedSqlLiteObjects()       // SQLite-Leaks
                    .detectLeakedRegistrationObjects()  // Nicht abgemeldete Receiver/Listener
                    .detectActivityLeaks()              // Activity-Leaks
                    .detectFileUriExposure()           // File URI Exposition
                    .penaltyLog()                      // Log-Ausgabe
                    //.penaltyDeath()                    // Optional: App crasht bei Leak
                    .build());

            // Thread Policy für Main-Thread Violations (optional)
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectDiskReads()
                    .detectDiskWrites()
                    .detectNetwork()
                    .penaltyLog()
                    .build());
        }

Alternative DirectShare Implementierung

package de.thedevstack.piratx;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.app.Person;
import androidx.core.content.pm.ShortcutInfoCompat;
import androidx.core.content.pm.ShortcutManagerCompat;
import androidx.core.graphics.drawable.IconCompat;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Conversational;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.ui.ConversationsActivity;
import eu.siacs.conversations.ui.ShareWithActivity;

public class SharingContactsManager {
    /**
     * Define maximum number of shortcuts.
     * Don't add more than {@link ShortcutManagerCompat#getMaxShortcutCountPerActivity(Context)}.
     */
    private static final int MAX_SHORTCUTS = 4;

    /**
     * Category name defined in res/xml/shortcuts.xml that accepts data of any type
     * and will trigger {@link ShareWithActivity>}
     */
    private static final String CATEGORY_DIRECT_SHARE_TARGET = "de.thedevstack.piratx.category.DIRECT_SHARE_TARGET";

    // Category that our sharing shortcuts will be assigned to
    private static final Set<String> contactCategories = new HashSet<>();

    static {
        contactCategories.add(CATEGORY_DIRECT_SHARE_TARGET);
    }

    /**
     * Publish the list of dynamics shortcuts that will be used in Direct Share.
     * <p>
     * For each shortcut, we specify the categories that it will be associated to,
     * the intent that will trigger when opened as a static launcher shortcut,
     * and the Shortcut ID between other things.
     * <p>
     * The Shortcut ID that we specify in the {@link ShortcutInfoCompat.Builder} constructor will
     * be received in the intent as {@link Intent#EXTRA_SHORTCUT_ID}.
     * <p>
     * In this code sample, this method is completely static. We are always setting the same sharing
     * shortcuts. In a real-world example, we would replace existing shortcuts depending on
     * how the user interacts with the app as often as we want to.
     */
    public void addDirectShareTargets(@NonNull XmppConnectionService xmppConnectionService, List<Conversation> conversations) {
        if (!conversations.isEmpty()) {
            ArrayList<ShortcutInfoCompat> shortcuts = new ArrayList<>();
            Log.d("SHORTCUTS", "adding direct share targets");

            // Adding maximum number of shortcuts to the list
            int i = 0;
            for (Conversation conversation : conversations) {
                // Creates a new Sharing Shortcut and adds it to the list
                // The id passed in the constructor will become EXTRA_SHORTCUT_ID in the received Intent
                shortcuts.add(createShortcutForConversation(xmppConnectionService, conversation));
                if (i == MAX_SHORTCUTS) {
                    break;
                }
                i++;
            }

            ShortcutManagerCompat.addDynamicShortcuts(xmppConnectionService, shortcuts);
        }
    }

    public void pushDirectShareTarget(@NonNull XmppConnectionService xmppConnectionService, @NonNull Conversation conversation) {
        ShortcutManagerCompat.pushDynamicShortcut(xmppConnectionService, createShortcutForConversation(xmppConnectionService, conversation));
    }

    public void pushDirectShareTarget(@NonNull XmppConnectionService xmppConnectionService, @NonNull Conversational conversational) {
        // Wrap method copied from SearchActivity#wrap
        Conversation conversation = null;
        if (conversational instanceof Conversation) {
            conversation = (Conversation) conversational;
        } else {
            conversation = xmppConnectionService.findOrCreateConversation(conversational.getAccount(),
                    conversational.getJid(),
                    conversational.getMode() == Conversational.MODE_MULTI,
                    true,
                    true);
        }
        ShortcutManagerCompat.pushDynamicShortcut(xmppConnectionService, createShortcutForConversation(xmppConnectionService, conversation));
    }



    /**
     * Remove all dynamic shortcuts
     */
    public void removeAllDirectShareTargets(@NonNull Context context) {
        ShortcutManagerCompat.removeAllDynamicShortcuts(context);
    }

    private ShortcutInfoCompat createShortcutForConversation(@NonNull XmppConnectionService xmppConnectionService, @NonNull Conversation conversation) {
        if (conversation.getMode() == Conversational.MODE_SINGLE) {
            return xmppConnectionService.getShortcutService().getShortcutInfo(conversation.getContact(), conversation.getUuid());
        } else {
            return xmppConnectionService.getShortcutService().getShortcutInfo(conversation.getMucOptions());
        }

        // Das naechste waere mein Code gewesen...
        /*final int pixel = AvatarService.getSystemUiAvatarSize(xmppConnectionService);
        final Icon icon =
                Icon.createWithBitmap(FileBackend.drawDrawable(
                        xmppConnectionService.getAvatarService().get(conversation, pixel)));

        // Item that will be sent if the shortcut is opened as a static launcher shortcut
        Intent staticLauncherShortcutIntent = new Intent(xmppConnectionService, ConversationsActivity.class);
        staticLauncherShortcutIntent.setAction(ConversationsActivity.ACTION_VIEW_CONVERSATION);

        return new ShortcutInfoCompat.Builder(xmppConnectionService, conversation.getUuid())
                .setShortLabel(conversation.getName())
                // Icon that will be displayed in the share target
                .setIcon(IconCompat.createFromIcon(icon))
                .setIntent(staticLauncherShortcutIntent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, conversation.getUuid()))
                .setCategories(contactCategories)
                // Make this sharing shortcut cached by the system
                // Even if it is unpublished, it can still appear on the sharesheet
                .setLongLived(true)
                .setLongLabel(conversation.getName())
                // Person objects are used to give better suggestions
                .setPerson(new Person.Builder()
                        .setName(conversation.getName())
                        .build())
                .build();*/
    }

    public static SharingContactsManager getInstance() {
        return INSTANCE;
    }

    private static final SharingContactsManager INSTANCE = new SharingContactsManager();

    private SharingContactsManager() {}
}