Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Widget開発再訪

ymnder
February 05, 2018

 Widget開発再訪

DroidKaigi2018, Room 2 - 2018/02/08 14:00-14:30
https://droidkaigi.jp/2018/timetable?session=16949

ymnder

February 05, 2018
Tweet

More Decks by ymnder

Other Decks in Programming

Transcript

  1. Widget Category ᶃ Information widgets ᶄ Collection widgets ᶅ Control

    widgets ᶆ Hybrid widgets ΨΠυϥΠϯɿhttps://material.io/guidelines/components/widgets.html#widgets-types-of-widgets چΨΠυϥΠϯɿhttps://developer.android.com/design/patterns/widgets.html 14
  2. Widget Category ᶃ Information widgets ᶄ Collection widgets ᶅ Control

    widgets ᶆ Hybrid widgets ΨΠυϥΠϯɿhttps://material.io/guidelines/components/widgets.html#widgets-types-of-widgets چΨΠυϥΠϯɿhttps://developer.android.com/design/patterns/widgets.html 15
  3. Widget Category ᶃ Information widgets ᶄ Collection widgets ᶅ Control

    widgets ᶆ Hybrid widgets ΨΠυϥΠϯɿhttps://material.io/guidelines/components/widgets.html#widgets-types-of-widgets چΨΠυϥΠϯɿhttps://developer.android.com/design/patterns/widgets.html 17
  4. Widget Category ᶃ Information widgets ᶄ Collection widgets ᶅ Control

    widgets ᶆ Hybrid widgets ΨΠυϥΠϯɿhttps://material.io/guidelines/components/widgets.html#widgets-types-of-widgets چΨΠυϥΠϯɿhttps://developer.android.com/design/patterns/widgets.html 19
  5. Widget Category ᶃ Information widgets ᶄ Collection widgets ᶅ Control

    widgets ᶆ Hybrid widgets ΨΠυϥΠϯɿhttps://material.io/guidelines/components/widgets.html#widgets-types-of-widgets چΨΠυϥΠϯɿhttps://developer.android.com/design/patterns/widgets.html 21
  6. Widget Classes • AppWidgetService • WidgetIdͷൃߦ΍ϥϯνϟʔ΁ͷϦΫΤετΛߦ͏ • AppWidgetHost • WidgetͱϗʔϜը໘ͷ஥ཱͪΛߦ͏

    • AppWidgetHostView • WidgetΛදࣔ͢ΔͨΊͷදࣔྖҬΛఏڙ͢Δ • AppWidgetManager • Widgetͷঢ়ଶΛߋ৽ͨ͠Γɺ৘ใΛऔಘ͢Δ؅ཧΫϥε • AppWidgetProvider • Widgetͷ֤छͷΠϕϯτΛϋϯυϦϯά͢Δ • AppWidgetProviderInfo • WidgetͷϝλσʔλΛѻ͏ 34
  7. Widget Classes • AppWidgetService • WidgetIdͷൃߦ΍ϥϯνϟʔ΁ͷϦΫΤετΛߦ͏ • AppWidgetHost • WidgetͱϗʔϜը໘ͷ஥ཱͪΛߦ͏

    • AppWidgetHostView • WidgetΛදࣔ͢ΔͨΊͷදࣔྖҬΛఏڙ͢Δ • AppWidgetManager • Widgetͷঢ়ଶΛߋ৽ͨ͠Γɺ৘ใΛऔಘ͢Δ؅ཧΫϥε • AppWidgetProvider • Widgetͷ֤छͷΠϕϯτΛϋϯυϦϯά͢Δ • AppWidgetProviderInfo • WidgetͷϝλσʔλΛѻ͏ 35 ←࣮૷Ͱ࢖͏
  8. Widget Classes: Simplify • AppWidgetManager • WidgetͷViewͷߋ৽Λߦ͏ • AppWidgetProvider •

    Widgetͷߋ৽Λϋϯυϧ͢Δ • AppWidgetProviderInfo • Widgetͷجຊ৘ใΛxmlʹهड़͢Δ • xml/layout • WidgetͷϨΠΞ΢τɺ௨ৗͷϨΠΞ΢τͱ֓Ͷಉ͡ 36
  9. onRecieve 58 public void onReceive(Context context, Intent intent) { String

    action = intent.getAction(); if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { this.onUpdate(…); } else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) { this.onDeleted(…); } else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) { this.onAppWidgetOptionsChanged(…); } else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) { this.onEnabled(…); } else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) { this.onDisabled(…); } else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) { this.onRestored(…); this.onUpdate(…); } }
  10. onAppWidgetOptionsChanged • ϦαΠζ͞Εͨͱ͖ʹݺ͹ΕΔ • added in API level 16 •

    ը໘αΠζΛdpͰऔಘͰ͖Δ • খ͘͞ͳͬͨͱ͖ʹཁૉΛඇදࣔͨ͠ΓͰ͖Δ •OPTION_MIN_WIDTHɿݱࡏͷwidthͷԼݶ •OPTION_MAX_WIDTHɿݱࡏͷwidthͷ্ݶ •OPTION_MIN_HEIGHTɿݱࡏͷheightͷԼݶ •OPTION_MAX_HEIGHTɿݱࡏͷheightͷ্ݶ 65
  11. onRestored • ௚ޙʹonUpdateΛݺͼग़͢ • added in API level 21 •

    backup͔Βprovider͕ϦετΞ͞Εͨͱ͖ʹݺ͹ΕΔ • widgetʹඥ෇͍ͨσʔλΛอ͍࣋ͨ͠৔߹ʹ࢖͏ • ݹ͍id͔Β৽͍͠id΁ͷҾ͖ܧ͗Λߦ͏ • widgetIdͱ͸ʁʔʼAppendix΁ʂ 66
  12. ࣮૷ 68 class SampleAppWidgetProvider : AppWidgetProvider() { override fun onUpdate(…)

    { for (appWidgetId in appWidgetIds) { val intent = Intent(context, MainActivity::class.java) val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0) val views = RemoteViews(context.packageName, R.layout.widget_container) views.setTextViewText(R.id.textWidget, "Hello:)") views.setOnClickPendingIntent(R.id.button, pendingIntent) appWidgetManager.updateAppWidget(appWidgetId, views) } } }
  13. ࣮૷ɿListViewͷέʔε 71 fun updateWidget(context: Context, appWidgetId: Int) { val manager

    = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.getPackageName(), R.layout.widget_container) // ListItemʹߋ৽௨஌Λߦ͏ͨΊͷintentΛ࡞੒ val intent = Intent(context, SampleWidgetService::class.java) .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) remoteViews.setRemoteAdapter(R.id.widgetListView, intent) // ListItem͕ۭͩͬͨ৔߹ͷEmptyදࣔ remoteViews.setEmptyView(R.id.widgetListView, android.R.id.empty) // ListItemΛλοϓͨ͠ͱ͖ͷintentΛηοτ // ListItemͷଆͰηοτ͢ΔͷͰͳ͘ɺ͜͜Ͱηοτ͢Δ val onClickIntent = Intent(context, DetailActivity::class.java) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) val onClickPendingIntent = PendingIntent.getActivity(context, 0, onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT) remoteViews.setPendingIntentTemplate(R.id.widgetListView, onClickPendingIntent) manager.updateAppWidget(appWidgetId, remoteViews) }
  14. ࣮૷ɿListViewͷέʔε 72 fun updateWidget(context: Context, appWidgetId: Int) { val manager

    = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.getPackageName(), R.layout.widget_container) // ListItemʹߋ৽௨஌Λߦ͏ͨΊͷintentΛ࡞੒ val intent = Intent(context, SampleWidgetService::class.java) .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) remoteViews.setRemoteAdapter(R.id.widgetListView, intent) // ListItem͕ۭͩͬͨ৔߹ͷEmptyදࣔ remoteViews.setEmptyView(R.id.widgetListView, android.R.id.empty) // ListItemΛλοϓͨ͠ͱ͖ͷintentΛηοτ // ListItemͷଆͰηοτ͢ΔͷͰͳ͘ɺ͜͜Ͱηοτ͢Δ val onClickIntent = Intent(context, DetailActivity::class.java) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) val onClickPendingIntent = PendingIntent.getActivity(context, 0, onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT) remoteViews.setPendingIntentTemplate(R.id.widgetListView, onClickPendingIntent) manager.updateAppWidget(appWidgetId, remoteViews) }
  15. ࣮૷ɿListViewͷέʔε 73 fun updateWidget(context: Context, appWidgetId: Int) { val manager

    = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.getPackageName(), R.layout.widget_container) // ListItemʹߋ৽௨஌Λߦ͏ͨΊͷintentΛ࡞੒ val intent = Intent(context, SampleWidgetService::class.java) .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) remoteViews.setRemoteAdapter(R.id.widgetListView, intent) // ListItem͕ۭͩͬͨ৔߹ͷEmptyදࣔ remoteViews.setEmptyView(R.id.widgetListView, android.R.id.empty) // ListItemΛλοϓͨ͠ͱ͖ͷintentΛηοτ // ListItemͷଆͰηοτ͢ΔͷͰͳ͘ɺ͜͜Ͱηοτ͢Δ val onClickIntent = Intent(context, DetailActivity::class.java) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) val onClickPendingIntent = PendingIntent.getActivity(context, 0, onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT) remoteViews.setPendingIntentTemplate(R.id.widgetListView, onClickPendingIntent) manager.updateAppWidget(appWidgetId, remoteViews) }
  16. ࣮૷ɿListView(Item)ͷέʔε 74 override fun getViewAt(position: Int): RemoteViews { val rv

    = RemoteViews(context.packageName, R.layout.list_item) rv.setTextViewText(R.id.list_text, items[position]) //͜͜ͰIntentΛ٧ΊΔɻ͜ͷintent͸͜ͷΫϥεͷݺͼग़͠ݩ΁౉͞ΕΔ //ListItemͷ࣋ͭσʔλ͕ཉ͍͠৔߹͸͜ͷintentʹ٧ΊΔ rv.setOnClickFillInIntent(R.id.list_container, createIntent(position)) return rv }
  17. ը໘ͷେ͖͞Λࢦఆ͢Δ΋ͷ • int minWidth / int minHeight • σϑΥϧτͷ෯ͱߴ͞ΛdpͰࢦఆ͢Δ •

    int minResizeWidth / int minResizeHeight • ϦαΠζͷԼݶΛdpͰࢦఆ͢Δ • minResizeWidth <= minWidth • minResizeHeight <= minHeight • int resizeMode(horizontal|vertical or none) • Ͳͷํ޲ͷϦαΠζΛڐՄ͢Δ͔ 77
  18. ϨΠΞ΢τ • int initialKeyguardLayout • KeyGuardʹදࣔͨ͠ͱ͖ͷϨΠΞ΢τΛࢦఆ͢Δ • int initialLayout •

    ΢ΟδΣοτͷϨΠΞ΢τΛࢦఆ͢Δ • int widgetCategory(home_screen|keyguard) • ΢ΟδΣοτΛͲ͜ʹஔ͚Δ͔ࢦఆ͢Δ • keyguard͸Android 5.0Ҏ্Ͱ͸࢖༻Ͱ͖ͳ͍ 79
  19. ը໘ߋ৽ܥ • int updatePeriodMillis • ϛϦඵͰWidgetͷߋ৽ִؒΛࢦఆ͢Δ(30minҎ্) • ComponentName configure •

    WidgetΛ௥Ճͨ͠৔߹ʹࢦఆͨ͠ActivityΛݺͼग़ͯ͘͠ΕΔ • onUpdate͸ݺ͹Εͳ͍ͷͰผ్ݺͿඞཁ͕͋Δ • Widget Dialog͔Βઃஔͨ͠ͱ͖ʹ͸ݺ͹Εͳ͍ • int autoAdvanceViewId • StackViewͳͲࢠཁૉΛ࣋ͭϨΠΞ΢τͷidΛࢦఆ͢Δ • Ϣʔβʔͷૢ࡞͕ͳͯ͘΋ࣗಈͰViewΛਐΊΔ 80
  20. ࣮૷ 87 val widgetManager = AppWidgetManager.getInstance(this) val provider = ComponentName(this,

    SampleAppWidgetProvider::class.java) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return if (widgetManager.isRequestPinAppWidgetSupported) { val callbackIntent = Intent(this, SubActivity::class.java) val successCallback = PendingIntent.getActivity(this, 0, callbackIntent, 0) val extras = Bundle() val remoteViews = RemoteViews(this.packageName, R.layout.widget_container) remoteViews.setTextViewText(R.id.button, "ͯ͢ͱ") extras.putParcelable(EXTRA_APPWIDGET_PREVIEW, remoteViews) widgetManager.requestPinAppWidget(provider, extras, null) }
  21. ࣮૷ 88 val widgetManager = AppWidgetManager.getInstance(this) val provider = ComponentName(this,

    SampleAppWidgetProvider::class.java) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return if (widgetManager.isRequestPinAppWidgetSupported) { val callbackIntent = Intent(this, SubActivity::class.java) val successCallback = PendingIntent.getActivity(this, 0, callbackIntent, 0) val extras = Bundle() val remoteViews = RemoteViews(this.packageName, R.layout.widget_container) remoteViews.setTextViewText(R.id.button, "ͯ͢ͱ") extras.putParcelable(EXTRA_APPWIDGET_PREVIEW, remoteViews) widgetManager.requestPinAppWidget(provider, extras, null) }
  22. ࣮૷ 90 val widgetManager = AppWidgetManager.getInstance(this) val provider = ComponentName(this,

    SampleAppWidgetProvider::class.java) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return if (widgetManager.isRequestPinAppWidgetSupported) { val callbackIntent = Intent(this, SubActivity::class.java) val successCallback = PendingIntent.getActivity(this, 0, callbackIntent, 0) val extras = Bundle() val remoteViews = RemoteViews(this.packageName, R.layout.widget_container) remoteViews.setTextViewText(R.id.button, "ͯ͢ͱ") extras.putParcelable(EXTRA_APPWIDGET_PREVIEW, remoteViews) widgetManager.requestPinAppWidget(provider, extras, null) }
  23. ࣮૷ 92 val widgetManager = AppWidgetManager.getInstance(this) val provider = ComponentName(this,

    SampleAppWidgetProvider::class.java) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return if (widgetManager.isRequestPinAppWidgetSupported) { val callbackIntent = Intent(this, SubActivity::class.java) val successCallback = PendingIntent.getActivity(this, 0, callbackIntent, 0) val extras = Bundle() val remoteViews = RemoteViews(this.packageName, R.layout.widget_container) remoteViews.setTextViewText(R.id.button, "ͯ͢ͱ") extras.putParcelable(EXTRA_APPWIDGET_PREVIEW, remoteViews) widgetManager.requestPinAppWidget(provider, extras, null) }
  24. ղઆ: successCallback • ઃஔޙʹݺͿcallbackΛPendingIntentͱͯ͠ηοτ • callback͸Widgetͷ௥ՃμΠΞϩάͰඞཁͱͳΔ • ࣗಈͰ௥ՃorखಈͰ௥Ճͷ̎௨Γ͋Δ • ࣗಈͰ௥Ճ

    • ΞϓϦͷը໘͔ΒભҠ͠ͳ͍ • खಈͰ௥Ճ • ϗʔϜϥϯνϟʔʹભҠ • ࣗ෼ͷΞϓϦʹ໭ͬͯ͜ͳ͍ • BroadcastͳͲΛ࢖༻ͯ͠෮ؼͯ͠΋Β͏ 93
  25. ղઆ: successCallback • ઃஔޙʹݺͿcallbackΛPendingIntentͱͯ͠ηοτ • callback͸Widgetͷ௥ՃμΠΞϩάͰඞཁͱͳΔ • ࣗಈͰ௥ՃorखಈͰ௥Ճͷ̎௨Γ͋Δ • ࣗಈͰ௥Ճ

    • ΞϓϦͷը໘͔ΒભҠ͠ͳ͍ • खಈͰ௥Ճ • ϗʔϜϥϯνϟʔʹભҠ • ࣗ෼ͷΞϓϦʹ໭ͬͯ͜ͳ͍ • BroadcastͳͲΛ࢖༻ͯ͠෮ؼͯ͠΋Β͏ 94
  26. ղઆ: successCallback • ઃஔޙʹݺͿcallbackΛPendingIntentͱͯ͠ηοτ • callback͸Widgetͷ௥ՃμΠΞϩάͰඞཁͱͳΔ • ࣗಈͰ௥ՃorखಈͰ௥Ճͷ̎௨Γ͋Δ • ࣗಈͰ௥Ճ

    • ΞϓϦͷը໘͔ΒભҠ͠ͳ͍ • खಈͰ௥Ճ • ϗʔϜϥϯνϟʔʹભҠ • ࣗ෼ͷΞϓϦʹ໭ͬͯ͜ͳ͍ • BroadcastͳͲΛ࢖༻ͯ͠෮ؼͯ͠΋Β͏ 95
  27. ࣮૷ 96 val widgetManager = AppWidgetManager.getInstance(this) val provider = ComponentName(this,

    SampleAppWidgetProvider::class.java) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return if (widgetManager.isRequestPinAppWidgetSupported) { val callbackIntent = Intent(this, SubActivity::class.java) val successCallback = PendingIntent.getActivity(this, 0, callbackIntent, 0) val extras = Bundle() val remoteViews = RemoteViews(this.packageName, R.layout.widget_container) remoteViews.setTextViewText(R.id.button, "ͯ͢ͱ") extras.putParcelable(EXTRA_APPWIDGET_PREVIEW, remoteViews) widgetManager.requestPinAppWidget(provider, extras, null) }
  28. ࣮૷ 98 val widgetManager = AppWidgetManager.getInstance(this) val provider = ComponentName(this,

    SampleAppWidgetProvider::class.java) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return if (widgetManager.isRequestPinAppWidgetSupported) { val callbackIntent = Intent(this, SubActivity::class.java) val successCallback = PendingIntent.getActivity(this, 0, callbackIntent, 0) val extras = Bundle() val remoteViews = RemoteViews(this.packageName, R.layout.widget_container) remoteViews.setTextViewText(R.id.button, "ͯ͢ͱ") extras.putParcelable(EXTRA_APPWIDGET_PREVIEW, remoteViews) widgetManager.requestPinAppWidget(provider, extras, null) }
  29. whoami • twitter:@ymnd, github:@ymnder • Application Engineer • Android ೔ܦిࢠ൛ΞϓϦ

    • Android ࢴ໘ϏϡʔΞʔΞϓϦ • ٕज़ॻయ̐Ͱ೔ܦిࢠ൛ͷ஌ݟΛ·ͱΊͨຊΛग़͠·͢ 104
  30. How to Calculate minWidth and minHeight WidgetͷminWidth/minHeightͷࢉग़ࣜ 70 × cell

    − 30 = size ྫɿ1ߦ2ྻͷwidgetΛ࡞੒͢Δ৔߹͸ minHeight =70 x 1 - 30 = 40 minWidth = 70 x 2 - 30 = 110 107
  31. How to Calculate minWidth and minHeight • API14ҎલͰܭࢉํ๏͕Ξοϓσʔτ͞Εͨʂ • targetSDK͕API14Ҏ্ͷ৔߹ɺϗʔϜը໘ͷ΢ΟδΣ

    οτͷ֤୺ʹϚʔδϯ͕ࣗಈతʹ௥Ճ͞ΕΔ • ͦͷͨΊɺAndroid4.0Ҏ্Ͱ͸widgetʹ༧Ί༨നΛ௥ Ճ͢Δඞཁ͸ͳ͍ 108
  32. how is appWidgetId created? • appWidgetId͸WidgetΛߋ৽͢Δͱ͖ʹ༻͍ΔID • ͜ͷID͕ͲͷΑ͏ʹৼΒΕ͍ͯΔ͔͕ؾʹͳΔ • ຊ౰ʹϢχʔΫͳͷʁ

    • AppWidgetHost.java#allocateAppWidgetId 110 //Get a appWidgetId for a host in the calling process. //@return a appWidgetId public int allocateAppWidgetId() {…}
  33. AppWidgetServiceImpl.java 111 public int allocateAppWidgetId(String callingPackage, int hostId) { ...

    if (mNextAppWidgetIds.indexOfKey(userId) < 0) { // ॳظԽॲཧ // AppWidgetManager.INVALID_APPWIDGET_ID͸0 // Widget͸1͔Β࠾൪͞Ε͍ͯ͘ɻ mNextAppWidgetIds.put(userId, AppWidgetManager.INVALID_APPWIDGET_ID + 1); } final int appWidgetId = incrementAndGetAppWidgetIdLocked(userId); ... }
  34. ͲͷΑ͏ʹ൪߸͕ৼΒΕΔ͔ʁ • mNextAppWidgetIds • {userId, appWidgetId}ͷϖΞͰid͕อଘ͞ΕΔ • ಡΈग़ͨ͠ޙɺ+1ͯ͠࠶౓อଘ͍ͯ͠Δ 112 private

    final SparseIntArray mNextAppWidgetIds = new SparseIntArray(); final int appWidgetId = peekNextAppWidgetIdLocked(userId) + 1; return mNextAppWidgetIds.get(userId);
  35. requestPinAppWidget & isRequestPinAppWidgetSupportedͷฦΓ஋ • isRequestPinAppWidgetSupported • Return {@code TRUE} if

    the default launcher supports • updateAppWidget • {@code TRUE} if the launcher supports this feature. Note the API will return without waiting for the user to respond, so getting {@code TRUE} from this API does not mean the shortcut is pinned. {@code FALSE} if the launcher doesn't support this feature. • ͜Εʹ͸ͲΜͳҧ͍͕͋Δͷ͔ 114
  36. callback͸ͲͷλΠϛϯάͰݺ͹ΕΔ͔ʁ → LauncherApps.java#PinItemRequest ੒ޭ࣌ʹacceptΛݺͿ → ShortcutRequestPinProcessor.java#PinAppWidgetRequestInner → ShortcutRequestPinProcessor.java#PinItemRequestInner ͜͜Ͱacceptͷத਎͕࣮૷͞Ε͍ͯΔ →

    ShortcutRequestPinProcessor.java#directPinShortcut ྫ֎ΛΩϟον͍ͯͯ͠ɺ࡞੒Ͱ͖ͳ͔ͬͨ৔߹͸falseΛฦ͢ tryAccept͕falseʹͳΓɺίʔϧόοΫ͕࣮ߦ͞Εͳ͍ → ShortcutService.java#fixUpIncomingShortcutInfo 122
  37. callback͸ͲͷλΠϛϯάͰݺ͹ΕΔ͔ʁʢऴ఺ʣ • tryAccept͕trueͷͱ͖sendResultIntent͕࣮ߦ͞ΕΔ • ͢ͳΘͪ͜͜Ͱcallback͕࣮ߦ͞ΕΔ • ࣦഊ࣌͸Կ΋͞Εͳ͍Ͱfalse͕ฦΔ 123 // PinItemRequestInner#accept

    // Pin it and send the result intent. if (tryAccept()) { mProcessor.sendResultIntent(mResultIntent, extras); return true; } else { return false; }