我正在为WhatsApp Sticker创建一个应用程序,并且正在从服务器中获取数据。当用户将标签添加到WhatsApp时,它将标签文件下载到文件夹中。我的问题是,当我下载贴纸并将其设置在WhatsApp上后,它将在下面的图片中给我以下错误
应用程序的行为:第一次下载标签并将其添加到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();
}
答案 0 :(得分:0)
首先,您需要查看给出的代码here
在此代码中,请使用以下步骤来解决您的问题。 从服务器下载图像后,使用StickerPackDetailsActivity.java文件中的以下代码
Uri uri = data.getData();
getContentResolver().takePersistableUriPermission(Objects.requireNonNull(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION);
stickerPack.addSticker(uri, this);
答案 1 :(得分:0)
*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'
}