All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.facebook.NativeAppCallAttachmentStore Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2010-present Facebook.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.facebook;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import com.facebook.internal.Utility;
import com.facebook.internal.Validate;

import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 

This class works in conjunction with {@link NativeAppCallContentProvider} to allow apps to attach binary * attachments (e.g., images) to native dialogs launched via the {@link com.facebook.widget.FacebookDialog} * class. It stores attachments in temporary files and allows the Facebook application to retrieve them via * the content provider.

* *

Callers are generally not expected to need to use this class directly; * see {@link com.facebook.widget.FacebookDialog.OpenGraphActionDialogBuilder#setImageAttachmentsForObject(String, * java.util.List) OpenGraphActionDialogBuilder.setImageAttachmentsForObject} for an example of a function * that will accept attachments, attach them to the native dialog call, and add them to the content provider * automatically.

**/ public final class NativeAppCallAttachmentStore implements NativeAppCallContentProvider.AttachmentDataSource { private static final String TAG = NativeAppCallAttachmentStore.class.getName(); static final String ATTACHMENTS_DIR_NAME = "com.facebook.NativeAppCallAttachmentStore.files"; private static File attachmentsDirectory; /** * Adds a number of bitmap attachments associated with a native app call. The attachments will be * served via {@link NativeAppCallContentProvider#openFile(android.net.Uri, String) openFile}. * * @param context the Context the call is being made from * @param callId the unique ID of the call * @param imageAttachments a Map of attachment names to Bitmaps; the attachment names will be part of * the URI processed by openFile * @throws java.io.IOException */ public void addAttachmentsForCall(Context context, UUID callId, Map imageAttachments) { Validate.notNull(context, "context"); Validate.notNull(callId, "callId"); Validate.containsNoNulls(imageAttachments.values(), "imageAttachments"); Validate.containsNoNullOrEmpty(imageAttachments.keySet(), "imageAttachments"); addAttachments(context, callId, imageAttachments, new ProcessAttachment() { @Override public void processAttachment(Bitmap attachment, File outputFile) throws IOException { FileOutputStream outputStream = new FileOutputStream(outputFile); try { attachment.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); } finally { Utility.closeQuietly(outputStream); } } }); } /** * Adds a number of bitmap attachment files associated with a native app call. The attachments will be * served via {@link NativeAppCallContentProvider#openFile(android.net.Uri, String) openFile}. * * @param context the Context the call is being made from * @param callId the unique ID of the call * @param imageAttachments a Map of attachment names to Files containing the bitmaps; the attachment names will be * part of the URI processed by openFile * @throws java.io.IOException */ public void addAttachmentFilesForCall(Context context, UUID callId, Map imageAttachmentFiles) { Validate.notNull(context, "context"); Validate.notNull(callId, "callId"); Validate.containsNoNulls(imageAttachmentFiles.values(), "imageAttachmentFiles"); Validate.containsNoNullOrEmpty(imageAttachmentFiles.keySet(), "imageAttachmentFiles"); addAttachments(context, callId, imageAttachmentFiles, new ProcessAttachment() { @Override public void processAttachment(File attachment, File outputFile) throws IOException { FileOutputStream outputStream = new FileOutputStream(outputFile); FileInputStream inputStream = null; try { inputStream = new FileInputStream(attachment); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, len); } } finally { Utility.closeQuietly(outputStream); Utility.closeQuietly(inputStream); } } }); } private void addAttachments(Context context, UUID callId, Map attachments, ProcessAttachment processor) { if (attachments.size() == 0) { return; } // If this is the first time we've been instantiated, clean up any existing attachments. if (attachmentsDirectory == null) { cleanupAllAttachments(context); } ensureAttachmentsDirectoryExists(context); List filesToCleanup = new ArrayList(); try { for (Map.Entry entry : attachments.entrySet()) { String attachmentName = entry.getKey(); T attachment = entry.getValue(); File file = getAttachmentFile(callId, attachmentName, true); filesToCleanup.add(file); processor.processAttachment(attachment, file); } } catch (IOException exception) { Log.e(TAG, "Got unexpected exception:" + exception); for (File file : filesToCleanup) { try { file.delete(); } catch (Exception e) { // Always try to delete other files. } } throw new FacebookException(exception); } } interface ProcessAttachment { void processAttachment(T attachment, File outputFile) throws IOException; } /** * Removes any temporary files associated with a particular native app call. * * @param context the Context the call is being made from * @param callId the unique ID of the call */ public void cleanupAttachmentsForCall(Context context, UUID callId) { File dir = getAttachmentsDirectoryForCall(callId, false); Utility.deleteDirectory(dir); } @Override public File openAttachment(UUID callId, String attachmentName) throws FileNotFoundException { if (Utility.isNullOrEmpty(attachmentName) || callId == null) { throw new FileNotFoundException(); } try { return getAttachmentFile(callId, attachmentName, false); } catch (IOException e) { // We don't try to create the file, so we shouldn't get any IOExceptions. But if we do, just // act like the file wasn't found. throw new FileNotFoundException(); } } synchronized static File getAttachmentsDirectory(Context context) { if (attachmentsDirectory == null) { attachmentsDirectory = new File(context.getCacheDir(), ATTACHMENTS_DIR_NAME); } return attachmentsDirectory; } File ensureAttachmentsDirectoryExists(Context context) { File dir = getAttachmentsDirectory(context); dir.mkdirs(); return dir; } File getAttachmentsDirectoryForCall(UUID callId, boolean create) { if (attachmentsDirectory == null) { return null; } File dir = new File(attachmentsDirectory, callId.toString()); if (create && !dir.exists()) { dir.mkdirs(); } return dir; } File getAttachmentFile(UUID callId, String attachmentName, boolean createDirs) throws IOException { File dir = getAttachmentsDirectoryForCall(callId, createDirs); if (dir == null) { return null; } try { return new File(dir, URLEncoder.encode(attachmentName, "UTF-8")); } catch (UnsupportedEncodingException e) { return null; } } void cleanupAllAttachments(Context context) { // Attachments directory may or may not exist; we won't create it if not, since we are just going to delete it. File dir = getAttachmentsDirectory(context); Utility.deleteDirectory(dir); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy