Возникли проблемы с приложением для настройки стикера WhatsApp - PullRequest
0 голосов
/ 21 ноября 2018

Я создаю приложение для наклеек WhatsApp и получаю данные с сервера.Когда пользователь добавляет стикер в WhatsApp, он загружает файл стикера в папку.Моя проблема в том, что когда я загружаю стикер и после этого устанавливаю его на WhatsApp, он выдаст мне следующую ошибку на изображении ниже enter image description here

Поведение приложения: Когда я в первый раз загружаю стикер и добавляю его в WhatsApp, он выдает ошибку выше.Однако, когда я удаляю приложение из памяти и снова открываю приложение, оно будет работать правильно. Почему приложение ведет себя так и в чем проблема?

вот мой код для StickerContentProvider.java

package com.bluemonk.sticki;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.net.Uri.Builder;
import android.database.MatrixCursor;
import android.database.MatrixCursor.RowBuilder;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import com.facebook.common.util.UriUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class StickerContentProvider extends ContentProvider {


static final String METADATA = "metadata";
public static final String ANDROID_APP_DOWNLOAD_LINK_IN_QUERY = "android_play_store_link";
public static Uri AUTHORITY_URI = new Builder().scheme(UriUtil.LOCAL_CONTENT_SCHEME).authority(BuildConfig.CONTENT_PROVIDER_AUTHORITY).appendPath(METADATA).build();
public static final String CONTENT_FILE_NAME = "contents.json";
public static final String IOS_APP_DOWNLOAD_LINK_IN_QUERY = "ios_app_download_link";
public static final String LICENSE_AGREENMENT_WEBSITE = "sticker_pack_license_agreement_website";
private static final UriMatcher MATCHER = new UriMatcher(-1);
private static final int METADATA_CODE = 1;
private static final int METADATA_CODE_FOR_SINGLE_PACK = 2;
public static final String PRIVACY_POLICY_WEBSITE = "sticker_pack_privacy_policy_website";
public static final String PUBLISHER_EMAIL = "sticker_pack_publisher_email";
public static final String PUBLISHER_WEBSITE = "sticker_pack_publisher_website";
static final String STICKERS = "stickers";
static final String STICKERS_ASSET = "stickers_asset";
private static final int STICKERS_ASSET_CODE = 4;
private static final int STICKERS_CODE = 3;
public static final String STICKER_FILE_EMOJI_IN_QUERY = "sticker_emoji";
public static final String STICKER_FILE_NAME_IN_QUERY = "sticker_file_name";
public static final String STICKER_PACK_ICON_IN_QUERY = "sticker_pack_icon";
public static final String STICKER_PACK_IDENTIFIER_IN_QUERY = "sticker_pack_identifier";
public static final String STICKER_PACK_NAME_IN_QUERY = "sticker_pack_name";
public static final String STICKER_PACK_PUBLISHER_IN_QUERY = "sticker_pack_publisher";
private static final int STICKER_PACK_TRAY_ICON_CODE = 5;
private String authority;
private File directory;

private List<StickerPack> stickerPackList;

@Override
public boolean onCreate() {
    authority = BuildConfig.CONTENT_PROVIDER_AUTHORITY;
    String str = authority;
    Context context = getContext();
    if (!checkFileExist()) {
        try {
            JSONObject j = new JSONObject();
            j.put("android_play_store_link", "https://play.google.com/store/apps/details?id="+getContext().getPackageName());
            JSONArray sticker = new JSONArray();
            j.put("sticker_packs", sticker);
            File file = getContext().getFilesDir();
            File content = new File(file + File.separator+"contents.json");
            content.createNewFile();
            FileWriter writer = new FileWriter(content);
            BufferedWriter bw = new BufferedWriter(writer);
            bw.write(j.toString());
            bw.close();
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    context.getClass();
    if (str.startsWith(context.getPackageName())) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(getContext().getFilesDir());
        stringBuilder.append("/");
        this.directory = new File(stringBuilder.toString());
        if (!this.directory.exists()) {
            this.directory.mkdir();
        }
        MATCHER.addURI(this.authority, METADATA, 1);
        MATCHER.addURI(this.authority, "metadata/*", 2);
        MATCHER.addURI(this.authority, "stickers/*", 3);
        for (StickerPack whatsappStickerPack : getStickerPackList()) {
            StringBuilder stringBuilder2 = new StringBuilder();
            stringBuilder2.append("Stickerpack id: ");
            stringBuilder2.append(whatsappStickerPack.identifier);
            UriMatcher uriMatcher = MATCHER;
            String str2 = this.authority;
            StringBuilder stringBuilder3 = new StringBuilder();
            stringBuilder3.append("stickers_asset/");
            stringBuilder3.append(whatsappStickerPack.identifier);
            stringBuilder3.append("/");
            stringBuilder3.append(whatsappStickerPack.trayImageFile);
            uriMatcher.addURI(str2, stringBuilder3.toString(), 5);
            for (Sticker whatsappSticker : whatsappStickerPack.getStickers()) {
                UriMatcher uriMatcher2 = MATCHER;
                String str3 = this.authority;
                StringBuilder stringBuilder4 = new StringBuilder();
                stringBuilder4.append("stickers_asset/");
                stringBuilder4.append(whatsappStickerPack.identifier);
                stringBuilder4.append("/");
                stringBuilder4.append(whatsappSticker.imageFileName);
                uriMatcher2.addURI(str3, stringBuilder4.toString(), 4);
            }
        }
        return true;
    }
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append("your authority (");
    stringBuilder.append(this.authority);
    stringBuilder.append(") for the content provider should start with your package name: ");
    stringBuilder.append(getContext().getPackageName());
    throw new IllegalStateException(stringBuilder.toString());
}

@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
    StringBuilder str = new StringBuilder();
    str.append("Query called URI: ");
    str.append(uri);
    int strArr = MATCHER.match(uri);
    System.out.println("File URI :"+uri);
    if (strArr == 1) {
        return getPackForAllStickerPacks(uri);
    }
    if (strArr == 2) {
        return getCursorForSingleStickerPack(uri);
    }
    if (strArr == 3) {
        return getStickersForAStickerPack(uri);
    }
    str = new StringBuilder();
    str.append("Unknown URI: ");
    str.append(uri);

    throw new IllegalArgumentException(str.toString());
}

@Nullable
public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String str) {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append("Get image asset from uri: ");
    stringBuilder.append(uri);
    int str1 = MATCHER.match(uri);
    StringBuilder stringBuilder2 = new StringBuilder();
    stringBuilder2.append("Match code: ");
    stringBuilder2.append(String.valueOf(str));
    if (str1 != 4) {
        if (str1 != 5) {
            return null;
        }
    }
    return getImageAsset(uri);
}

