2011年5月15日日曜日
2011年5月14日土曜日
アプリケーションが android:largeHeap=”true”指定されているかどうか確認する
ApplicationInfoの情報
AndroidManifest.xmlに情報を記述するってことは、その情報はApplicationInfoに格納されることは容易に想像がつくと思います。
デベロッパーサイトのApplicationInfoに以下の記載がありました。
public static final int FLAG_LARGE_HEAP
Since: API Level 11
Value for flags: true when the application has requested a large heap for its processes. Corresponds to android:largeHeap.
Constant Value: 1048576 (0x00100000)
ApplicationInfoのpublicメンバー、「flags」のフラグをチェックすれば判断できるってことですね。
MOTOROLA XOOMのインストールアプリを確認
以下のようにインストールアプリの情報を取得して、FLAG_LARGE_HEAPのフラグが立っているアプリのみログ出力してみました。
PackageManager pm = getPackageManager(); if(pm != null){ List<PackageInfo> package_list = pm.getInstalledPackages( PackageManager.GET_UNINSTALLED_PACKAGES ); for (PackageInfo info : package_list){ if(info.applicationInfo != null){ if((info.applicationInfo.flags & ApplicationInfo.FLAG_LARGE_HEAP) != 0){ Log.e("FLAG_LARGE_HEAP", info.packageName); } } } }
結果は以下のアプリでした。
なんとなく納得できそうなアプリ達でした。
05-15 04:25:42.530: ERROR/FLAG_LARGE_HEAP(7592): com.android.launcher
05-15 04:25:42.530: ERROR/FLAG_LARGE_HEAP(7592): com.google.android.youtube
2011年5月13日金曜日
android:largeHeap=”true”で使用可能なHeapサイズ
アプリケーションで使用するHeapサイズを拡大する
APIレベル11(ハニカム)からアプリケーションで使用するHeapサイズを拡大できるらしい。デベロッパーサイトに以下のような記載があります。
Return the approximate per-application memory class of the current device when an application is running with a large heap. This is the space available for memory-intensive applications; most applications should not need this amount of memory, and should instead stay with the getMemoryClass() limit. The returned value is in megabytes. This may be the same size as getMemoryClass() on memory constrained devices, or it may be significantly larger on devices with a large amount of available RAM.
The is the size of the application's Dalvik heap if it has specified android:largeHeap="true" in its manifest.
AndroidManifest.xmlに以下の記述をすると使用Heapサイズの拡大可能。
android:largeHeap="true"
ActivityManager.getLargeMemoryClass()でサイズを確認。
ActivityManager am = ((ActivityManager)getSystemService(Activity.ACTIVITY_SERVICE)); int largeMemory = am.getLargeMemoryClass();
ためしに、Motorola Xoom(MZ600) Android OS 3.0で確認したところ、"256MB"でした。
(追記)
Android OS 3.1にUpdate後確認。
Motorola Xoom(MZ600) Android OS 3.1で確認したところ、"256MB"でした。
2011年5月7日土曜日
カスタムNotification Layoutについて
NotificationにカスタムRemoteViewsをセット
NotificationManagerに登録するオブジェクト・Notificationを次のようにすると、カスタムLayoutを表示することができます。NotificationManager notificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE); Notification notification = new Notification(R.drawable.icon, context.getString(R.string.app_name), 0); notification.contentView = new RemoteViews(context.getPackageName(),YOUR_CUSTOM_LAYOUT_ID);
下の画像みたいな感じで表示できます。
各画像からIntentを発行したい
カスタムLayoutが表示できるとなると、次は「各画像をクリックしたら各アプリを起動」したくなります。RemoteViewsは以下のように各ViewにPendingIntentをセットすることができます。
notification.contentView.setOnClickPendingIntent( VIEW_ID, pendingIntent);
しかし、結論からいうと、FroyoでもGingerBreadでもIntent起動は不可能でした。
(※ただしHTC端末は可能。Android OS 3.0から正式サポートされています)
以下のソースをみれば理解できると思いますが、Intentの発行処理はnotification.contentIntentのみ対象となっています。
\frameworks\base\services\java\com\android\server
- StatusBarManagerService.java
- NotificationManagerService.java
Android OS 3.0から正式サポート
各ViewのPendingIntentによる起動がAndroid OS 3.0から正式サポートされています。デベロッパーサイト Android 3.0 Platform
Support for custom notification layouts to include buttons with PendingIntents, for more interactive notification widgets. For example, a notification can control music playback without starting an activity.
Motorola Xoomで確認すると次のような表示ができました。また、アイコンをクリックするとアプリ起動も可能でした。
2011年5月4日水曜日
自アプリ以外のアプリをclearDefaultできません
自アプリに対してのみclearDefault可能
PackageManagerクラスのclearPackagePreferredActivities()で各Actionの「デフォルトでの起動」を解除できます。ただし、Developerサイトに以下の記載されている通り、自アプリに対してのみ使用可能です。"An application can only clear its own package(s)."
プログラムをみてみる
あまりframworkのソースコードまで追いかけるサイトがありませんが、あえて確認の意味で覗いてみます。該当ソースコードは
\frameworks\base\services\java\com\android\server
PackageManagerService.java
public void clearPackagePreferredActivities(String packageName) { synchronized (mPackages) { int uid = Binder.getCallingUid(); PackageParser.Package pkg = mPackages.get(packageName); if (pkg == null || pkg.applicationInfo.uid != uid) { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS) != PackageManager.PERMISSION_GRANTED) { if (getUidTargetSdkVersionLockedLP(Binder.getCallingUid()) < Build.VERSION_CODES.FROYO) { Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " + Binder.getCallingUid()); return; } mContext.enforceCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); } } if (clearPackagePreferredActivitiesLP(packageName)) { scheduleWriteSettingsLocked(); } } }
以下のソースでTargetSdkの確認を行い、Froyo以前の場合は問答無用でエラー扱い。
if (getUidTargetSdkVersionLockedLP(Binder.getCallingUid()) < Build.VERSION_CODES.FROYO) {
TargetSdkがFroyo以上でも、以下のソースでパーミッションやPidのチェックが行われ、SecurityExceptionとなります。
private void enforce( String permission, int resultOfCheck, boolean selfToo, int uid, String message) { if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { throw new SecurityException( (message != null ? (message + ": ") : "") + (selfToo ? "Neither user " + uid + " nor current process has " : "User " + uid + " does not have ") + permission + "."); } } public void enforceCallingOrSelfPermission( String permission, String message) { enforce(permission, checkCallingOrSelfPermission(permission), true, Binder.getCallingUid(), message); }
2011年5月3日火曜日
Settingsアプリのアプリケーション詳細画面を呼び出してみる
呼び出し方法
APIレベル9よりSettingsクラスに「ACTION_APPLICATION_DETAILS_SETTINGS」が追加されています。Developerサイトより
Activity Action: Show screen of details about a particular application.IntentにはActionと表示したいアプリケーションのpackageスキームを指定します。
In some cases, a matching Activity may not exist, so ensure you safeguard against this.
Input: The Intent's data URI specifies the application package name to be shown, with the "package" scheme. That is "package:com.my.app".
Output: Nothing.
Constant Value: "android.settings.APPLICATION_DETAILS_SETTINGS"
ソースコード上はこんな感じでしょうか。
(※actionの指定が直書きですが気にしないでください)
startActivityForResult(new Intent("android.settings.APPLICATION_DETAILS_SETTINGS", Uri.parse("package:[起動したいアプリのPackageName]") )),0);
2011年5月2日月曜日
検索キーでアプリ起動したい
やりたいこと
検索キー長押しで特定のActivityを起動したい。デフォルトは音声検索が起動しますが、自分はあまり必要としないので、別のアプリを起動したい。
実現方法
AndroidManifest.xmlにintent-filterを記載すれば起動可能。<intent-filter> <action android:name="android.intent.action.SEARCH_LONG_PRESS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
登録:
投稿 (Atom)