summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml6
-rw-r--r--res/drawable-hdpi/ic_empty.pngbin0 -> 1364 bytes
-rw-r--r--res/drawable-hdpi/ic_menu_save.pngbin0 -> 3406 bytes
-rw-r--r--res/drawable-hdpi/ic_settings_lockscreen.pngbin0 -> 1370 bytes
-rw-r--r--res/drawable-mdpi/ic_empty.pngbin0 -> 1231 bytes
-rw-r--r--res/drawable-mdpi/ic_menu_save.pngbin0 -> 1416 bytes
-rw-r--r--res/drawable-mdpi/ic_settings_lockscreen.pngbin0 -> 861 bytes
-rw-r--r--res/drawable-xhdpi/ic_empty.pngbin0 -> 1423 bytes
-rw-r--r--res/drawable-xhdpi/ic_menu_save.pngbin0 -> 1777 bytes
-rw-r--r--res/drawable-xhdpi/ic_settings_lockscreen.pngbin0 -> 1851 bytes
-rw-r--r--res/drawable/activities_icon.pngbin0 -> 2938 bytes
-rw-r--r--res/layout-land/lockscreen_targets.xml50
-rw-r--r--res/layout-sw600dp/lockscreen_targets.xml50
-rw-r--r--res/layout/lockscreen_shortcut_dialog.xml32
-rw-r--r--res/layout/lockscreen_targets.xml50
-rwxr-xr-xres/layout/pick_item.xml10
-rw-r--r--res/values/arrays.xml50
-rwxr-xr-xres/values/dimens.xml2
-rw-r--r--res/values/strings.xml46
-rw-r--r--res/xml/lockscreen_interface_settings.xml26
-rw-r--r--res/xml/settings_headers.xml7
-rw-r--r--src/com/android/settings/cyanogenmod/IconPicker.java201
-rw-r--r--src/com/android/settings/cyanogenmod/LockscreenInterface.java53
-rw-r--r--src/com/android/settings/cyanogenmod/LockscreenTargets.java571
-rw-r--r--src/com/android/settings/cyanogenmod/ShortcutPickHelper.java324
25 files changed, 1471 insertions, 7 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index adbd457..b22c96b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1200,7 +1200,7 @@
<activity android:name="ActivityPicker"
android:label="@string/activity_picker_label"
- android:theme="@*android:style/Theme.Dialog.Alert"
+ android:theme="@*android:style/Theme.Holo.Dialog.Alert"
android:finishOnCloseSystemDialogs="true">
<intent-filter>
<action android:name="android.intent.action.PICK_ACTIVITY" />
@@ -1477,6 +1477,10 @@
<activity android:name=".profiles.NFCProfileSelect" />
+ <activity android:name=".cyanogenmod.LockscreenTargets" />
+
+ <activity android:name=".cyanogenmod.LockscreenInterface" />
+
<activity android:name=".cyanogenmod.PowerMenu" />
<activity android:name=".profiles.NFCProfile"
diff --git a/res/drawable-hdpi/ic_empty.png b/res/drawable-hdpi/ic_empty.png
new file mode 100644
index 0000000..a45c6cf
--- /dev/null
+++ b/res/drawable-hdpi/ic_empty.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_save.png b/res/drawable-hdpi/ic_menu_save.png
new file mode 100644
index 0000000..2b29557
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_save.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_settings_lockscreen.png b/res/drawable-hdpi/ic_settings_lockscreen.png
new file mode 100644
index 0000000..a08d513
--- /dev/null
+++ b/res/drawable-hdpi/ic_settings_lockscreen.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_empty.png b/res/drawable-mdpi/ic_empty.png
new file mode 100644
index 0000000..ede2c83
--- /dev/null
+++ b/res/drawable-mdpi/ic_empty.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_save.png b/res/drawable-mdpi/ic_menu_save.png
new file mode 100644
index 0000000..283be30
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_save.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_settings_lockscreen.png b/res/drawable-mdpi/ic_settings_lockscreen.png
new file mode 100644
index 0000000..ac18347
--- /dev/null
+++ b/res/drawable-mdpi/ic_settings_lockscreen.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_empty.png b/res/drawable-xhdpi/ic_empty.png
new file mode 100644
index 0000000..5742d13
--- /dev/null
+++ b/res/drawable-xhdpi/ic_empty.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_save.png b/res/drawable-xhdpi/ic_menu_save.png
new file mode 100644
index 0000000..c403206
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_save.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_settings_lockscreen.png b/res/drawable-xhdpi/ic_settings_lockscreen.png
new file mode 100644
index 0000000..f669da1
--- /dev/null
+++ b/res/drawable-xhdpi/ic_settings_lockscreen.png
Binary files differ
diff --git a/res/drawable/activities_icon.png b/res/drawable/activities_icon.png
new file mode 100644
index 0000000..abd62e2
--- /dev/null
+++ b/res/drawable/activities_icon.png
Binary files differ
diff --git a/res/layout-land/lockscreen_targets.xml b/res/layout-land/lockscreen_targets.xml
new file mode 100644
index 0000000..22f0d4a
--- /dev/null
+++ b/res/layout-land/lockscreen_targets.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/holo_blue_light"
+ android:layout_marginRight="8dip"
+ android:layout_marginLeft="8dip"
+ android:padding="4dip"
+ android:gravity="center_horizontal"
+ android:textColor="#FFFFFF"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/lockscreen_target_info" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <com.android.internal.widget.multiwaveview.GlowPadView
+ android:id="@+id/lock_target"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="horizontal"
+ android:gravity="@*android:integer/kg_selector_gravity"
+ android:contentDescription="@*android:string/keyguard_accessibility_slide_area"
+ prvandroid:targetDrawables="@*android:array/lockscreen_targets_unlock_only"
+ prvandroid:targetDescriptions="@*android:array/lockscreen_target_descriptions_unlock_only"
+ prvandroid:directionDescriptions="@*android:array/lockscreen_direction_descriptions"
+ prvandroid:handleDrawable="@*android:drawable/ic_lockscreen_handle"
+ prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring"
+ prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius"
+ prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+ prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin"
+ prvandroid:firstItemOffset="@*android:integer/kg_glowpad_rotation_offset"
+ prvandroid:magneticTargets="false"
+ prvandroid:feedbackCount="1"
+ prvandroid:vibrationDuration="20"
+ prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
+ prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+ prvandroid:allowScaling="true" />
+
+</LinearLayout>
diff --git a/res/layout-sw600dp/lockscreen_targets.xml b/res/layout-sw600dp/lockscreen_targets.xml
new file mode 100644
index 0000000..22f0d4a
--- /dev/null
+++ b/res/layout-sw600dp/lockscreen_targets.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/holo_blue_light"
+ android:layout_marginRight="8dip"
+ android:layout_marginLeft="8dip"
+ android:padding="4dip"
+ android:gravity="center_horizontal"
+ android:textColor="#FFFFFF"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/lockscreen_target_info" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <com.android.internal.widget.multiwaveview.GlowPadView
+ android:id="@+id/lock_target"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="horizontal"
+ android:gravity="@*android:integer/kg_selector_gravity"
+ android:contentDescription="@*android:string/keyguard_accessibility_slide_area"
+ prvandroid:targetDrawables="@*android:array/lockscreen_targets_unlock_only"
+ prvandroid:targetDescriptions="@*android:array/lockscreen_target_descriptions_unlock_only"
+ prvandroid:directionDescriptions="@*android:array/lockscreen_direction_descriptions"
+ prvandroid:handleDrawable="@*android:drawable/ic_lockscreen_handle"
+ prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring"
+ prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius"
+ prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+ prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin"
+ prvandroid:firstItemOffset="@*android:integer/kg_glowpad_rotation_offset"
+ prvandroid:magneticTargets="false"
+ prvandroid:feedbackCount="1"
+ prvandroid:vibrationDuration="20"
+ prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
+ prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+ prvandroid:allowScaling="true" />
+
+</LinearLayout>
diff --git a/res/layout/lockscreen_shortcut_dialog.xml b/res/layout/lockscreen_shortcut_dialog.xml
new file mode 100644
index 0000000..638af0f
--- /dev/null
+++ b/res/layout/lockscreen_shortcut_dialog.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:layout_height="wrap_content"
+ android:paddingBottom="5dp"
+ android:paddingLeft="8dp"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+ <ImageButton
+ android:padding="5dp"
+ android:layout_width="@android:dimen/app_icon_size"
+ style="?android:attr/borderlessButtonStyle"
+ android:id="@+id/icon"
+ android:layout_height="@android:dimen/app_icon_size" />
+ <View
+ android:layout_width="2dp"
+ android:layout_height="match_parent"
+ android:layout_marginTop="5dp"
+ android:layout_marginBottom="5dp"
+ android:layout_marginRight="5dp"
+ android:layout_marginLeft="5dp"
+ android:background="@android:drawable/divider_horizontal_dark" />
+ <Button
+ android:layout_width="match_parent"
+ style="?android:attr/borderlessButtonStyle"
+ android:gravity="left|center_vertical"
+ android:paddingLeft="5dp"
+ android:layout_height="wrap_content"
+ android:id="@+id/label" />
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/lockscreen_targets.xml b/res/layout/lockscreen_targets.xml
new file mode 100644
index 0000000..cff327c
--- /dev/null
+++ b/res/layout/lockscreen_targets.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/holo_blue_light"
+ android:layout_marginRight="8dip"
+ android:layout_marginLeft="8dip"
+ android:padding="4dip"
+ android:gravity="center_horizontal"
+ android:textColor="#FFFFFF"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/lockscreen_target_info" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.4" />
+
+ <com.android.internal.widget.multiwaveview.GlowPadView
+ android:id="@+id/lock_target"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.6"
+ android:orientation="horizontal"
+ android:gravity="top"
+ android:contentDescription="@*android:string/keyguard_accessibility_slide_area"
+ prvandroid:targetDrawables="@*android:array/lockscreen_targets_unlock_only"
+ prvandroid:targetDescriptions="@*android:array/lockscreen_target_descriptions_unlock_only"
+ prvandroid:directionDescriptions="@*android:array/lockscreen_direction_descriptions"
+ prvandroid:handleDrawable="@*android:drawable/ic_lockscreen_handle"
+ prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring"
+ prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius"
+ prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+ prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin"
+ prvandroid:firstItemOffset="@*android:integer/kg_glowpad_rotation_offset"
+ prvandroid:magneticTargets="false"
+ prvandroid:feedbackCount="1"
+ prvandroid:vibrationDuration="20"
+ prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
+ prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+ prvandroid:allowScaling="true" />
+
+</LinearLayout>
diff --git a/res/layout/pick_item.xml b/res/layout/pick_item.xml
index d85edc4..e937d7b 100755
--- a/res/layout/pick_item.xml
+++ b/res/layout/pick_item.xml
@@ -17,9 +17,9 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:textAppearance="?android:attr/textAppearanceMedium"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center_vertical"
- android:drawablePadding="8dip"
- android:paddingStart="11dip"
- android:paddingEnd="11dip" />
+ android:drawablePadding="14dip"
+ android:paddingLeft="15dip"
+ android:paddingRight="15dip" />
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 2935cbf..bc222ad 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -847,6 +847,56 @@
<item>2</item>
</string-array>
+ <string-array name="lockscreen_icon_picker_labels" translatable="false">
+ <item>@string/icon_picker_alarm</item>
+ <item>@string/icon_picker_browser</item>
+ <item>@string/icon_picker_calendar</item>
+ <item>@string/icon_picker_camera</item>
+ <item>@string/icon_picker_chrome</item>
+ <item>@string/icon_picker_email</item>
+ <item>@string/icon_picker_email2</item>
+ <item>@string/icon_picker_facebook</item>
+ <item>@string/icon_picker_gallery</item>
+ <item>@string/icon_picker_google_small</item>
+ <item>@string/icon_picker_googleplus</item>
+ <item>@string/icon_picker_googletalk</item>
+ <item>@string/icon_picker_maps</item>
+ <item>@string/icon_picker_sms</item>
+ <item>@string/icon_picker_movie</item>
+ <item>@string/icon_picker_music</item>
+ <item>@string/icon_picker_nav_normal</item>
+ <item>@string/icon_picker_phone</item>
+ <item>@string/icon_picker_podcast</item>
+ <item>@string/icon_picker_rss</item>
+ <item>@string/icon_picker_search</item>
+ <item>@string/icon_picker_twitter</item>
+ </string-array>
+
+ <string-array name="lockscreen_icon_picker_icons" translatable="false">
+ <item>@*android:drawable/ic_lockscreen_alarm_normal</item>
+ <item>@*android:drawable/ic_lockscreen_browser_normal</item>
+ <item>@*android:drawable/ic_lockscreen_calendar_normal</item>
+ <item>@*android:drawable/ic_lockscreen_camera_normal</item>
+ <item>@*android:drawable/ic_lockscreen_chrome_normal</item>
+ <item>@*android:drawable/ic_lockscreen_email_normal</item>
+ <item>@*android:drawable/ic_lockscreen_email2_normal</item>
+ <item>@*android:drawable/ic_lockscreen_facebook_normal</item>
+ <item>@*android:drawable/ic_lockscreen_gallery_normal</item>
+ <item>@*android:drawable/ic_lockscreen_google_small_normal</item>
+ <item>@*android:drawable/ic_lockscreen_gplus_normal</item>
+ <item>@*android:drawable/ic_lockscreen_gtalk_normal</item>
+ <item>@*android:drawable/ic_lockscreen_maps_normal</item>
+ <item>@*android:drawable/ic_lockscreen_sms_normal</item>
+ <item>@*android:drawable/ic_lockscreen_movie_normal</item>
+ <item>@*android:drawable/ic_lockscreen_music_normal</item>
+ <item>@*android:drawable/ic_lockscreen_nav_normal</item>
+ <item>@*android:drawable/ic_lockscreen_phone_normal</item>
+ <item>@*android:drawable/ic_lockscreen_podcast_normal</item>
+ <item>@*android:drawable/ic_lockscreen_rss_normal</item>
+ <item>@*android:drawable/ic_lockscreen_google_normal</item>
+ <item>@*android:drawable/ic_lockscreen_twitter_normal</item>
+ </string-array>
+
<!-- Profile mode options. -->
<string-array name="profile_entries">
<item>On</item>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index cbc9b6d..2f0f859 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -31,7 +31,7 @@
<dimen name="data_usage_chart_height">252dip</dimen>
<dimen name="data_usage_chart_optimalWidth">440dip</dimen>
-
+ <dimen name="shortcut_picker_left_padding">70dip</dimen>
<dimen name="volume_seekbar_side_margin">8dip</dimen>
<dimen name="crypt_clock_size">100sp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 24af239..0179aaf 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4496,6 +4496,18 @@
<string name="lock_screen_title">Lock screen</string>
+ <!-- Lock Screen Shortcuts -->
+ <string name="lockscreen_target_info">Drag the slider to targets to assign shortcuts</string>
+ <string name="lockscreen_target_title">Slider shortcuts</string>
+ <string name="lockscreen_target_summary">View or change custom lock screen shortcuts</string>
+ <string name="lockscreen_target_reset">Lock screen shortcuts reset to default</string>
+ <string name="lockscreen_target_save">Lock screen shortcuts saved</string>
+ <string name="lockscreen_target_reset_title">Reset</string>
+ <string name="lockscreen_target_reset_message">Delete all user created lock screen shortcuts and restore to default?</string>
+ <string name="lockscreen_target_empty">Empty</string>
+ <string name="lockscreen_target_edit_title">Edit shortcut and icon</string>
+ <string name="lockscreen_target_edit_msg">Select or change the desired application or activity and the associated icon</string>
+
<!-- Profiles settings -->
<string name="profiles_settings_title">Profiles</string>
<string name="profiles_general_title">General</string>
@@ -4684,6 +4696,40 @@
<string name="display_rotation_180_title">180 degrees</string>
<string name="display_rotation_270_title">270 degrees</string>
+ <!-- Lock screen shortcuts -->
+ <string name="picker_activities">Activities</string>
+ <string name="select_custom_app_title">Select custom application</string>
+ <string name="select_custom_activity_title">Select custom activity</string>
+ <string name="icon_picker_choose_icon_title">Choose icon</string>
+ <string name="icon_picker_alarm">Alarm</string>
+ <string name="icon_picker_browser">Browser</string>
+ <string name="icon_picker_calendar">Calendar</string>
+ <string name="icon_picker_camera">Camera</string>
+ <string name="icon_picker_chrome">Chrome</string>
+ <string name="icon_picker_email">Email</string>
+ <string name="icon_picker_email2">Email Holo</string>
+ <string name="icon_picker_facebook">Facebook</string>
+ <string name="icon_picker_gallery">Gallery</string>
+ <string name="icon_picker_google_small">Google (small)</string>
+ <string name="icon_picker_googleplus">Google Plus</string>
+ <string name="icon_picker_googletalk">Google Talk</string>
+ <string name="icon_picker_maps">Maps</string>
+ <string name="icon_picker_movie">Movie</string>
+ <string name="icon_picker_music">Music</string>
+ <string name="icon_picker_nav_normal">Navigation</string>
+ <string name="icon_picker_phone">Phone</string>
+ <string name="icon_picker_podcast">Podcast</string>
+ <string name="icon_picker_rss">Rss</string>
+ <string name="icon_picker_search">Search</string>
+ <string name="icon_picker_sms">Messaging</string>
+ <string name="icon_picker_twitter">Twitter</string>
+
+ <!-- String for IconPicker -->
+ <string name="icon_picker_title">Choose icon source</string>
+ <string name="icon_picker_system_icons_title">System icons</string>
+ <string name="icon_picker_gallery_title">Gallery</string>
+ <string name="icon_picker_pack_title">Icon pack</string>
+
<string name="increasing_ring_title">Ascending ringtone</string>
<!-- Sound settings screen, the caption of the checkbox for making incoming calls increase in volume -->
<string name="checkbox_increasing_ring">Enable</string>
diff --git a/res/xml/lockscreen_interface_settings.xml b/res/xml/lockscreen_interface_settings.xml
new file mode 100644
index 0000000..1142264
--- /dev/null
+++ b/res/xml/lockscreen_interface_settings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The CyanogenMod Project
+
+ 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.
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
+ android:title="@string/themes_settings_title" >
+
+ <Preference
+ android:fragment="com.android.settings.cyanogenmod.LockscreenTargets"
+ android:key="lockscreen_targets"
+ android:summary="@string/lockscreen_target_summary"
+ android:title="@string/lockscreen_target_title" />
+
+</PreferenceScreen>
diff --git a/res/xml/settings_headers.xml b/res/xml/settings_headers.xml
index 05cc2be..5f1fd54 100644
--- a/res/xml/settings_headers.xml
+++ b/res/xml/settings_headers.xml
@@ -67,6 +67,13 @@
android:title="@string/launcher_settings_title"
android:icon="@drawable/ic_settings_cmlauncher" />
+ <!-- Lock screen -->
+ <header
+ android:id="@+id/lock_screen_settings"
+ android:fragment="com.android.settings.cyanogenmod.LockscreenInterface"
+ android:title="@string/lock_screen_title"
+ android:icon="@drawable/ic_settings_lockscreen" />
+
<!-- Themes -->
<header
android:id="@+id/themes_settings"
diff --git a/src/com/android/settings/cyanogenmod/IconPicker.java b/src/com/android/settings/cyanogenmod/IconPicker.java
new file mode 100644
index 0000000..386468a
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/IconPicker.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod Project
+ *
+ * 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.android.settings.cyanogenmod;
+
+import java.io.File;
+import java.util.ArrayList;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.Fragment;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.settings.R;
+
+public class IconPicker {
+
+ private Activity mParent;
+ private Resources mResources;
+ private OnIconPickListener mIconListener;
+ private static final String ICON_ACTION = "com.cyanogenmod.ACTION_PICK_ICON";
+ public static final String RESOURCE_NAME = "resource_name";
+ public static final String PACKAGE_NAME = "package_name";
+ public static final int REQUEST_PICK_SYSTEM = 0;
+ public static final int REQUEST_PICK_GALLERY = 1;
+ public static final int REQUEST_PICK_ICON_PACK = 2;
+
+ public interface OnIconPickListener {
+ void iconPicked(int requestCode, int resultCode, Intent in);
+ }
+
+ public IconPicker(Activity parent, OnIconPickListener listener) {
+ mParent = parent;
+ mResources = parent.getResources();
+ mIconListener = listener;
+ }
+
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ mIconListener.iconPicked(requestCode, resultCode, data);
+ }
+
+ public void pickIcon(final int fragmentId, final File image) {
+ Intent iconPack = new Intent(ICON_ACTION);
+ ArrayList<String> items = new ArrayList<String>();
+ items.add(mResources.getString(R.string.icon_picker_system_icons_title));
+ items.add(mResources.getString(R.string.icon_picker_gallery_title));
+ ComponentName aInfo = iconPack.resolveActivity(mParent.getPackageManager());
+ if (aInfo != null) {
+ items.add(mResources.getString(R.string.icon_picker_pack_title));
+ }
+ new AlertDialog.Builder(mParent)
+ .setTitle(R.string.icon_picker_title)
+ .setItems(items.toArray(new String[items.size()]), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ showChosen(item, image, fragmentId);
+ }
+ }).show();
+ }
+
+ private void startFragmentOrActivityForResult(Intent pickIntent, int requestCode, int fragmentId) {
+ if (fragmentId == 0) {
+ mParent.startActivityForResult(pickIntent, requestCode);
+ } else {
+ Fragment cFrag = mParent.getFragmentManager().findFragmentById(fragmentId);
+ if (cFrag != null) {
+ mParent.startActivityFromFragment(cFrag, pickIntent, requestCode);
+ }
+ }
+ }
+
+ private void showChosen(final int type, File image, int fragmentId) {
+ if (type == REQUEST_PICK_SYSTEM) {
+ ListView listie = new ListView(mParent);
+ listie.setAdapter(new IconAdapter());
+ final Dialog dialog = new Dialog(mParent);
+ dialog.setTitle(R.string.icon_picker_choose_icon_title);
+ dialog.setContentView(listie);
+ listie.setOnItemClickListener(new OnItemClickListener(){
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view,
+ int position, long id) {
+ Intent in = new Intent();
+ in.putExtra("resource_name", ((IconAdapter) parent.getAdapter()).getItemReference(position));
+ mIconListener.iconPicked(type, Activity.RESULT_OK, in);
+ dialog.dismiss();
+ }
+ });
+ dialog.show();
+ } else if (type == REQUEST_PICK_GALLERY) {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
+ intent.setType("image/*");
+ intent.putExtra("crop", "true");
+ intent.putExtra("scale", true);
+ intent.putExtra("scaleUpIfNeeded", false);
+ intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
+ intent.putExtra("aspectX", 1);
+ intent.putExtra("aspectY", 1);
+ intent.putExtra("outputX", 162);
+ intent.putExtra("outputY", 162);
+ try {
+ intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(image));
+ intent.putExtra("return-data", false);
+ startFragmentOrActivityForResult(intent, type, fragmentId);
+ } catch (ActivityNotFoundException e) {
+ e.printStackTrace();
+ }
+ } else if (type == REQUEST_PICK_ICON_PACK) {
+ Intent iconPack = new Intent(ICON_ACTION);
+ startFragmentOrActivityForResult(iconPack, type, fragmentId);
+ }
+ }
+
+ class IconAdapter extends BaseAdapter {
+
+ String[] labels;
+ TypedArray icons;
+
+ public IconAdapter() {
+ labels = mResources.getStringArray(R.array.lockscreen_icon_picker_labels);
+ icons = mResources.obtainTypedArray(R.array.lockscreen_icon_picker_icons);
+ }
+
+ @Override
+ public int getCount() {
+ return labels.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return icons.getDrawable(position);
+ }
+
+ public String getItemReference(int position) {
+ String name = icons.getString(position);
+ int separatorIndex = name.lastIndexOf(File.separator);
+ int periodIndex = name.lastIndexOf('.');
+ return name.substring(separatorIndex + 1, periodIndex);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View iView = convertView;
+ if (convertView == null) {
+ iView = View.inflate(mParent, android.R.layout.simple_list_item_1, null);
+ }
+ TextView tt = (TextView) iView.findViewById(android.R.id.text1);
+ tt.setText(labels[position]);
+ Drawable ic = ((Drawable) getItem(position)).mutate();
+ int bound = mParent.getResources().getDimensionPixelSize(R.dimen.shortcut_picker_left_padding);
+ ic.setBounds(0, 0, bound, bound);
+ tt.setCompoundDrawables(ic, null, null, null);
+ return iView;
+ }
+
+ }
+
+ class IconItem {
+ String label;
+ int id;
+ IconItem(String l, int i) {
+ label = l;
+ id = i;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/com/android/settings/cyanogenmod/LockscreenInterface.java b/src/com/android/settings/cyanogenmod/LockscreenInterface.java
new file mode 100644
index 0000000..1a13e04
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/LockscreenInterface.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.android.settings.cyanogenmod;
+
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
+public class LockscreenInterface extends SettingsPreferenceFragment {
+ private static final String TAG = "LockscreenInterface";
+
+ public boolean hasButtons() {
+ return !getResources().getBoolean(com.android.internal.R.bool.config_showNavigationBar);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.lockscreen_interface_settings);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
+ }
+}
diff --git a/src/com/android/settings/cyanogenmod/LockscreenTargets.java b/src/com/android/settings/cyanogenmod/LockscreenTargets.java
new file mode 100644
index 0000000..b788030
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/LockscreenTargets.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod Project
+ *
+ * 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.android.settings.cyanogenmod;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.Intent.ShortcutIconResource;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.StateListDrawable;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.internal.widget.multiwaveview.GlowPadView;
+import com.android.internal.widget.multiwaveview.TargetDrawable;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.cyanogenmod.IconPicker.OnIconPickListener;
+
+public class LockscreenTargets extends Fragment implements ShortcutPickHelper.OnPickListener,
+ GlowPadView.OnTriggerListener, OnIconPickListener {
+
+ private GlowPadView mWaveView;
+ private ImageButton mDialogIcon;
+ private Button mDialogLabel;
+ private ShortcutPickHelper mPicker;
+ private IconPicker mIconPicker;
+ private ArrayList<TargetInfo> mTargetStore = new ArrayList<TargetInfo>();
+ private int mTargetOffset;
+ private int mTargetInset;
+ private boolean mIsLandscape;
+ private boolean mIsScreenLarge;
+ private ViewGroup mContainer;
+ private Activity mActivity;
+ private Resources mResources;
+ private File mImageTmp;
+ private int mTargetIndex = 0;
+ private static final int MENU_RESET = Menu.FIRST;
+ private static final int MENU_SAVE = Menu.FIRST + 1;
+ private static String EMPTY_LABEL;
+
+ class TargetInfo {
+ String uri, pkgName;
+ StateListDrawable icon;
+ Drawable defaultIcon;
+ String iconType;
+ String iconSource;
+ TargetInfo(StateListDrawable target) {
+ icon = target;
+ }
+ TargetInfo(String in, StateListDrawable target, String iType, String iSource, Drawable dI) {
+ uri = in;
+ icon = target;
+ defaultIcon = dI;
+ iconType = iType;
+ iconSource = iSource;
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mContainer = container;
+ setHasOptionsMenu(true);
+ mActivity = getActivity();
+ mIsScreenLarge = !Utils.isPhone(mActivity);
+ mResources = getResources();
+ mIsLandscape = mResources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
+ mTargetOffset = mIsLandscape && !mIsScreenLarge ? 2 : 0;
+ mTargetInset = mResources.getDimensionPixelSize(com.android.internal.R.dimen.lockscreen_target_inset);
+ mIconPicker = new IconPicker(mActivity, this);
+ mPicker = new ShortcutPickHelper(mActivity, this);
+ mImageTmp = new File(mActivity.getCacheDir() + "/target.tmp");
+ EMPTY_LABEL = mActivity.getResources().getString(R.string.lockscreen_target_empty);
+ return inflater.inflate(R.layout.lockscreen_targets, container, false);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ mWaveView = ((GlowPadView) mActivity.findViewById(R.id.lock_target));
+ mWaveView.setOnTriggerListener(this);
+ initializeView(Settings.System.getString(mActivity.getContentResolver(), Settings.System.LOCKSCREEN_TARGETS));
+ }
+
+ /**
+ * Create a layered drawable
+ * @param back - Background image to use when target is active
+ * @param front - Front image to use for target
+ * @param inset - Target inset padding
+ * @param frontBlank - Whether the front image for active target should be blank
+ * @return StateListDrawable
+ */
+ private StateListDrawable getLayeredDrawable(Drawable back, Drawable front, int inset, boolean frontBlank) {
+ front.mutate();
+ back.mutate();
+ InsetDrawable[] inactivelayer = new InsetDrawable[2];
+ InsetDrawable[] activelayer = new InsetDrawable[2];
+ Drawable activeFront = frontBlank ? mResources.getDrawable(android.R.color.transparent) : front;
+ Drawable inactiveBack = mResources.getDrawable(com.android.internal.R.drawable.ic_lockscreen_lock_pressed);
+ inactivelayer[0] = new InsetDrawable(inactiveBack, 0, 0, 0, 0);
+ inactivelayer[1] = new InsetDrawable(front, inset, inset, inset, inset);
+ activelayer[0] = new InsetDrawable(back, 0, 0, 0, 0);
+ activelayer[1] = new InsetDrawable(activeFront, inset, inset, inset, inset);
+ StateListDrawable states = new StateListDrawable();
+ LayerDrawable inactiveLayerDrawable = new LayerDrawable(inactivelayer);
+ inactiveLayerDrawable.setId(0, 0);
+ inactiveLayerDrawable.setId(1, 1);
+ LayerDrawable activeLayerDrawable = new LayerDrawable(activelayer);
+ activeLayerDrawable.setId(0, 0);
+ activeLayerDrawable.setId(1, 1);
+ states.addState(TargetDrawable.STATE_INACTIVE, inactiveLayerDrawable);
+ states.addState(TargetDrawable.STATE_ACTIVE, activeLayerDrawable);
+ states.addState(TargetDrawable.STATE_FOCUSED, activeLayerDrawable);
+ return states;
+ }
+
+ private void initializeView(String input) {
+ if (input == null) {
+ input = GlowPadView.EMPTY_TARGET;
+ }
+ mTargetStore.clear();
+ final int maxTargets = mIsScreenLarge ? GlowPadView.MAX_TABLET_TARGETS : GlowPadView.MAX_PHONE_TARGETS;
+ final PackageManager packMan = mActivity.getPackageManager();
+ final Drawable activeBack = mResources.getDrawable(com.android.internal.R.drawable.ic_lockscreen_target_activated);
+ final String[] targetStore = input.split("\\|");
+ //Shift by 2 targets for phones in landscape
+ if (mIsLandscape && !mIsScreenLarge) {
+ mTargetStore.add(new TargetInfo(null));
+ mTargetStore.add(new TargetInfo(null));
+ }
+ //Add the unlock icon
+ Drawable unlockFront = mResources.getDrawable(com.android.internal.R.drawable.ic_lockscreen_unlock_normal);
+ Drawable unlockBack = mResources.getDrawable(com.android.internal.R.drawable.ic_lockscreen_unlock_activated);
+ mTargetStore.add(new TargetInfo(getLayeredDrawable(unlockBack, unlockFront, 0, true)));
+ for (int cc = 0; cc < 8 - mTargetOffset - 1; cc++) {
+ String uri = GlowPadView.EMPTY_TARGET;
+ Drawable front = null;
+ Drawable back = activeBack;
+ boolean frontBlank = false;
+ String iconType = null;
+ String iconSource = null;
+ int tmpInset = mTargetInset;
+ if (cc < targetStore.length && cc < maxTargets) {
+ uri = targetStore[cc];
+ if (!uri.equals(GlowPadView.EMPTY_TARGET)) {
+ try {
+ Intent in = Intent.parseUri(uri, 0);
+ if (in.hasExtra(GlowPadView.ICON_FILE)) {
+ String rSource = in.getStringExtra(GlowPadView.ICON_FILE);
+ File fPath = new File(rSource);
+ if (fPath != null) {
+ if (fPath.exists()) {
+ front = new BitmapDrawable(getResources(), BitmapFactory.decodeFile(rSource));
+ }
+ }
+ } else if (in.hasExtra(GlowPadView.ICON_RESOURCE)) {
+ String rSource = in.getStringExtra(GlowPadView.ICON_RESOURCE);
+ String rPackage = in.getStringExtra(GlowPadView.ICON_PACKAGE);
+ if (rSource != null) {
+ if (rPackage != null) {
+ try {
+ Context rContext = mActivity.createPackageContext(rPackage, 0);
+ int id = rContext.getResources().getIdentifier(rSource, "drawable", rPackage);
+ front = rContext.getResources().getDrawable(id);
+ id = rContext.getResources().getIdentifier(rSource.replaceAll("_normal", "_activated"),
+ "drawable", rPackage);
+ back = rContext.getResources().getDrawable(id);
+ tmpInset = 0;
+ frontBlank = true;
+ } catch (NameNotFoundException e) {
+ e.printStackTrace();
+ } catch (NotFoundException e) {
+ e.printStackTrace();
+ }
+ } else {
+ front = mResources.getDrawable(mResources.getIdentifier(rSource, "drawable", "android"));
+ back = mResources.getDrawable(mResources.getIdentifier(
+ rSource.replaceAll("_normal", "_activated"), "drawable", "android"));
+ tmpInset = 0;
+ frontBlank = true;
+ }
+ }
+ }
+ if (front == null) {
+ ActivityInfo aInfo = in.resolveActivityInfo(packMan, PackageManager.GET_ACTIVITIES);
+ if (aInfo != null) {
+ front = aInfo.loadIcon(packMan);
+ } else {
+ front = mResources.getDrawable(android.R.drawable.sym_def_app_icon).mutate();
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+ } else if (cc >= maxTargets) {
+ mTargetStore.add(new TargetInfo(null));
+ continue;
+ }
+ if (back == null || front == null) {
+ Drawable emptyIcon = mResources.getDrawable(R.drawable.ic_empty).mutate();
+ front = emptyIcon;
+ }
+ mTargetStore.add(new TargetInfo(uri, getLayeredDrawable(back,front, tmpInset, frontBlank), iconType,
+ iconSource, front.getConstantState().newDrawable().mutate()));
+ }
+ ArrayList<TargetDrawable> tDraw = new ArrayList<TargetDrawable>();
+ for (TargetInfo i : mTargetStore) {
+ if (i != null) {
+ tDraw.add(new TargetDrawable(mResources, i.icon));
+ } else {
+ tDraw.add(new TargetDrawable(mResources, null));
+ }
+ }
+ mWaveView.setTargetResources(tDraw);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // If running on a phone, remove padding around container
+ if (!mIsScreenLarge) {
+ mContainer.setPadding(0, 0, 0, 0);
+ }
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ menu.add(0, MENU_RESET, 0, R.string.profile_reset_title)
+ .setIcon(R.drawable.ic_settings_backup) // use the backup icon
+ .setAlphabeticShortcut('r')
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
+ MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ menu.add(0, MENU_SAVE, 0, R.string.wifi_save)
+ .setIcon(R.drawable.ic_menu_save)
+ .setAlphabeticShortcut('s')
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
+ MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_RESET:
+ resetAll();
+ return true;
+ case MENU_SAVE:
+ saveAll();
+ Toast.makeText(mActivity, R.string.lockscreen_target_save, Toast.LENGTH_LONG).show();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Resets the target layout to stock
+ */
+ private void resetAll() {
+ new AlertDialog.Builder(mActivity)
+ .setTitle(R.string.lockscreen_target_reset_title)
+ .setIconAttribute(android.R.attr.alertDialogIcon)
+ .setMessage(R.string.lockscreen_target_reset_message)
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ initializeView(GlowPadView.EMPTY_TARGET);
+ saveAll();
+ Toast.makeText(mActivity, R.string.lockscreen_target_reset, Toast.LENGTH_LONG).show();
+ }
+ }).setNegativeButton(R.string.cancel, null)
+ .create().show();
+ }
+
+ /**
+ * Save targets to settings provider
+ */
+ private void saveAll() {
+ StringBuilder targetLayout = new StringBuilder();
+ ArrayList<String> existingImages = new ArrayList<String>();
+ final int maxTargets = mIsScreenLarge ? GlowPadView.MAX_TABLET_TARGETS : GlowPadView.MAX_PHONE_TARGETS;
+ for (int i = mTargetOffset + 1; i <= mTargetOffset + maxTargets; i++) {
+ String uri = mTargetStore.get(i).uri;
+ String type = mTargetStore.get(i).iconType;
+ String source = mTargetStore.get(i).iconSource;
+ existingImages.add(source);
+ if (!uri.equals(GlowPadView.EMPTY_TARGET) && type != null) {
+ try {
+ Intent in = Intent.parseUri(uri, 0);
+ in.putExtra(type, source);
+ String pkgName = mTargetStore.get(i).pkgName;
+ if (pkgName != null) {
+ in.putExtra(GlowPadView.ICON_PACKAGE, mTargetStore.get(i).pkgName);
+ } else {
+ in.removeExtra(GlowPadView.ICON_PACKAGE);
+ }
+ uri = in.toUri(0);
+ } catch (URISyntaxException e) {
+ }
+ }
+ targetLayout.append(uri);
+ targetLayout.append("|");
+ }
+ targetLayout.deleteCharAt(targetLayout.length() - 1);
+ Settings.System.putString(mActivity.getContentResolver(), Settings.System.LOCKSCREEN_TARGETS, targetLayout.toString());
+ for (File pic : mActivity.getFilesDir().listFiles()) {
+ if (pic.getName().startsWith("lockscreen_") && !existingImages.contains(pic.toString())) {
+ pic.delete();
+ }
+ }
+ }
+
+ /**
+ * Updates a target in the GlowPadView
+ */
+ private void setTarget(int position, String uri, Drawable draw, String iconType, String iconSource, String pkgName) {
+ TargetInfo item = mTargetStore.get(position);
+ StateListDrawable state = (StateListDrawable) item.icon;
+ LayerDrawable inActiveLayer = (LayerDrawable) state.getStateDrawable(0);
+ LayerDrawable activeLayer = (LayerDrawable) state.getStateDrawable(1);
+ inActiveLayer.setDrawableByLayerId(1, draw);
+ boolean isSystem = iconType != null && iconType.equals(GlowPadView.ICON_RESOURCE);
+ if (!isSystem) {
+ final Drawable activeBack = mResources.getDrawable(com.android.internal.R.drawable.ic_lockscreen_target_activated);
+ activeLayer.setDrawableByLayerId(0, new InsetDrawable(activeBack, 0, 0, 0, 0));
+ activeLayer.setDrawableByLayerId(1, draw);
+ } else {
+ InsetDrawable empty = new InsetDrawable(mResources.getDrawable(android.R.color.transparent), 0, 0, 0, 0);
+ activeLayer.setDrawableByLayerId(1, empty);
+ int activeId = mResources.getIdentifier(iconSource.replaceAll("_normal", "_activated"), "drawable", "android");
+ Drawable back = null;
+ if (activeId != 0) {
+ back = mResources.getDrawable(activeId);
+ activeLayer.setDrawableByLayerId(0, back);
+ } else {
+ final Drawable activeBack = mResources.getDrawable(com.android.internal.R.drawable.ic_lockscreen_target_activated);
+ activeLayer.setDrawableByLayerId(0, new InsetDrawable(activeBack, 0, 0, 0, 0));
+ }
+ }
+ item.defaultIcon = mDialogIcon.getDrawable().getConstantState().newDrawable().mutate();
+ item.uri = uri;
+ item.iconType = iconType;
+ item.iconSource = iconSource;
+ item.pkgName = pkgName;
+ }
+
+ @Override
+ public void shortcutPicked(String uri, String friendlyName, boolean isApplication) {
+ try {
+ Intent i = Intent.parseUri(uri, 0);
+ PackageManager pm = mActivity.getPackageManager();
+ ActivityInfo aInfo = i.resolveActivityInfo(pm, PackageManager.GET_ACTIVITIES);
+ Drawable icon = null;
+ if (aInfo != null) {
+ icon = aInfo.loadIcon(pm).mutate();
+ } else {
+ icon = mResources.getDrawable(android.R.drawable.sym_def_app_icon);
+ }
+ mDialogLabel.setText(friendlyName);
+ mDialogLabel.setTag(uri);
+ mDialogIcon.setImageDrawable(resizeForDialog(icon));
+ mDialogIcon.setTag(null);
+ } catch (Exception e) {
+ }
+ }
+
+ private Drawable resizeForDialog(Drawable image) {
+ int size = (int) mResources.getDimension(android.R.dimen.app_icon_size);
+ Bitmap d = ((BitmapDrawable)image).getBitmap();
+ Bitmap bitmapOrig = Bitmap.createScaledBitmap(d, size, size, false);
+ return new BitmapDrawable(mResources, bitmapOrig);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ String shortcut_name = null;
+ if (data != null) {
+ shortcut_name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+ }
+ if (shortcut_name != null && shortcut_name.equals(EMPTY_LABEL)) {
+ mDialogLabel.setText(EMPTY_LABEL);
+ mDialogLabel.setTag(GlowPadView.EMPTY_TARGET);
+ mDialogIcon.setImageResource(R.drawable.ic_empty);
+ } else if (requestCode == IconPicker.REQUEST_PICK_SYSTEM || requestCode == IconPicker.REQUEST_PICK_GALLERY
+ || requestCode == IconPicker.REQUEST_PICK_ICON_PACK) {
+ mIconPicker.onActivityResult(requestCode, resultCode, data);
+ } else if (requestCode != Activity.RESULT_CANCELED && resultCode != Activity.RESULT_CANCELED) {
+ mPicker.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ @Override
+ public void onGrabbed(View v, int handle) {
+ }
+
+ @Override
+ public void onReleased(View v, int handle) {
+ }
+
+ @Override
+ public void onTrigger(View v, final int target) {
+ mTargetIndex = target;
+ if ((target != 0 && (mIsScreenLarge || !mIsLandscape)) || (target != 2 && !mIsScreenLarge && mIsLandscape)) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
+ builder.setTitle(R.string.lockscreen_target_edit_title);
+ builder.setMessage(R.string.lockscreen_target_edit_msg);
+ View view = View.inflate(mActivity, R.layout.lockscreen_shortcut_dialog, null);
+ view.findViewById(R.id.icon).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!mDialogLabel.getText().equals(EMPTY_LABEL)) {
+ try {
+ mImageTmp.createNewFile();
+ mImageTmp.setWritable(true, false);
+ mIconPicker.pickIcon(getId(), mImageTmp);
+ } catch (IOException e) {
+ }
+ }
+ }
+ });
+ view.findViewById(R.id.label).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mPicker.pickShortcut(new String[] {EMPTY_LABEL}, new ShortcutIconResource[] {
+ ShortcutIconResource.fromContext(mActivity, android.R.drawable.ic_delete) }, getId());
+ }
+ });
+ mDialogIcon = ((ImageButton) view.findViewById(R.id.icon));
+ mDialogLabel = ((Button) view.findViewById(R.id.label));
+ TargetInfo item = mTargetStore.get(target);
+ mDialogIcon.setImageDrawable(mTargetStore.get(target).defaultIcon.mutate());
+ TargetInfo tmpIcon = new TargetInfo(null);
+ tmpIcon.iconType = item.iconType;
+ tmpIcon.iconSource = item.iconSource;
+ tmpIcon.pkgName = item.pkgName;
+ mDialogIcon.setTag(tmpIcon);
+ if (mTargetStore.get(target).uri.equals(GlowPadView.EMPTY_TARGET)) {
+ mDialogLabel.setText(EMPTY_LABEL);
+ } else {
+ mDialogLabel.setText(mPicker.getFriendlyNameForUri(mTargetStore.get(target).uri));
+ }
+ mDialogLabel.setTag(mTargetStore.get(target).uri);
+ builder.setView(view);
+ builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ TargetInfo vObject = (TargetInfo) mDialogIcon.getTag();
+ String type = null, source = null, pkgName = null;
+ int targetInset = mTargetInset;
+ if (vObject != null) {
+ type = vObject.iconType;
+ source = vObject.iconSource;
+ pkgName = vObject.pkgName;
+ }
+ if (type != null && type.equals(GlowPadView.ICON_RESOURCE)) {
+ targetInset = 0;
+ }
+ InsetDrawable pD = new InsetDrawable(mDialogIcon.getDrawable(), targetInset,
+ targetInset, targetInset, targetInset);
+ setTarget(mTargetIndex, mDialogLabel.getTag().toString(), pD, type, source, pkgName);
+ }
+ });
+ builder.setNegativeButton(R.string.cancel, null);
+ builder.setCancelable(false);
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ ((TextView)dialog.findViewById(android.R.id.message)).setTextAppearance(mActivity,
+ android.R.style.TextAppearance_DeviceDefault_Small);
+ }
+ }
+
+ @Override
+ public void onGrabbedStateChange(View v, int handle) {
+ }
+
+ @Override
+ public void iconPicked(int requestCode, int resultCode, Intent in) {
+ Drawable ic = null;
+ String iconType = null;
+ String pkgName = null;
+ String iconSource = null;
+ if (requestCode == IconPicker.REQUEST_PICK_GALLERY) {
+ if (resultCode == Activity.RESULT_OK) {
+ File mImage = new File(mActivity.getFilesDir() + "/lockscreen_" + System.currentTimeMillis() + ".png");
+ if (mImageTmp.exists()) {
+ mImageTmp.renameTo(mImage);
+ }
+ mImage.setReadOnly();
+ iconType = GlowPadView.ICON_FILE;
+ iconSource = mImage.toString();
+ ic = new BitmapDrawable(getResources(), BitmapFactory.decodeFile(mImage.toString()));
+ } else {
+ if (mImageTmp.exists()) {
+ mImageTmp.delete();
+ }
+ return;
+ }
+ } else if (requestCode == IconPicker.REQUEST_PICK_SYSTEM) {
+ String resourceName = in.getStringExtra(IconPicker.RESOURCE_NAME);
+ ic = mResources.getDrawable(mResources.getIdentifier(resourceName, "drawable", "android")).mutate();
+ iconType = GlowPadView.ICON_RESOURCE;
+ iconSource = resourceName;
+ } else if (requestCode == IconPicker.REQUEST_PICK_ICON_PACK && resultCode == Activity.RESULT_OK) {
+ String resourceName = in.getStringExtra(IconPicker.RESOURCE_NAME);
+ pkgName = in.getStringExtra(IconPicker.PACKAGE_NAME);
+ try {
+ Context rContext = mActivity.createPackageContext(pkgName, 0);
+ int id = rContext.getResources().getIdentifier(resourceName, "drawable", pkgName);
+ ic = rContext.getResources().getDrawable(id);
+ } catch (NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ iconType = GlowPadView.ICON_RESOURCE;
+ iconSource = resourceName;
+ } else {
+ return;
+ }
+ TargetInfo tmpIcon = new TargetInfo(null);
+ tmpIcon.iconType = iconType;
+ tmpIcon.iconSource = iconSource;
+ tmpIcon.pkgName = pkgName;
+ mDialogIcon.setTag(tmpIcon);
+ mDialogIcon.setImageDrawable(ic);
+ }
+
+ @Override
+ public void onFinishFinalAnimation() {
+ }
+}
diff --git a/src/com/android/settings/cyanogenmod/ShortcutPickHelper.java b/src/com/android/settings/cyanogenmod/ShortcutPickHelper.java
new file mode 100644
index 0000000..07a4ee1
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/ShortcutPickHelper.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2011 The CyanogenMod Project
+ *
+ * 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.android.settings.cyanogenmod;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.Intent.ShortcutIconResource;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.TextView;
+
+import com.android.settings.R;
+import com.android.settings.cyanogenmod.ShortcutPickHelper.AppExpandableAdapter.GroupInfo;
+
+public class ShortcutPickHelper {
+
+ private Activity mParent;
+ private AlertDialog mAlertDialog;
+ private OnPickListener mListener;
+ private PackageManager mPackageManager;
+ private static final int REQUEST_PICK_SHORTCUT = 100;
+ private static final int REQUEST_PICK_APPLICATION = 101;
+ private static final int REQUEST_CREATE_SHORTCUT = 102;
+ private int lastFragmentId;
+
+ public interface OnPickListener {
+ void shortcutPicked(String uri, String friendlyName, boolean isApplication);
+ }
+
+ public ShortcutPickHelper(Activity parent, OnPickListener listener) {
+ mParent = parent;
+ mPackageManager = mParent.getPackageManager();
+ mListener = listener;
+ }
+
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ case REQUEST_PICK_APPLICATION:
+ completeSetCustomApp(data);
+ break;
+ case REQUEST_CREATE_SHORTCUT:
+ completeSetCustomShortcut(data);
+ break;
+ case REQUEST_PICK_SHORTCUT:
+ processShortcut(data, REQUEST_PICK_APPLICATION, REQUEST_CREATE_SHORTCUT);
+ break;
+ }
+ }
+ }
+
+ public void pickShortcut(String[] names, ShortcutIconResource[] icons, int fragmentId) {
+ Bundle bundle = new Bundle();
+
+ ArrayList<String> shortcutNames = new ArrayList<String>();
+ if (names != null) {
+ for (String s : names) {
+ shortcutNames.add(s);
+ }
+ }
+ shortcutNames.add(mParent.getString(R.string.profile_applist_title));
+ shortcutNames.add(mParent.getString(R.string.picker_activities));
+ bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
+
+ ArrayList<ShortcutIconResource> shortcutIcons = new ArrayList<ShortcutIconResource>();
+ if (icons != null) {
+ for (ShortcutIconResource s : icons) {
+ shortcutIcons.add(s);
+ }
+ }
+ shortcutIcons.add(ShortcutIconResource.fromContext(mParent, android.R.drawable.sym_def_app_icon));
+ shortcutIcons.add(ShortcutIconResource.fromContext(mParent, R.drawable.activities_icon));
+ bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
+
+ Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
+ pickIntent.putExtra(Intent.EXTRA_INTENT, new Intent(Intent.ACTION_CREATE_SHORTCUT));
+ pickIntent.putExtra(Intent.EXTRA_TITLE, mParent.getText(R.string.select_custom_app_title));
+ pickIntent.putExtras(bundle);
+ lastFragmentId = fragmentId;
+ startFragmentOrActivity(pickIntent, REQUEST_PICK_SHORTCUT);
+ }
+
+ private void startFragmentOrActivity(Intent pickIntent, int requestCode) {
+ if (lastFragmentId == 0) {
+ mParent.startActivityForResult(pickIntent, requestCode);
+ } else {
+ Fragment cFrag = mParent.getFragmentManager().findFragmentById(lastFragmentId);
+ if (cFrag != null) {
+ mParent.startActivityFromFragment(cFrag, pickIntent, requestCode);
+ }
+ }
+ }
+
+ private void processShortcut(final Intent intent, int requestCodeApplication, int requestCodeShortcut) {
+ // Handle case where user selected "Applications"
+ String applicationName = mParent.getString(R.string.profile_applist_title);
+ String application2name = mParent.getString(R.string.picker_activities);
+ String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+ if (applicationName != null && applicationName.equals(shortcutName)) {
+ Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+ mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+ Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
+ pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
+ startFragmentOrActivity(pickIntent, requestCodeApplication);
+ } else if (application2name != null && application2name.equals(shortcutName)){
+ final List<PackageInfo> pInfos = mPackageManager.getInstalledPackages(PackageManager.GET_ACTIVITIES);
+ ExpandableListView appListView = new ExpandableListView(mParent);
+ AppExpandableAdapter appAdapter = new AppExpandableAdapter(pInfos, mParent);
+ appListView.setAdapter(appAdapter);
+ appListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
+ @Override
+ public boolean onChildClick(ExpandableListView parent, View v,
+ int groupPosition, int childPosition, long id) {
+ Intent shortIntent = new Intent(Intent.ACTION_MAIN);
+ String pkgName = ((GroupInfo)parent.getExpandableListAdapter().getGroup(groupPosition))
+ .info.packageName;
+ String actName = ((GroupInfo)parent.getExpandableListAdapter().getGroup(groupPosition))
+ .info.activities[childPosition].name;
+ shortIntent.setClassName(pkgName, actName);
+ completeSetCustomApp(shortIntent);
+ mAlertDialog.dismiss();
+ return true;
+ }
+ });
+ Builder builder = new Builder(mParent);
+ builder.setView(appListView);
+ mAlertDialog = builder.create();
+ mAlertDialog.setTitle(mParent.getString(R.string.select_custom_activity_title));
+ mAlertDialog.show();
+ mAlertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ mListener.shortcutPicked(null, null, false);
+ }
+ });
+ } else {
+ startFragmentOrActivity(intent, requestCodeShortcut);
+ }
+ }
+
+ public class AppExpandableAdapter extends BaseExpandableListAdapter {
+
+ ArrayList<GroupInfo> allList = new ArrayList<GroupInfo>();
+ final int groupPadding;
+
+ public class LabelCompare implements Comparator<GroupInfo>{
+ @Override
+ public int compare(GroupInfo item1, GroupInfo item2) {
+ String rank1 = item1.label.toLowerCase();
+ String rank2 = item2.label.toLowerCase();
+ int result = rank1.compareTo(rank2);
+ if(result == 0) {
+ return 0;
+ } else if(result < 0) {
+ return -1;
+ } else {
+ return +1;
+ }
+ }
+ }
+
+ class GroupInfo {
+ String label;
+ PackageInfo info;
+ GroupInfo (String l, PackageInfo p) {
+ label = l;
+ info = p;
+ }
+ }
+
+ public AppExpandableAdapter(List<PackageInfo> pInfos, Context context) {
+ for (PackageInfo i : pInfos) {
+ allList.add(new GroupInfo(i.applicationInfo.loadLabel(mPackageManager).toString(), i));
+ }
+ Collections.sort(allList, new LabelCompare());
+ groupPadding = context.getResources().getDimensionPixelSize(R.dimen.shortcut_picker_left_padding);
+ }
+
+ public String getChild(int groupPosition, int childPosition) {
+ return allList.get(groupPosition).info.activities[childPosition].name;
+ }
+
+ public long getChildId(int groupPosition, int childPosition) {
+ return childPosition;
+ }
+
+ public int getChildrenCount(int groupPosition) {
+ if (allList.get(groupPosition).info.activities != null) {
+ return allList.get(groupPosition).info.activities.length;
+ } else {
+ return 0;
+ }
+ }
+
+
+ public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+ View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = View.inflate(mParent, android.R.layout.simple_list_item_1, null);
+ convertView.setPadding(groupPadding, 0, 0, 0);
+
+ }
+ TextView textView = (TextView)convertView.findViewById(android.R.id.text1);
+ textView.setText(getChild(groupPosition, childPosition).replaceFirst(allList.get(groupPosition).info.packageName + ".", ""));
+ return convertView;
+ }
+
+ public GroupInfo getGroup(int groupPosition) {
+ return allList.get(groupPosition);
+ }
+
+ public int getGroupCount() {
+ return allList.size();
+ }
+
+ public long getGroupId(int groupPosition) {
+ return groupPosition;
+ }
+
+ public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
+ ViewGroup parent) {
+ if (convertView == null) {
+ convertView = View.inflate(mParent, android.R.layout.simple_list_item_1, null);
+ convertView.setPadding(70, 0, 0, 0);
+ }
+ TextView textView = (TextView)convertView.findViewById(android.R.id.text1);
+ textView.setText(getGroup(groupPosition).label.toString());
+ return convertView;
+ }
+
+ public boolean isChildSelectable(int groupPosition, int childPosition) {
+ return true;
+ }
+
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ }
+
+ private void completeSetCustomApp(Intent data) {
+ mListener.shortcutPicked(data.toUri(0), getFriendlyActivityName(data, false), true);
+ }
+
+ private void completeSetCustomShortcut(Intent data) {
+ Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
+ /* preserve shortcut name, we want to restore it later */
+ intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME));
+ String appUri = intent.toUri(0);
+ appUri = appUri.replaceAll("com.android.contacts.action.QUICK_CONTACT", "android.intent.action.VIEW");
+ mListener.shortcutPicked(appUri, getFriendlyShortcutName(intent), false);
+ }
+
+ private String getFriendlyActivityName(Intent intent, boolean labelOnly) {
+ ActivityInfo ai = intent.resolveActivityInfo(mPackageManager, PackageManager.GET_ACTIVITIES);
+ String friendlyName = null;
+ if (ai != null) {
+ friendlyName = ai.loadLabel(mPackageManager).toString();
+ if (friendlyName == null && !labelOnly) {
+ friendlyName = ai.name;
+ }
+ }
+ return friendlyName != null || labelOnly ? friendlyName : intent.toUri(0);
+ }
+
+ private String getFriendlyShortcutName(Intent intent) {
+ String activityName = getFriendlyActivityName(intent, true);
+ String name = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+
+ if (activityName != null && name != null) {
+ return activityName + ": " + name;
+ }
+ return name != null ? name : intent.toUri(0);
+ }
+
+ public String getFriendlyNameForUri(String uri) {
+ if (uri == null) {
+ return null;
+ }
+
+ try {
+ Intent intent = Intent.parseUri(uri, 0);
+ if (Intent.ACTION_MAIN.equals(intent.getAction())) {
+ return getFriendlyActivityName(intent, false);
+ }
+ return getFriendlyShortcutName(intent);
+ } catch (URISyntaxException e) {
+ }
+
+ return uri;
+ }
+} \ No newline at end of file