@Nullable
@Override
public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode, @Nullable CancellationSignal signal) throws FileNotFoundException {
    System.out.println("Opened File :"+uri);
    return super.openFile(uri, mode, signal);
}

@Nullable
@Override
public String getType(@NonNull Uri uri) {
    switch (MATCHER.match(uri)) {
        case 1:
            return "vnd.android.cursor.dir/vnd.stickermaker.android.stickermaker.stickercontentprovider.metadata";
        case 2:
            return "vnd.android.cursor.item/vnd.stickermaker.android.stickermaker.stickercontentprovider.metadata";
        case 3:
            return "vnd.android.cursor.dir/vnd.stickermaker.android.stickermaker.stickercontentprovider.stickers";
        case 4:
            return "image/webp";
        case 5:
            return "image/png";
        default:
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("Unknown URI: ");
            stringBuilder.append(uri);
            throw new IllegalArgumentException(stringBuilder.toString());
    }
}

private synchronized void readContentFile() {
    try {
        this.stickerPackList = ContentFileParser.parseStickerPacks(new FileInputStream(new File(this.directory, CONTENT_FILE_NAME)));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return;
}

public List<StickerPack> getStickerPackList() {
    readContentFile();
    return this.stickerPackList;
}

private Cursor getPackForAllStickerPacks(@NonNull Uri uri) {
    return getStickerPackInfo(uri, getStickerPackList());
}

private Cursor getCursorForSingleStickerPack(@NonNull Uri uri) {
    String lastPathSegment = uri.getLastPathSegment();
    for (StickerPack whatsappStickerPack : getStickerPackList()) {
        if (lastPathSegment.equals(whatsappStickerPack.identifier)) {
            return getStickerPackInfo(uri, Collections.singletonList(whatsappStickerPack));
        }
    }
    return getStickerPackInfo(uri, new ArrayList());
}

@NonNull
private Cursor getStickerPackInfo(@NonNull Uri uri, @NonNull List<StickerPack> list) {
    MatrixCursor matrixCursor = new MatrixCursor(new String[]{
            STICKER_PACK_IDENTIFIER_IN_QUERY,
            STICKER_PACK_NAME_IN_QUERY,
            STICKER_PACK_PUBLISHER_IN_QUERY,
            STICKER_PACK_ICON_IN_QUERY,
            ANDROID_APP_DOWNLOAD_LINK_IN_QUERY,
            IOS_APP_DOWNLOAD_LINK_IN_QUERY,
            PUBLISHER_EMAIL, PUBLISHER_WEBSITE,
            PRIVACY_POLICY_WEBSITE,
            LICENSE_AGREENMENT_WEBSITE});
    for (StickerPack whatsappStickerPack : list) {
        RowBuilder newRow = matrixCursor.newRow();
        newRow.add(whatsappStickerPack.identifier);
        newRow.add(whatsappStickerPack.name);
        newRow.add(whatsappStickerPack.publisher);
        newRow.add(whatsappStickerPack.trayImageFile);
        newRow.add(whatsappStickerPack.androidPlayStoreLink);
        newRow.add(whatsappStickerPack.iosAppStoreLink);
        newRow.add(whatsappStickerPack.publisherEmail);
        newRow.add(whatsappStickerPack.publisherWebsite);
        newRow.add(whatsappStickerPack.privacyPolicyWebsite);
        newRow.add(whatsappStickerPack.licenseAgreementWebsite);
    }
    matrixCursor.setNotificationUri(Objects.requireNonNull(getContext()).getContentResolver(), uri);
    return matrixCursor;
}

@NonNull
private Cursor getStickersForAStickerPack(@NonNull Uri uri) {
    String lastPathSegment = uri.getLastPathSegment();
    MatrixCursor matrixCursor = new MatrixCursor(new String[]{STICKER_FILE_NAME_IN_QUERY, STICKER_FILE_EMOJI_IN_QUERY});
    for (StickerPack whatsappStickerPack : getStickerPackList()) {
        if (lastPathSegment.equals(whatsappStickerPack.identifier)) {
            for (Sticker whatsappSticker : whatsappStickerPack.getStickers()) {
                matrixCursor.addRow(new Object[]{whatsappSticker.imageFileName, TextUtils.join(",", whatsappSticker.emojis)});
            }
        }
    }
    matrixCursor.setNotificationUri(Objects.requireNonNull(getContext()).getContentResolver(), uri);
    return matrixCursor;
}

private ParcelFileDescriptor getImageAsset(Uri uri) throws IllegalArgumentException {
    System.out.println("Image Assest URI :"+uri);
    List pathSegments = uri.getPathSegments();
    StringBuilder stringBuilder;
    if (pathSegments.size() == 3) {
        String str = (String) pathSegments.get(pathSegments.size() - 1);
        StringBuilder stringBuilder2 = new StringBuilder();
        stringBuilder2.append("File name: ");
        stringBuilder2.append(str);
        String str2 = (String) pathSegments.get(pathSegments.size() - 2);
        stringBuilder2 = new StringBuilder();
        stringBuilder2.append("Identifier: ");
        stringBuilder2.append(str2);
        if (TextUtils.isEmpty(str2)) {
            stringBuilder = new StringBuilder();
            stringBuilder.append("identifier is empty, uri: ");
            stringBuilder.append(uri);
            throw new IllegalArgumentException(stringBuilder.toString());
        } else if (TextUtils.isEmpty(str)) {
            stringBuilder = new StringBuilder();
            stringBuilder.append("file name is empty, uri: ");
            stringBuilder.append(uri);
            throw new IllegalArgumentException(stringBuilder.toString());
        } else {
            for (StickerPack whatsappStickerPack : getStickerPackList()) {
                if (str2.equals(whatsappStickerPack.identifier)) {
                    if (str.equals(whatsappStickerPack.trayImageFile)) {
                        return fetchFile(uri, str, str2);
                    }
                    for (Sticker whatsappSticker : whatsappStickerPack.getStickers()) {
                        if (str.equals(whatsappSticker.imageFileName)) {
                            return fetchFile(uri, str, str2);
                        }
                    }
                    continue;
                }
            }
            return null;
        }
    }
    stringBuilder = new StringBuilder();
    stringBuilder.append("path segments should be 3, uri is: ");
    stringBuilder.append(uri);

    throw new IllegalArgumentException(stringBuilder.toString());
}

private ParcelFileDescriptor fetchFile(@NonNull Uri uri, @NonNull String str, @NonNull String str2) {
    try {
        File file = this.directory;
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(str2);
        stringBuilder.append("/");
        stringBuilder.append(str);
        return ParcelFileDescriptor.open(new File(file, stringBuilder.toString()), 268435456);
    } catch (FileNotFoundException e) {
        str2.getClass();
        str2 = getContext().getPackageName();
        StringBuilder stringBuilder2 = new StringBuilder();
        stringBuilder2.append("IOException when getting asset file, uri:");
        stringBuilder2.append(uri);
        return null;
    }
}

@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
    throw new UnsupportedOperationException("Not supported");
}

@Override
public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
    throw new UnsupportedOperationException("Not supported");
}

@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
    /*StringBuilder str = new StringBuilder();
    str.append("Sticker pack count: ");
    str.append(getStickerPackList().size());
    for (StickerPack whatsappStickerPack : getStickerPackList()) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Stickerpack iddd: ");
        stringBuilder.append(whatsappStickerPack.identifier);
        UriMatcher strArr = MATCHER;
        String str2 = this.authority;
        StringBuilder stringBuilder2 = new StringBuilder();
        stringBuilder2.append("stickers_asset/");
        stringBuilder2.append(whatsappStickerPack.identifier);
        stringBuilder2.append("/");
        stringBuilder2.append(whatsappStickerPack.trayImageFile);
        strArr.addURI(str2, stringBuilder2.toString(), 5);
        for (Sticker whatsappSticker : whatsappStickerPack.getStickers()) {
            UriMatcher uriMatcher = MATCHER;
            String str3 = this.authority;
            StringBuilder stringBuilder3 = new StringBuilder();
            stringBuilder3.append("stickers_asset/");
            stringBuilder3.append(whatsappStickerPack.identifier);
            stringBuilder3.append("/");
            stringBuilder3.append(whatsappSticker.imageFileName);
            uriMatcher.addURI(str3, stringBuilder3.toString(), 4);
        }
    }
    getContext().getContentResolver().notifyChange(uri, null);*/
    return 0;
}

