From 831eed8799db2251df299753d948c508e17c7e8c Mon Sep 17 00:00:00 2001 From: tom79 Date: Sat, 2 Sep 2017 10:13:40 +0200 Subject: [PATCH] Simplify the process to retrieve remote picture and content (Mastalab logic). --- .../mastodon/activities/TootActivity.java | 120 ++++++--------- .../asynctasks/RetrieveMetaDataAsyncTask.java | 69 +++++++++ .../gouv/etalab/mastodon/helper/Helper.java | 2 +- .../etalab/mastodon/helper/ManageHeader.java | 9 ++ .../etalab/mastodon/helper/ParserUtils.java | 141 ------------------ .../OnRetrieveMetaDataInterface.java | 24 +++ .../activities/MainActivity.java | 22 +-- 7 files changed, 165 insertions(+), 222 deletions(-) create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveMetaDataAsyncTask.java create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/helper/ManageHeader.java delete mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/helper/ParserUtils.java create mode 100644 app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveMetaDataInterface.java diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java index 9d0561199..52f31cadd 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java @@ -17,11 +17,14 @@ package fr.gouv.etalab.mastodon.activities; import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.IntentFilter; import android.content.pm.PackageManager; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.net.Uri; +import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AlertDialog; import android.content.ActivityNotFoundException; import android.content.Context; @@ -40,7 +43,6 @@ import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.text.Editable; import android.text.Html; -import android.text.TextUtils; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.Menu; @@ -50,6 +52,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.inputmethod.InputMethodManager; +import android.webkit.URLUtil; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; @@ -108,7 +111,6 @@ import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader; import fr.gouv.etalab.mastodon.drawers.AccountsSearchAdapter; import fr.gouv.etalab.mastodon.drawers.DraftsListAdapter; import fr.gouv.etalab.mastodon.helper.Helper; -import fr.gouv.etalab.mastodon.helper.ParserUtils; import fr.gouv.etalab.mastodon.interfaces.OnPostStatusActionInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface; @@ -118,7 +120,6 @@ import fr.gouv.etalab.mastodon.sqlite.Sqlite; import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO; import mastodon.etalab.gouv.fr.mastodon.R; -import static fr.gouv.etalab.mastodon.helper.Helper.EXTERNAL_STORAGE_REQUEST_CODE; import static fr.gouv.etalab.mastodon.helper.Helper.HOME_TIMELINE_INTENT; import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION; import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor; @@ -128,7 +129,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor; * Toot activity class */ -public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, ParserUtils.ParserListener { +public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface { private String visibility; @@ -146,7 +147,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc private EditText toot_cw_content; private LinearLayout toot_reply_content_container; private Status tootReply = null; - private String sharedContent, sharedSubject, sharedStream; + private String sharedContent, sharedSubject; private CheckBox toot_sensitive; public long currentToId; private long restored; @@ -159,6 +160,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc private int currentCursorPosition, searchLength; private TextView toot_space_left; private final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754; + private BroadcastReceiver receive_picture; @Override protected void onCreate(Bundle savedInstanceState) { @@ -251,7 +253,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc tootReply = b.getParcelable("tootReply"); sharedContent = b.getString("sharedContent", null); sharedSubject = b.getString("sharedSubject", null); - sharedStream = b.getString("sharedStream", null); // ACTION_SEND route if (b.getInt("uriNumber", 0) == 1) { @@ -311,43 +312,45 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc if( sharedContent != null ){ //Shared content - // ParserUtils is a class I borrowed from Tusky. - final ParserUtils parser = new ParserUtils(this); - - parser.putInClipboardManager(TootActivity.this, sharedContent); - String urlString = parser.getPastedURLText(TootActivity.this); - if( sharedSubject != null){ sharedContent = sharedSubject + "\n\n" + sharedContent; } - if( sharedStream != null){ - AsyncHttpClient client = new AsyncHttpClient(); - String[] allowedTypes = new String[] { "image/png" }; - client.get(url, new BinaryHttpResponseHandler(allowedTypes) { - @Override - public void onSuccess(int statusCode, Header[] headers, byte[] binaryData) { - OutputStream f; - try { - f = new FileOutputStream(getCacheDir()); - picture_scrollview.setVisibility(View.VISIBLE); - ByteArrayInputStream bis = new ByteArrayInputStream(binaryData); - loading_picture.setVisibility(View.VISIBLE); - toot_picture.setEnabled(false); - new UploadActionAsyncTask(getApplicationContext(),bis,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - f.write(binaryData); //your bytes - f.close(); - } catch (IOException e) { - e.printStackTrace(); - } + receive_picture = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String url = intent.getStringExtra("pictureURL"); + if( url != null){ + AsyncHttpClient client = new AsyncHttpClient(); + String[] allowedTypes = new String[] { "image/png","image/jpeg" }; + client.get(url, new BinaryHttpResponseHandler(allowedTypes) { + @Override + public void onSuccess(int statusCode, Header[] headers, byte[] binaryData) { + OutputStream f; + try { + f = new FileOutputStream(getCacheDir() + URLUtil.guessFileName(url, null, null)); + picture_scrollview.setVisibility(View.VISIBLE); + InputStream bis = new ByteArrayInputStream(binaryData); + loading_picture.setVisibility(View.VISIBLE); + toot_picture.setEnabled(false); + new UploadActionAsyncTask(getApplicationContext(),bis,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + f.write(binaryData); + f.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error) { + error.printStackTrace(); + } + + }); } - @Override - public void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error) { - - } - - }); - } + } + }; + LocalBroadcastManager.getInstance(this).registerReceiver(receive_picture, new IntentFilter(Helper.RECEIVE_PICTURE)); toot_content.setText( String.format("\n%s", sharedContent)); } attachments = new ArrayList<>(); @@ -572,6 +575,14 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc } } + @Override + public void onDestroy(){ + super.onDestroy(); + if( receive_picture != null) + LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_picture); + } + + @Override public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { @@ -595,15 +606,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc mToast.show(); } - //TODO: This overload takes care of the single URL coming from a text share. - public void uploadSharedImage(Uri image) - { - if (image != null) { - ArrayList uri = new ArrayList<>(); - uri.add(image); - uploadSharedImage(uri); - } - } // Handles uploading shared images public void uploadSharedImage(ArrayList uri) @@ -1373,28 +1375,4 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc changeDrawableColor(TootActivity.this, R.drawable.ic_check, R.color.white); } } - - // TODO: These two methods are part of the interface for ParserUtils - /* - These two methods are added to handle the grafted on code from Tusky, - they are part of its interface. - */ - @Override - public void onReceiveHeaderInfo(ParserUtils.HeaderInfo headerInfo) { - if (!TextUtils.isEmpty(headerInfo.title)) { - Toast.makeText(getApplicationContext(), headerInfo.title, Toast.LENGTH_SHORT).show(); - - if (!TextUtils.isEmpty(headerInfo.image)) { - Toast.makeText(getApplicationContext(), "We have an image", Toast.LENGTH_SHORT).show(); - - Toast.makeText(getApplicationContext(), headerInfo.image, Toast.LENGTH_SHORT).show(); - uploadSharedImage(Uri.parse(headerInfo.image)); - } - } - } - - @Override - public void onErrorHeaderInfo() { - Toast.makeText(this.getApplicationContext(), "An error has occurred.", Toast.LENGTH_SHORT).show(); - } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveMetaDataAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveMetaDataAsyncTask.java new file mode 100644 index 000000000..6874dcf4f --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveMetaDataAsyncTask.java @@ -0,0 +1,69 @@ +/* Copyright 2017 Thomas Schneider + * + * This file is a part of Mastalab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Mastalab; if not, + * see . */ +package fr.gouv.etalab.mastodon.asynctasks; + +import android.os.AsyncTask; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import java.io.IOException; +import fr.gouv.etalab.mastodon.interfaces.OnRetrieveMetaDataInterface; + + +/** + * Created by Thomas on 02/09/2017. + * Retrieves metadata of a remote page + */ + +public class RetrieveMetaDataAsyncTask extends AsyncTask { + + private OnRetrieveMetaDataInterface listener; + private String url; + private boolean error = false; + private String imageUrl, content; + + public RetrieveMetaDataAsyncTask(String url, OnRetrieveMetaDataInterface onRetrieveRemoteAccountInterface){ + this.url = url; + this.listener = onRetrieveRemoteAccountInterface; + } + + @Override + protected Void doInBackground(Void... params) { + String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36"; + try { + Document document = Jsoup.connect(url).userAgent(userAgent).get(); + Elements metaOgTitle = document.select("meta[property=og:title]"); + if (metaOgTitle != null) { + content = metaOgTitle.attr("content"); + } else { + content = document.title(); + } + Elements metaOgImage = document.select("meta[property=og:image]"); + if (metaOgImage != null) { + imageUrl = metaOgImage.attr("content"); + } + } catch (IOException | IndexOutOfBoundsException e) { + error = true; + } + return null; + } + + @Override + protected void onPostExecute(Void result) { + listener.onRetrieveRemoteAccount(error, imageUrl, content); + } + +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java index b70886fc8..4d9954e18 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java @@ -253,7 +253,7 @@ public class Helper { public static final String SEARCH_VALIDATE_ACCOUNT = "search_validate_account"; public static final String HEADER_ACCOUNT = "header_account"; public static final String RECEIVE_DATA = "receive_data"; - + public static final String RECEIVE_PICTURE = "receive_picture"; //User agent public static final String USER_AGENT = "Mastalab/"+ BuildConfig.VERSION_NAME + " Android/"+ Build.VERSION.RELEASE; diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/ManageHeader.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/ManageHeader.java new file mode 100644 index 000000000..cca3a5574 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/ManageHeader.java @@ -0,0 +1,9 @@ +package fr.gouv.etalab.mastodon.helper; + +/** + * Created by Thomas on 02/09/2017. + */ + +public class ManageHeader { + +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/ParserUtils.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/ParserUtils.java deleted file mode 100644 index d74e06d09..000000000 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/ParserUtils.java +++ /dev/null @@ -1,141 +0,0 @@ -package fr.gouv.etalab.mastodon.helper; - -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.os.AsyncTask; -import android.text.TextUtils; -import android.util.Log; -import android.util.Patterns; -import android.webkit.URLUtil; - -import org.jsoup.Connection; -import org.jsoup.Jsoup; -import org.jsoup.helper.HttpConnection; -import org.jsoup.nodes.Document; -import org.jsoup.select.Elements; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; - - -// TODO: Borrowed wholesale from Tusky - -/** - * Inspect and get the information from a URL. - */ -public class ParserUtils { - public final static String carriageReturn = System.getProperty("line.separator"); - final private static String QUOTE = "\""; - - private static final String TAG = "ParserUtils"; - private ParserListener parserListener; - - public ParserUtils(ParserListener parserListener) { - this.parserListener = parserListener; - } - - // TootActivity : EditText inside the onTextChanged - public String getPastedURLText(Context context) { - ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - String pasteData; - if (clipboard.hasPrimaryClip()) { - // get what is in the clipboard - ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0); - pasteData = item.getText().toString(); - - // If we share with an app, it's not only an url - List strings = extractUrl(pasteData); - if (strings.size() > 0) { - String url = strings.get(0); // we assume that the first url is the good one - if (URLUtil.isValidUrl(url)) { - new ThreadHeaderInfo().execute(url); - } - } - } - return null; - } - - public void putInClipboardManager(Context context, String string) { - ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("", string); - clipboard.setPrimaryClip(clip); - } - - /** parse the HTML page */ - private HeaderInfo parsePageHeaderInfo(String urlStr) throws Exception { - Connection con = Jsoup.connect(urlStr); - HeaderInfo headerInfo = new HeaderInfo(); - con.userAgent(HttpConnection.DEFAULT_UA); - Document doc = con.get(); - - // get info - String text; - Elements metaOgTitle = doc.select("meta[property=og:title]"); - if (metaOgTitle != null) { - text = metaOgTitle.attr("content"); - } else { - text = doc.title(); - } - - String imageUrl = null; - Elements metaOgImage = doc.select("meta[property=og:image]"); - if (metaOgImage != null) { - imageUrl = metaOgImage.attr("content"); - } - - // set info - headerInfo.baseUrl = urlStr; - if (!TextUtils.isEmpty(text)) { - headerInfo.title = QUOTE + text + QUOTE; - } - if (!TextUtils.isEmpty(imageUrl)) { - headerInfo.image = (imageUrl); - } - return headerInfo; - } - - public interface ParserListener { - void onReceiveHeaderInfo(HeaderInfo headerInfo); - - void onErrorHeaderInfo(); - } - - public class HeaderInfo { - public String baseUrl; - public String title; - public String image; - } - - private class ThreadHeaderInfo extends AsyncTask { - protected HeaderInfo doInBackground(String... urls) { - try { - String url = urls[0]; - return parsePageHeaderInfo(url); - } catch (Exception e) { - Log.e(TAG, "ThreadHeaderInfo#parsePageHeaderInfo() failed." + e.getMessage()); - return null; - } - } - - protected void onPostExecute(HeaderInfo headerInfo) { - if (headerInfo != null) { - Log.i(TAG, "ThreadHeaderInfo#parsePageHeaderInfo() success." + headerInfo.title + " " + headerInfo.image); - parserListener.onReceiveHeaderInfo(headerInfo); - } else { - parserListener.onErrorHeaderInfo(); - } - } - } - - static List extractUrl(String text) { - List links = new ArrayList<>(); - Matcher m = Patterns.WEB_URL.matcher(text); - while (m.find()) { - String url = m.group(); - links.add(url); - } - return links; - } -} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveMetaDataInterface.java b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveMetaDataInterface.java new file mode 100644 index 000000000..9d57b84be --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveMetaDataInterface.java @@ -0,0 +1,24 @@ +/* Copyright 2017 Thomas Schneider + * + * This file is a part of Mastalab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Mastalab; if not, + * see . */ +package fr.gouv.etalab.mastodon.interfaces; + + +/** + * Created by Thomas on 02/09/2017. + * Interface for retrieving meta data + */ +public interface OnRetrieveMetaDataInterface { + void onRetrieveRemoteAccount(boolean error, String pictureUrl, String content); +} diff --git a/app/src/safetynet/java/fr.gouv.etalab.mastodon/activities/MainActivity.java b/app/src/safetynet/java/fr.gouv.etalab.mastodon/activities/MainActivity.java index fde7d8172..3a94296b8 100644 --- a/app/src/safetynet/java/fr.gouv.etalab.mastodon/activities/MainActivity.java +++ b/app/src/safetynet/java/fr.gouv.etalab.mastodon/activities/MainActivity.java @@ -26,7 +26,6 @@ import android.graphics.PorterDuff; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; -import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.TabLayout; @@ -38,7 +37,6 @@ import android.support.v4.view.ViewPager; import android.support.v7.app.AlertDialog; import android.support.v7.widget.SearchView; import android.support.v7.widget.SwitchCompat; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.support.design.widget.NavigationView; @@ -71,6 +69,7 @@ import java.util.HashMap; import java.util.Locale; import java.util.Stack; +import fr.gouv.etalab.mastodon.asynctasks.RetrieveMetaDataAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoByIDAsyncTask; import fr.gouv.etalab.mastodon.client.Entities.Account; import fr.gouv.etalab.mastodon.client.Entities.Notification; @@ -81,6 +80,7 @@ import fr.gouv.etalab.mastodon.fragments.DisplayFollowRequestSentFragment; import fr.gouv.etalab.mastodon.fragments.DisplayNotificationsFragment; import fr.gouv.etalab.mastodon.fragments.DisplayScheduledTootsFragment; import fr.gouv.etalab.mastodon.helper.Helper; +import fr.gouv.etalab.mastodon.interfaces.OnRetrieveMetaDataInterface; import fr.gouv.etalab.mastodon.interfaces.OnUpdateAccountInfoInterface; import fr.gouv.etalab.mastodon.services.StreamingService; import fr.gouv.etalab.mastodon.sqlite.Sqlite; @@ -107,7 +107,7 @@ import android.support.v4.app.FragmentStatePagerAdapter; public class MainActivity extends AppCompatActivity - implements NavigationView.OnNavigationItemSelectedListener, OnUpdateAccountInfoInterface, ProviderInstaller.ProviderInstallListener { + implements NavigationView.OnNavigationItemSelectedListener, OnUpdateAccountInfoInterface, ProviderInstaller.ProviderInstallListener, OnRetrieveMetaDataInterface { private FloatingActionButton toot; private HashMap tagTile = new HashMap<>(); @@ -621,17 +621,13 @@ public class MainActivity extends AppCompatActivity if ("text/plain".equals(type)) { String sharedSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT); String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); - Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM); - String sharedStream = null; - if( uri!= null) - sharedStream = uri.toString(); - Log.v(Helper.TAG,"sharedStream1: " + sharedStream); + // ParserUtils is a class I borrowed from Tusky. if (sharedText != null) { + new RetrieveMetaDataAsyncTask(sharedText, MainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); Intent intentToot = new Intent(getApplicationContext(), TootActivity.class); Bundle b = new Bundle(); b.putString("sharedSubject", sharedSubject); b.putString("sharedContent", sharedText); - b.putString("sharedStream", sharedStream); intentToot.putExtras(b); startActivity(intentToot); } @@ -1080,6 +1076,14 @@ public class MainActivity extends AppCompatActivity // appropriate action. } + @Override + public void onRetrieveRemoteAccount(boolean error, String pictureUrl, String content) { + if( !error && pictureUrl != null) { + Intent intentSendImage = new Intent(Helper.RECEIVE_PICTURE); + intentSendImage.putExtra("pictureURL", pictureUrl); + LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intentSendImage); + } + } /**