Loading app/src/main/AndroidManifest.xml +9 −4 Original line number Original line Diff line number Diff line Loading @@ -115,10 +115,15 @@ <activity android:name=".features.widgets.WidgetsActivity" <activity android:name=".features.widgets.WidgetsActivity" android:autoRemoveFromRecents="true" android:autoRemoveFromRecents="true" android:excludeFromRecents="true" android:excludeFromRecents="true" android:theme="@android:style/Theme.Material.Light.DarkActionBar" android:theme="@style/AppTheme" android:label="Widgets"> android:label="Widgets"/> <activity android:name=".features.widgets.WidgetPicker" </activity> android:autoRemoveFromRecents="true" android:excludeFromRecents="true" android:theme="@style/WidgetPickerDialog" android:finishOnCloseSystemDialogs="true" android:label="Choose widget" android:exported="true"/> </application> </application> </manifest> </manifest> No newline at end of file app/src/main/java/foundation/e/blisslauncher/features/widgets/AddedWidgetsAdapter.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,8 @@ public class AddedWidgetsAdapter extends @NonNull @NonNull @Override @Override public WidgetsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { public WidgetsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View view = LayoutInflater.from(mContext).inflate(R.layout.item_widget_all, viewGroup, false); View view = LayoutInflater.from(mContext).inflate(R.layout.item_added_widget, viewGroup, false); WidgetsViewHolder widgetsViewHolder = new WidgetsViewHolder(view); WidgetsViewHolder widgetsViewHolder = new WidgetsViewHolder(view); widgetsViewHolder.actionBtn.setImageResource(R.drawable.ic_remove_widget_red_24dp); widgetsViewHolder.actionBtn.setImageResource(R.drawable.ic_remove_widget_red_24dp); widgetsViewHolder.actionBtn.setOnClickListener( widgetsViewHolder.actionBtn.setOnClickListener( Loading Loading @@ -79,7 +80,6 @@ public class AddedWidgetsAdapter extends label = itemView.findViewById(R.id.widget_label); label = itemView.findViewById(R.id.widget_label); actionBtn = itemView.findViewById(R.id.action_image_view); actionBtn = itemView.findViewById(R.id.action_image_view); } } } } interface OnActionClickListener { interface OnActionClickListener { Loading app/src/main/java/foundation/e/blisslauncher/features/widgets/WidgetPicker.java 0 → 100644 +218 −0 Original line number Original line Diff line number Diff line package foundation.e.blisslauncher.features.widgets; import android.app.Activity; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Parcelable; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.DisplayMetrics; import android.util.Log; import android.widget.Toast; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import foundation.e.blisslauncher.R; public class WidgetPicker extends Activity implements WidgetPickerAdapter.OnClickListener { private static final int REQUEST_BIND_APPWIDGET = 111; private int mAppWidgetId; private AppWidgetManager mAppWidgetManager; private PackageManager mPackageManager; private static final String TAG = "WidgetPicker"; private Intent mBaseIntent; @Override public void onCreate(Bundle savedInstanceState) { mPackageManager = getPackageManager(); mAppWidgetManager = AppWidgetManager.getInstance(this); super.onCreate(savedInstanceState); // Set default return data setResultData(RESULT_CANCELED, null); // Read the appWidgetId passed our direction, otherwise bail if not found final Intent intent = getIntent(); if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } else { finish(); } // Read base intent from extras, otherwise assume default Parcelable parcel = intent.getParcelableExtra(Intent.EXTRA_INTENT); if (parcel instanceof Intent) { mBaseIntent = (Intent) parcel; mBaseIntent.setFlags(mBaseIntent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)); } else { mBaseIntent = new Intent(Intent.ACTION_MAIN, null); mBaseIntent.addCategory(Intent.CATEGORY_DEFAULT); } setContentView(R.layout.activity_widget_picker); RecyclerView recyclerView = findViewById(R.id.all_widgets_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setHasFixedSize(true); recyclerView.addItemDecoration( new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); WidgetPickerAdapter adapter = new WidgetPickerAdapter(this); recyclerView.setAdapter(adapter); List<WidgetPickerAdapter.Item> items = new ArrayList<>(); putInstalledAppWidgets(items); Collections.sort(items, new Comparator<WidgetPickerAdapter.Item>() { Collator mCollator = Collator.getInstance(); public int compare(WidgetPickerAdapter.Item lhs, WidgetPickerAdapter.Item rhs) { return mCollator.compare(lhs.getLabel(), rhs.getLabel()); } }); adapter.setItems(items); } private void putInstalledAppWidgets(List<WidgetPickerAdapter.Item> items) { List<AppWidgetProviderInfo> installed = mAppWidgetManager.getInstalledProviders(); if (installed == null) return; final int size = installed.size(); for (int i = 0; i < size; i++) { AppWidgetProviderInfo info = installed.get(i); items.add(createItem(info)); } } public WidgetPickerAdapter.Item createItem(AppWidgetProviderInfo info) { CharSequence label = info.loadLabel(mPackageManager); Drawable icon = null; if (info.icon != 0) { try { final Resources res = getResources(); final int density = res.getDisplayMetrics().densityDpi; int iconDensity; switch (density) { case DisplayMetrics.DENSITY_MEDIUM: iconDensity = DisplayMetrics.DENSITY_LOW; break; case DisplayMetrics.DENSITY_TV: iconDensity = DisplayMetrics.DENSITY_MEDIUM; break; case DisplayMetrics.DENSITY_HIGH: iconDensity = DisplayMetrics.DENSITY_MEDIUM; break; case DisplayMetrics.DENSITY_XHIGH: iconDensity = DisplayMetrics.DENSITY_HIGH; break; case DisplayMetrics.DENSITY_XXHIGH: iconDensity = DisplayMetrics.DENSITY_XHIGH; break; default: // The density is some abnormal value. Return some other // abnormal value that is a reasonable scaling of it. iconDensity = (int) ((density * 0.75f) + .5f); } Resources packageResources = mPackageManager. getResourcesForApplication(info.provider.getPackageName()); icon = packageResources.getDrawableForDensity(info.icon, iconDensity); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Can't load icon drawable 0x" + Integer.toHexString(info.icon) + " for provider: " + info.provider); } if (icon == null) { Log.w(TAG, "Can't load icon drawable 0x" + Integer.toHexString(info.icon) + " for provider: " + info.provider); } } WidgetPickerAdapter.Item item = new WidgetPickerAdapter.Item(label, icon); item.packageName = info.provider.getPackageName(); item.className = info.provider.getClassName(); item.profile = info.getProfile(); return item; } @Override public void onClick(WidgetPickerAdapter.Item item) { Intent intent = item.getIntent(mBaseIntent); int result = -10; if (item.extras != null) { setResultData(RESULT_OK, intent); } else { try { Bundle options = null; if (intent.getExtras() != null) { options = intent.getExtras().getBundle( AppWidgetManager.EXTRA_APPWIDGET_OPTIONS); } boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(mAppWidgetId, intent.getComponent(), options); if (success) { result = RESULT_OK; } else { Intent permissionIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); permissionIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); permissionIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, new ComponentName(item.packageName, item.className)); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, item.profile); // TODO: we need to make sure that this accounts for the options bundle. // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options); startActivityForResult(permissionIntent, REQUEST_BIND_APPWIDGET); } } catch (IllegalArgumentException e) { result = RESULT_CANCELED; } setResultData(result, null); } finish(); } /** * Convenience method for setting the result code and intent. This method * correctly injects the {@link AppWidgetManager#EXTRA_APPWIDGET_ID} that * most hosts expect returned. */ void setResultData(int code, Intent intent) { Intent result = intent != null ? intent : new Intent(); result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); setResult(code, result); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d(TAG, "onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]"); if (requestCode == REQUEST_BIND_APPWIDGET) { int appWidgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1; if (resultCode == RESULT_OK) { setResultData(RESULT_OK, null); } else { Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show(); setResultData(RESULT_CANCELED, null); } finish(); } else { super.onActivityResult(requestCode, resultCode, data); } } } app/src/main/java/foundation/e/blisslauncher/features/widgets/WidgetPickerAdapter.java 0 → 100644 +142 −0 Original line number Original line Diff line number Diff line package foundation.e.blisslauncher.features.widgets; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import foundation.e.blisslauncher.R; public class WidgetPickerAdapter extends RecyclerView.Adapter<WidgetPickerAdapter.WidgetsViewHolder> { private Context mContext; private List<Item> mItems = new ArrayList<>(); private OnClickListener mOnClickListener; private static final String TAG = "AddedWidgetsAdapter"; public WidgetPickerAdapter(Context context) { this.mContext = context; mOnClickListener = (OnClickListener) mContext; } @NonNull @Override public WidgetsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View view = LayoutInflater.from(mContext).inflate(R.layout.item_all_widget, viewGroup, false); WidgetsViewHolder widgetsViewHolder = new WidgetsViewHolder(view); widgetsViewHolder.itemView.setOnClickListener(v -> { int position = widgetsViewHolder.getAdapterPosition(); if (position != RecyclerView.NO_POSITION){ mOnClickListener.onClick(mItems.get(position)); } }); return widgetsViewHolder; } @Override public void onBindViewHolder(@NonNull WidgetsViewHolder widgetsViewHolder, int i) { Item info = mItems.get(i); widgetsViewHolder.icon.setImageDrawable(info.icon); widgetsViewHolder.label.setText(info.label); } @Override public int getItemCount() { return mItems.size(); } public void setItems(List<Item> items) { this.mItems = items; notifyDataSetChanged(); } public static class WidgetsViewHolder extends RecyclerView.ViewHolder { ImageView icon; TextView label; public WidgetsViewHolder(@NonNull View itemView) { super(itemView); icon = itemView.findViewById(R.id.widget_icon); label = itemView.findViewById(R.id.widget_label); } } public static class Item { public UserHandle profile; CharSequence label; Drawable icon; String packageName; String className; Bundle extras; /** * Create a list item from given label and icon. */ Item(CharSequence label, Drawable icon) { this.label = label; this.icon = icon; } /** * Create a list item and fill it with details from the given * {@link ResolveInfo} object. */ Item(PackageManager pm, ResolveInfo resolveInfo) { label = resolveInfo.loadLabel(pm); if (label == null && resolveInfo.activityInfo != null) { label = resolveInfo.activityInfo.name; } icon = resolveInfo.loadIcon(pm); packageName = resolveInfo.activityInfo.applicationInfo.packageName; className = resolveInfo.activityInfo.name; } /** * Build the {@link Intent} described by this item. If this item * can't create a valid {@link android.content.ComponentName}, it will return * {@link Intent#ACTION_CREATE_SHORTCUT} filled with the item label. */ Intent getIntent(Intent baseIntent) { Intent intent = new Intent(baseIntent); if (packageName != null && className != null) { // Valid package and class, so fill details as normal intent intent.setClassName(packageName, className); if (extras != null) { intent.putExtras(extras); } } else { // No valid package or class, so treat as shortcut with label intent.setAction(Intent.ACTION_CREATE_SHORTCUT); intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label); } return intent; } public CharSequence getLabel() { return label; } } interface OnClickListener { void onClick(Item item); } } app/src/main/java/foundation/e/blisslauncher/features/widgets/WidgetsActivity.java +15 −3 Original line number Original line Diff line number Diff line Loading @@ -3,12 +3,14 @@ package foundation.e.blisslauncher.features.widgets; import android.app.Activity; import android.app.Activity; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.appwidget.AppWidgetProviderInfo; import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.Intent; import android.os.Bundle; import android.os.Bundle; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView; import android.util.DisplayMetrics; import android.util.DisplayMetrics; import android.widget.Toast; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; Loading Loading @@ -81,7 +83,7 @@ public class WidgetsActivity extends Activity implements AddedWidgetsAdapter.OnA void selectWidget() { void selectWidget() { int appWidgetId = this.mAppWidgetHost.allocateAppWidgetId(); int appWidgetId = this.mAppWidgetHost.allocateAppWidgetId(); Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK); Intent pickIntent = new Intent(this, WidgetPicker.class); pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); addEmptyData(pickIntent); addEmptyData(pickIntent); startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET); startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET); Loading Loading @@ -117,10 +119,11 @@ public class WidgetsActivity extends Activity implements AddedWidgetsAdapter.OnA int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId); AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId); if (appWidgetInfo != null && appWidgetInfo.configure != null) { if (appWidgetInfo != null && appWidgetInfo.configure != null) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); /*Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); intent.setComponent(appWidgetInfo.configure); intent.setComponent(appWidgetInfo.configure); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); startActivityForResult(intent, REQUEST_CREATE_APPWIDGET); startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);*/ startAppWidgetConfigureActivitySafely(appWidgetId); } else { } else { createWidget(data); createWidget(data); } } Loading @@ -138,4 +141,13 @@ public class WidgetsActivity extends Activity implements AddedWidgetsAdapter.OnA refreshRecyclerView(); refreshRecyclerView(); } } void startAppWidgetConfigureActivitySafely(int appWidgetId) { try { mAppWidgetHost.startAppWidgetConfigureActivityForResult(this, appWidgetId, 0, REQUEST_CREATE_APPWIDGET, null); } catch (ActivityNotFoundException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); } } } } Loading
app/src/main/AndroidManifest.xml +9 −4 Original line number Original line Diff line number Diff line Loading @@ -115,10 +115,15 @@ <activity android:name=".features.widgets.WidgetsActivity" <activity android:name=".features.widgets.WidgetsActivity" android:autoRemoveFromRecents="true" android:autoRemoveFromRecents="true" android:excludeFromRecents="true" android:excludeFromRecents="true" android:theme="@android:style/Theme.Material.Light.DarkActionBar" android:theme="@style/AppTheme" android:label="Widgets"> android:label="Widgets"/> <activity android:name=".features.widgets.WidgetPicker" </activity> android:autoRemoveFromRecents="true" android:excludeFromRecents="true" android:theme="@style/WidgetPickerDialog" android:finishOnCloseSystemDialogs="true" android:label="Choose widget" android:exported="true"/> </application> </application> </manifest> </manifest> No newline at end of file
app/src/main/java/foundation/e/blisslauncher/features/widgets/AddedWidgetsAdapter.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,8 @@ public class AddedWidgetsAdapter extends @NonNull @NonNull @Override @Override public WidgetsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { public WidgetsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View view = LayoutInflater.from(mContext).inflate(R.layout.item_widget_all, viewGroup, false); View view = LayoutInflater.from(mContext).inflate(R.layout.item_added_widget, viewGroup, false); WidgetsViewHolder widgetsViewHolder = new WidgetsViewHolder(view); WidgetsViewHolder widgetsViewHolder = new WidgetsViewHolder(view); widgetsViewHolder.actionBtn.setImageResource(R.drawable.ic_remove_widget_red_24dp); widgetsViewHolder.actionBtn.setImageResource(R.drawable.ic_remove_widget_red_24dp); widgetsViewHolder.actionBtn.setOnClickListener( widgetsViewHolder.actionBtn.setOnClickListener( Loading Loading @@ -79,7 +80,6 @@ public class AddedWidgetsAdapter extends label = itemView.findViewById(R.id.widget_label); label = itemView.findViewById(R.id.widget_label); actionBtn = itemView.findViewById(R.id.action_image_view); actionBtn = itemView.findViewById(R.id.action_image_view); } } } } interface OnActionClickListener { interface OnActionClickListener { Loading
app/src/main/java/foundation/e/blisslauncher/features/widgets/WidgetPicker.java 0 → 100644 +218 −0 Original line number Original line Diff line number Diff line package foundation.e.blisslauncher.features.widgets; import android.app.Activity; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Parcelable; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.DisplayMetrics; import android.util.Log; import android.widget.Toast; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import foundation.e.blisslauncher.R; public class WidgetPicker extends Activity implements WidgetPickerAdapter.OnClickListener { private static final int REQUEST_BIND_APPWIDGET = 111; private int mAppWidgetId; private AppWidgetManager mAppWidgetManager; private PackageManager mPackageManager; private static final String TAG = "WidgetPicker"; private Intent mBaseIntent; @Override public void onCreate(Bundle savedInstanceState) { mPackageManager = getPackageManager(); mAppWidgetManager = AppWidgetManager.getInstance(this); super.onCreate(savedInstanceState); // Set default return data setResultData(RESULT_CANCELED, null); // Read the appWidgetId passed our direction, otherwise bail if not found final Intent intent = getIntent(); if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } else { finish(); } // Read base intent from extras, otherwise assume default Parcelable parcel = intent.getParcelableExtra(Intent.EXTRA_INTENT); if (parcel instanceof Intent) { mBaseIntent = (Intent) parcel; mBaseIntent.setFlags(mBaseIntent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)); } else { mBaseIntent = new Intent(Intent.ACTION_MAIN, null); mBaseIntent.addCategory(Intent.CATEGORY_DEFAULT); } setContentView(R.layout.activity_widget_picker); RecyclerView recyclerView = findViewById(R.id.all_widgets_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setHasFixedSize(true); recyclerView.addItemDecoration( new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); WidgetPickerAdapter adapter = new WidgetPickerAdapter(this); recyclerView.setAdapter(adapter); List<WidgetPickerAdapter.Item> items = new ArrayList<>(); putInstalledAppWidgets(items); Collections.sort(items, new Comparator<WidgetPickerAdapter.Item>() { Collator mCollator = Collator.getInstance(); public int compare(WidgetPickerAdapter.Item lhs, WidgetPickerAdapter.Item rhs) { return mCollator.compare(lhs.getLabel(), rhs.getLabel()); } }); adapter.setItems(items); } private void putInstalledAppWidgets(List<WidgetPickerAdapter.Item> items) { List<AppWidgetProviderInfo> installed = mAppWidgetManager.getInstalledProviders(); if (installed == null) return; final int size = installed.size(); for (int i = 0; i < size; i++) { AppWidgetProviderInfo info = installed.get(i); items.add(createItem(info)); } } public WidgetPickerAdapter.Item createItem(AppWidgetProviderInfo info) { CharSequence label = info.loadLabel(mPackageManager); Drawable icon = null; if (info.icon != 0) { try { final Resources res = getResources(); final int density = res.getDisplayMetrics().densityDpi; int iconDensity; switch (density) { case DisplayMetrics.DENSITY_MEDIUM: iconDensity = DisplayMetrics.DENSITY_LOW; break; case DisplayMetrics.DENSITY_TV: iconDensity = DisplayMetrics.DENSITY_MEDIUM; break; case DisplayMetrics.DENSITY_HIGH: iconDensity = DisplayMetrics.DENSITY_MEDIUM; break; case DisplayMetrics.DENSITY_XHIGH: iconDensity = DisplayMetrics.DENSITY_HIGH; break; case DisplayMetrics.DENSITY_XXHIGH: iconDensity = DisplayMetrics.DENSITY_XHIGH; break; default: // The density is some abnormal value. Return some other // abnormal value that is a reasonable scaling of it. iconDensity = (int) ((density * 0.75f) + .5f); } Resources packageResources = mPackageManager. getResourcesForApplication(info.provider.getPackageName()); icon = packageResources.getDrawableForDensity(info.icon, iconDensity); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Can't load icon drawable 0x" + Integer.toHexString(info.icon) + " for provider: " + info.provider); } if (icon == null) { Log.w(TAG, "Can't load icon drawable 0x" + Integer.toHexString(info.icon) + " for provider: " + info.provider); } } WidgetPickerAdapter.Item item = new WidgetPickerAdapter.Item(label, icon); item.packageName = info.provider.getPackageName(); item.className = info.provider.getClassName(); item.profile = info.getProfile(); return item; } @Override public void onClick(WidgetPickerAdapter.Item item) { Intent intent = item.getIntent(mBaseIntent); int result = -10; if (item.extras != null) { setResultData(RESULT_OK, intent); } else { try { Bundle options = null; if (intent.getExtras() != null) { options = intent.getExtras().getBundle( AppWidgetManager.EXTRA_APPWIDGET_OPTIONS); } boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(mAppWidgetId, intent.getComponent(), options); if (success) { result = RESULT_OK; } else { Intent permissionIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); permissionIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); permissionIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, new ComponentName(item.packageName, item.className)); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, item.profile); // TODO: we need to make sure that this accounts for the options bundle. // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options); startActivityForResult(permissionIntent, REQUEST_BIND_APPWIDGET); } } catch (IllegalArgumentException e) { result = RESULT_CANCELED; } setResultData(result, null); } finish(); } /** * Convenience method for setting the result code and intent. This method * correctly injects the {@link AppWidgetManager#EXTRA_APPWIDGET_ID} that * most hosts expect returned. */ void setResultData(int code, Intent intent) { Intent result = intent != null ? intent : new Intent(); result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); setResult(code, result); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d(TAG, "onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]"); if (requestCode == REQUEST_BIND_APPWIDGET) { int appWidgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1; if (resultCode == RESULT_OK) { setResultData(RESULT_OK, null); } else { Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show(); setResultData(RESULT_CANCELED, null); } finish(); } else { super.onActivityResult(requestCode, resultCode, data); } } }
app/src/main/java/foundation/e/blisslauncher/features/widgets/WidgetPickerAdapter.java 0 → 100644 +142 −0 Original line number Original line Diff line number Diff line package foundation.e.blisslauncher.features.widgets; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import foundation.e.blisslauncher.R; public class WidgetPickerAdapter extends RecyclerView.Adapter<WidgetPickerAdapter.WidgetsViewHolder> { private Context mContext; private List<Item> mItems = new ArrayList<>(); private OnClickListener mOnClickListener; private static final String TAG = "AddedWidgetsAdapter"; public WidgetPickerAdapter(Context context) { this.mContext = context; mOnClickListener = (OnClickListener) mContext; } @NonNull @Override public WidgetsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View view = LayoutInflater.from(mContext).inflate(R.layout.item_all_widget, viewGroup, false); WidgetsViewHolder widgetsViewHolder = new WidgetsViewHolder(view); widgetsViewHolder.itemView.setOnClickListener(v -> { int position = widgetsViewHolder.getAdapterPosition(); if (position != RecyclerView.NO_POSITION){ mOnClickListener.onClick(mItems.get(position)); } }); return widgetsViewHolder; } @Override public void onBindViewHolder(@NonNull WidgetsViewHolder widgetsViewHolder, int i) { Item info = mItems.get(i); widgetsViewHolder.icon.setImageDrawable(info.icon); widgetsViewHolder.label.setText(info.label); } @Override public int getItemCount() { return mItems.size(); } public void setItems(List<Item> items) { this.mItems = items; notifyDataSetChanged(); } public static class WidgetsViewHolder extends RecyclerView.ViewHolder { ImageView icon; TextView label; public WidgetsViewHolder(@NonNull View itemView) { super(itemView); icon = itemView.findViewById(R.id.widget_icon); label = itemView.findViewById(R.id.widget_label); } } public static class Item { public UserHandle profile; CharSequence label; Drawable icon; String packageName; String className; Bundle extras; /** * Create a list item from given label and icon. */ Item(CharSequence label, Drawable icon) { this.label = label; this.icon = icon; } /** * Create a list item and fill it with details from the given * {@link ResolveInfo} object. */ Item(PackageManager pm, ResolveInfo resolveInfo) { label = resolveInfo.loadLabel(pm); if (label == null && resolveInfo.activityInfo != null) { label = resolveInfo.activityInfo.name; } icon = resolveInfo.loadIcon(pm); packageName = resolveInfo.activityInfo.applicationInfo.packageName; className = resolveInfo.activityInfo.name; } /** * Build the {@link Intent} described by this item. If this item * can't create a valid {@link android.content.ComponentName}, it will return * {@link Intent#ACTION_CREATE_SHORTCUT} filled with the item label. */ Intent getIntent(Intent baseIntent) { Intent intent = new Intent(baseIntent); if (packageName != null && className != null) { // Valid package and class, so fill details as normal intent intent.setClassName(packageName, className); if (extras != null) { intent.putExtras(extras); } } else { // No valid package or class, so treat as shortcut with label intent.setAction(Intent.ACTION_CREATE_SHORTCUT); intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label); } return intent; } public CharSequence getLabel() { return label; } } interface OnClickListener { void onClick(Item item); } }
app/src/main/java/foundation/e/blisslauncher/features/widgets/WidgetsActivity.java +15 −3 Original line number Original line Diff line number Diff line Loading @@ -3,12 +3,14 @@ package foundation.e.blisslauncher.features.widgets; import android.app.Activity; import android.app.Activity; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.appwidget.AppWidgetProviderInfo; import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.Intent; import android.os.Bundle; import android.os.Bundle; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView; import android.util.DisplayMetrics; import android.util.DisplayMetrics; import android.widget.Toast; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; Loading Loading @@ -81,7 +83,7 @@ public class WidgetsActivity extends Activity implements AddedWidgetsAdapter.OnA void selectWidget() { void selectWidget() { int appWidgetId = this.mAppWidgetHost.allocateAppWidgetId(); int appWidgetId = this.mAppWidgetHost.allocateAppWidgetId(); Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK); Intent pickIntent = new Intent(this, WidgetPicker.class); pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); addEmptyData(pickIntent); addEmptyData(pickIntent); startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET); startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET); Loading Loading @@ -117,10 +119,11 @@ public class WidgetsActivity extends Activity implements AddedWidgetsAdapter.OnA int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId); AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId); if (appWidgetInfo != null && appWidgetInfo.configure != null) { if (appWidgetInfo != null && appWidgetInfo.configure != null) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); /*Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); intent.setComponent(appWidgetInfo.configure); intent.setComponent(appWidgetInfo.configure); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); startActivityForResult(intent, REQUEST_CREATE_APPWIDGET); startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);*/ startAppWidgetConfigureActivitySafely(appWidgetId); } else { } else { createWidget(data); createWidget(data); } } Loading @@ -138,4 +141,13 @@ public class WidgetsActivity extends Activity implements AddedWidgetsAdapter.OnA refreshRecyclerView(); refreshRecyclerView(); } } void startAppWidgetConfigureActivitySafely(int appWidgetId) { try { mAppWidgetHost.startAppWidgetConfigureActivityForResult(this, appWidgetId, 0, REQUEST_CREATE_APPWIDGET, null); } catch (ActivityNotFoundException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); } } } }