public boolean checkFileExist () {
    boolean exist = false;
    File file = getContext().getFilesDir();
    File content = new File(file, "contents.json");
    if (content.exists()) {
        exist = true;
    } else {
        exist = false;
    }
    return exist;
}
 }

Вот код для добавления стикера вприложение WhatsApp

  Intent intent = new Intent();
            //noinspection SpellCheckingInspection
            intent.setAction("com.whatsapp.intent.action.ENABLE_STICKER_PACK");
            intent.putExtra(StickerPackDetailsActivity.EXTRA_STICKER_PACK_ID, downloadpack.name);
            intent.putExtra(StickerPackDetailsActivity.EXTRA_STICKER_PACK_AUTHORITY, BuildConfig.CONTENT_PROVIDER_AUTHORITY);
            intent.putExtra(StickerPackDetailsActivity.EXTRA_STICKER_PACK_NAME, downloadpack.name);
            try {
                startActivityForResult(intent, StickerPackDetailsActivity.ADD_PACK);
            } catch (ActivityNotFoundException e) {
                Toast.makeText(StickerPackListActivity.this, R.string.error_adding_sticker_pack, Toast.LENGTH_LONG).show();
            }

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018
*You use in glide*
    apply plugin: 'com.android.application'

    android {
        //the compression of webp file during build causes problem with FileDescriptor in ContentProvider.
        aaptOptions {
            noCompress "webp"
        }
        compileSdkVersion 28
        defaultConfig {
            applicationId "stickers.whatsapp.com"
            minSdkVersion 16
            targetSdkVersion 28
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            def contentProviderAuthority = applicationId + ".stickercontentprovider"
            // Creates a placeholder property to use in the manifest.
            manifestPlaceholders = [contentProviderAuthority: contentProviderAuthority]
            // Adds a new field for the authority to the BuildConfig class.
            buildConfigField("String",
                    "CONTENT_PROVIDER_AUTHORITY",
                    "\"${contentProviderAuthority}\"")
        }
        buildTypes {
            debug {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }

    task checkDebug {
        doLast {
            println("checkDebug")
            /* if (android.defaultConfig.applicationId.startsWith("com.whatsapp")) {
                 throw new GradleException("applicationId in defaultConfig cannot start with com.whatsapp, please change your applicationId in app/build.gradle");
             }*/
            checkApplicationIdInDebug()
        }
    }

    private void checkApplicationIdInDebug() {
        Properties properties = new Properties()
        properties.load(project.rootProject.file('local.properties').newDataInputStream())
        def ignoreApplicationIdCheck = properties.getProperty('ignoreApplicationIdCheck')
        /*  if (ignoreApplicationIdCheck == null) {
              if (android.defaultConfig.applicationId.equals("stickers.whatsapp.com")) {
                  throw new GradleException("Your applicationId is currently stickers.whatsapp.com, please change your applicationId to a different string in app/build.gradle in line 16");
              }
          } else {
              println("application id check ignored")
          }*/
    }


    task checkRelease {
        doLast {
            println("checkRelease")
            /*if (android.defaultConfig.applicationId.startsWith("com.example")) {
                throw new GradleException("applicationId in defaultConfig cannot start with com.example, please change your applicationId in app/build.gradle");
            }*/
        }
    }

    tasks.whenTaskAdded { task ->
        println(task.name)
        if (task.name.contains("assembleDebug")) {
            task.dependsOn checkDebug
        }
        if (task.name.contains("assembleRelease")) {
            task.dependsOn checkRelease
        }
    }


    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        implementation 'com.android.support:appcompat-v7:28.0.0'
        implementation 'com.android.support:design:28.0.0'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
        implementation 'com.android.support:recyclerview-v7:28.0.0'
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        implementation 'com.facebook.fresco:fresco:1.11.0'
        implementation 'com.facebook.fresco:webpsupport:1.11.0'
        implementation 'com.facebook.fresco:animated-webp:1.11.0'
        implementation 'de.hdodenhof:circleimageview:2.2.0'
        implementation 'com.intuit.sdp:sdp-android:1.0.6'
        implementation 'com.android.support:cardview-v7:28.0.0'
        implementation 'com.squareup.picasso:picasso:2.5.2'

        implementation 'com.skyfishjy.ripplebackground:library:1.0.1'

        implementation 'com.google.android.gms:play-services-ads:17.1.1'
        implementation 'com.android.support:multidex:1.0.3'
    }
0 голосов
/ 26 ноября 2018

Сначала вам нужно увидеть указанный здесь код

В этом коде используйте следующие шаги, чтобы решить вашу проблему.После загрузки изображений с сервера используйте приведенный ниже код в файле StickerPackDetailsActivity.java

 Uri uri = data.getData();
                getContentResolver().takePersistableUriPermission(Objects.requireNonNull(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION);
                stickerPack.addSticker(uri, this);
...