зеркало из https://github.com/mozilla/gecko-dev.git
Bug 667530 - Add ability to add application/bookmark shortcuts to Launcher screens [r=blassey, r=fabrice]
This commit is contained in:
Родитель
7164872b44
Коммит
87e308ca2d
|
@ -89,6 +89,7 @@
|
|||
<action android:name="org.mozilla.gecko.restart"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
#if MOZ_CRASHREPORTER
|
||||
<activity android:name="CrashReporter"
|
||||
android:label="@string/crash_reporter_title"
|
||||
|
@ -98,5 +99,14 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
#endif
|
||||
|
||||
<activity android:name="LauncherShortcuts"
|
||||
android:label="@string/launcher_shortcuts_title">
|
||||
<!-- This intent-filter allows your shortcuts to be created in the launcher. -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.CREATE_SHORTCUT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -303,7 +303,7 @@ abstract public class GeckoApp
|
|||
Log.i("GeckoApp", "Intent : ACTION_MAIN");
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(""));
|
||||
}
|
||||
else if (action.equals("org.mozilla.fennec.WEBAPP")) {
|
||||
else if (action.equals("org.mozilla.gecko.WEBAPP")) {
|
||||
String uri = intent.getStringExtra("args");
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(uri));
|
||||
Log.i("GeckoApp","Intent : WEBAPP - " + uri);
|
||||
|
|
|
@ -678,7 +678,7 @@ public class GeckoAppShell
|
|||
Log.w("GeckoAppJava", "installWebApplication for " + aURI + " [" + aTitle + "]");
|
||||
|
||||
// the intent to be launched by the shortcut
|
||||
Intent shortcutIntent = new Intent("org.mozilla.fennec.WEBAPP");
|
||||
Intent shortcutIntent = new Intent("org.mozilla.gecko.WEBAPP");
|
||||
shortcutIntent.setClassName(GeckoApp.mAppContext,
|
||||
GeckoApp.mAppContext.getPackageName() + ".App");
|
||||
shortcutIntent.putExtra("args", "--webapp=" + aURI);
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Android code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Wes Johnston <wjohnston@mozilla.com>
|
||||
* Mark Finkle <mfinkle@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#filter substitution
|
||||
package @ANDROID_PACKAGE_NAME@;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import org.mozilla.gecko.*;
|
||||
|
||||
import android.os.*;
|
||||
import android.content.*;
|
||||
import android.app.*;
|
||||
import android.text.*;
|
||||
import android.util.*;
|
||||
import android.widget.*;
|
||||
import android.database.sqlite.*;
|
||||
import android.database.*;
|
||||
import android.view.*;
|
||||
import android.net.Uri;
|
||||
import android.graphics.*;
|
||||
|
||||
|
||||
public class LauncherShortcuts extends ListActivity {
|
||||
public static final String CREATE_SHORTCUT = "org.mozilla.gecko.CREATE_SHORTCUT";
|
||||
|
||||
public class LauncherCursorAdapter extends SimpleCursorAdapter {
|
||||
private Cursor _cursor;
|
||||
private Context _context;
|
||||
|
||||
public LauncherCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
|
||||
// Using the older, deprecated constructor so we can work on API < 11
|
||||
super(context, layout, c, from, to);
|
||||
_cursor = c;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.favicon);
|
||||
|
||||
String favicon = cursor.getString(3);
|
||||
byte[] raw = Base64.decode(favicon.substring(22), Base64.DEFAULT);
|
||||
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(raw, 0, raw.length), 48, 48, true);
|
||||
imageView.setImageBitmap(bitmap);
|
||||
|
||||
super.bindView(view, context, cursor);
|
||||
}
|
||||
}
|
||||
|
||||
private Cursor getCursor(Context context) {
|
||||
File home = new File(context.getFilesDir(), "mozilla");
|
||||
if (!home.exists())
|
||||
return null;
|
||||
|
||||
File profile = null;
|
||||
String[] files = home.list();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
if (files[i].endsWith(".default")) {
|
||||
profile = new File(home, files[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (profile == null)
|
||||
return null;
|
||||
|
||||
File webapps = new File(profile, "webapps.sqlite");
|
||||
if (!webapps.exists())
|
||||
return null;
|
||||
|
||||
Log.i("LauncherShortcuts", "Opening: " + webapps.getPath());
|
||||
mDb = SQLiteDatabase.openDatabase(webapps.getPath(), null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
|
||||
return mDb.rawQuery("SELECT rowid as _id, title, uri, icon FROM webapps", null);
|
||||
}
|
||||
|
||||
private Cursor mCursor;
|
||||
private SQLiteDatabase mDb;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.launch_app_list);
|
||||
|
||||
final Intent intent = getIntent();
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
|
||||
mCursor = getCursor(this);
|
||||
if (mCursor != null) {
|
||||
// After selecting an item, the empty view can flash on screen. Clear
|
||||
// the text so we don't see it.
|
||||
TextView emptyText = (TextView)findViewById(android.R.id.empty);
|
||||
emptyText.setText("");
|
||||
|
||||
// Load the list using a custom adapter so we can create the bitmaps
|
||||
ListAdapter adapter = new LauncherCursorAdapter(
|
||||
this,
|
||||
R.layout.launch_app_listitem,
|
||||
mCursor,
|
||||
new String[] {"title"},
|
||||
new int[] {R.id.title}
|
||||
);
|
||||
setListAdapter(adapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
mCursor.moveToPosition(position);
|
||||
|
||||
Intent shortcutintent = new Intent("org.mozilla.gecko.WEBAPP");
|
||||
shortcutintent.setClass(this, App.class);
|
||||
shortcutintent.putExtra("args", "--webapp=" + mCursor.getString(2));
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, mCursor.getString(1));
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutintent);
|
||||
|
||||
String favicon = mCursor.getString(3);
|
||||
byte[] raw = Base64.decode(favicon.substring(22), Base64.DEFAULT);
|
||||
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
int size;
|
||||
switch (dm.densityDpi) {
|
||||
case DisplayMetrics.DENSITY_MEDIUM:
|
||||
size = 48;
|
||||
break;
|
||||
case DisplayMetrics.DENSITY_HIGH:
|
||||
size = 72;
|
||||
break;
|
||||
default:
|
||||
size = 72;
|
||||
}
|
||||
|
||||
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(raw, 0, raw.length), size, size, true);
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
|
||||
|
||||
// Now, return the result to the launcher
|
||||
setResult(RESULT_OK, intent);
|
||||
mDb.close();
|
||||
mCursor.close();
|
||||
finish();
|
||||
}
|
||||
}
|
|
@ -59,6 +59,7 @@ PROCESSEDJAVAFILES = \
|
|||
App.java \
|
||||
Restarter.java \
|
||||
NotificationHandler.java \
|
||||
LauncherShortcuts.java \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
@ -116,6 +117,8 @@ RES_LAYOUT = \
|
|||
res/layout/notification_progress.xml \
|
||||
res/layout/notification_progress_text.xml \
|
||||
res/layout/notification_icon_text.xml \
|
||||
res/layout/launch_app_list.xml \
|
||||
res/layout/launch_app_listitem.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_VALUES = res/values/colors.xml res/values/themes.xml
|
||||
|
|
|
@ -16,3 +16,6 @@
|
|||
<!ENTITY sending_crash_report "Sending crash report\u2026">
|
||||
<!ENTITY exit_label "Exit">
|
||||
<!ENTITY continue_label "Continue">
|
||||
|
||||
<!ENTITY launcher_shortcuts_title "&brandShortName; Web Apps">
|
||||
<!ENTITY launcher_shortcuts_empty "No web apps were found">
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="3dip"
|
||||
android:orientation="vertical"
|
||||
android:windowIsFloating="true">
|
||||
|
||||
<ListView android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:drawSelectorOnTop="false"/>
|
||||
|
||||
<TextView android:id="@android:id/empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/launcher_shortcuts_empty"/>
|
||||
</LinearLayout>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/listPreferredItemHeight"
|
||||
android:padding="6dip"
|
||||
android:orientation="horizontal">
|
||||
<ImageView
|
||||
android:id="@+id/favicon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="6dip"/>
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"/>
|
||||
</LinearLayout>
|
|
@ -21,4 +21,7 @@
|
|||
<string name="sending_crash_report">&sending_crash_report;</string>
|
||||
<string name="exit_label">&exit_label;</string>
|
||||
<string name="continue_label">&continue_label;</string>
|
||||
|
||||
<string name="launcher_shortcuts_title">&launcher_shortcuts_title;</string>
|
||||
<string name="launcher_shortcuts_empty">&launcher_shortcuts_empty;</string>
|
||||
</resources>
|
||||
|
|
Загрузка…
Ссылка в новой задаче