Upload
ryan-murray
View
224
Download
1
Embed Size (px)
Citation preview
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 1 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Build AnBuild AnApplicationApplicationLauncher ForLauncher ForAndroidAndroid
To start off create a new
Android application
project within Eclipse.
Whenever I develop
Android apps I usually
start with the layout of the
application and add
functionality via Java
BlogBlog ArchiveArchive ProjectsProjects AboutAbout RSSRSS
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 2 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
classes later. Since our app
will display the users
installed apps within a
ListView widget we have
to first declare a layout to
hold the ListView itself.
Create a new xml layout
for the ListView by right
clicking the res/layout
folder and adding a new
android xml file. Title it
"applauncher.xml" and
then add the code below to
it.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/applauncher_linearlayout"
android:layout_width
android:layout_height
android:orientation
<ListView
android:id=
android:layout_width
android:layout_height
<TextView
android:id=
android:layout_width
android:layout_height
android:text
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 3 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
When using ListViews we
can setup the overall look
of each row by creating an
xml layout with a skeleton
of the widgets that we
want to display in each row
of our ListView. Think of
the row layout as a "row
template". If you look at
the screenshots of the app
you can tell that we only
need two widgets within
our row layout, an
ImageView to hold the
apps icon and a TextView
to display the apps
package name. Create a
new xml layout for the
ListView rows by right
clicking the res/layout
folder and adding a new
android xml file. Title it
"applauncherrow.xml" and
add the code below.
</LinearLayout>
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 4 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Next we're going to setup
the main activity for the
launcher app and register
the activity in the manifest.
Create a new Java Class
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/applauncherrow_imagelinearlayout"
android:layout_width
android:layout_height
android:padding="6dip"
<ImageView
android:id="@+id/applauncherrow_icon"
android:layout_width
android:layout_height
android:layout_marginRight
<LinearLayout
android:id="@+id/applauncherrow_namelinearlayout"
android:orientation
android:layout_width
android:layout_weight
android:layout_height
<TextView
android:id="@+id/applauncherrow_appname"
android:layout_width
android:layout_height
android:layout_weight
android:gravity
</LinearLayout>
</LinearLayout>
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 5 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
and name it
"AppLauncher.java". Next
open up the manifest file
for your application and
make sure it looks like the
code below.
<!-- Your package="" name might differ -->
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="org.example.hello"
android:versionCode
android:versionName
<!-- Your default android:icon="" name might differ -->
<application
android:icon="@drawable/icon"
android:label
android:debuggable
android:description
<activity
android:name
android:label
<!-- This tag indicates the initial activity -->
<intent-filter>
<action
<category
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 6 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Ok so now that the layouts
are coded up and the
activity is registered within
the manifest open up
AppLauncher.java and lets
begin. Lets start off with
importing all the necessary
libraries needed for our
app.
</manifest>
//Your package name might differ
package org.example.hello;
import java.util.ArrayList;
import java.util.Collections
import java.util.List;
import android.app.ListActivity
import android.app.ProgressDialog
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.graphics.drawable
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater
import android.view.View;
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 7 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Our app will extend the
ListActivity class in order
to reduce the boiler plate
needed to build a ListView.
However, due to the
structure of the app we'll
build the classes needed
and stitch them together
so just follow along with a
text editor for now. To
begin we'll need a class to
hold all the useful data we
can obtain from a given
app. We'll call it AppInfo,
its very basic so go ahead
and type it into your editor.
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.ListView
import android.widget.TextView
public class AppLauncher extends
public class AppInfo{
private String
private String
private String
private String
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 8 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
The next class we need is a
class that will be used to
obtain the application info
for the AppInfo class. This
class is the bread and
butter of our AppLauncher
and it together with the
private Integer
private Drawable
public String
return
}
public String
return
}
public String
return
}
public String
return
}
public Integer
return
}
public Drawable
return
}
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 9 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
AppInfo class can be
ported to any application
which needs to access
other apps via intents.
For the Applications
constructor we will pass in
the all important
PackageManager from the
main context.
Below are some getter
methods for the package
and activities list. The
difference between the
two is that the package list
contains the info about the
apps data and the activity
public class Applications{
private ArrayList
private List
private Intent
private PackageManager
public Applications(PackageManager
packMan
packageList
activityList
this
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 10 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
list contains info about the
intents the app responds
to.
The next method is the
createPackageList method.
All it does is simply extract
a list of all the installed
apps via the
PackageManager that we
passed into the
constructor. Next we
iterate over the list and
copy the info we need into
a AppInfo object and then
shove that object into the
ArrayList<AppInfo> that
will be returned.
public ArrayList getPackageList
return
}
public List
return
}
private ArrayList createPackageList
ArrayList
List packs
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 11 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Similar to the
createPakageList method,
createActivityList will
return a list with all of the
apps installed intent data
but unlike
createPackageList its only
8 lines of code.
for(int
PackageInfo
if((!
}
AppInfo
newInfo
getPackageManager
newInfo
newInfo
newInfo
newInfo
getPackageManager
pList
}
return pList
}
private List createActivityList
List
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 12 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
The next two methods are
purely for dubugging
purposes and can actually
be left out but we'll include
them for completeness or
in case you use this class in
another application.
Collections
return
}
private void packageDebug(){
if(
}
for
packageList
packageList
packageList
packageList
packageList
}
}
private void
if(
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 13 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
The next method is needed
only because in order to
launch an app you need
both its package name and
its intent name that
connects to the main class
of the app. However, if you
only use the packageList
you'll lack the intent data,
so the last method of the
Application class adds the
class name(intent data) to
the packageList making it
such that client of the class
can have everything
bundled up nicely in the
packageList instead of
having to rely on using
both the activity and
for
i
}
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 14 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
packageList in unison. For
the method
addClassNameToPackageList
we'll iterate over the
packageList and for each
packageName we'll find its
match within the
activityList by
packageName and then
extract the className
from the activityList.
private void addClassNamesToPackageList
if(null
}
String
for(int
tempName
j
packageList
j
}
}
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 15 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Below is the complete
Application class
public class Applications{
private ArrayList
private List
private Intent
private PackageManager
public Applications
packMan
packageList
activityList
this
}
public ArrayList
return
}
public List
return
}
private ArrayList
ArrayList
List packs
for(int
PackageInfo
if((!
}
AppInfo
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 16 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
newInfo
getPackageManager
newInfo
newInfo
newInfo
newInfo
getPackageManager
pList
}
return pList
}
private List
List
Collections
return
}
private void
if(
}
for
packageList
packageList
packageList
packageList
packageList
}
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 17 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Remember the AppInfo
class that we made and the
private void
if(
}
for
i
}
}
private void
if(
}
String
for
tempName
j
packageList
j
}
}
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 18 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
applauncherrow.xml
layout. Well, now we'll
utilize both within the
custom ArrayAdapter
extension we'll use to
populate the data of our
List. ArrayAdapters are
used to fill in the data fields
of a ListView widget by
storing a layout(android
uses the term inflate)
holding data into a single
row of the list.
The constructor for our
ArrayAdapter extension...
Being an ArrayAdapter
extension means that we
have to override the
getView method, this is
public class ApplicationAdapter
private ArrayList
public ApplicationAdapter(Context
super(context, textViewResourceId
this.items = items;
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 19 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
where the applauncherrow
layout is populated with
data and is used to
represent each row of the
ListView. To start we'll
reference the
applauncherrow layout
and inflate it to become a
view.
Now that the view is
inflated with the
applauncherrow.xml
layout we can now match
the ImageView and
TextView with the
contents of a AppInfo
object in preparation for
moving it into the ListView.
@Override
public View getView
ViewGroup
View
if(
view
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 20 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Here is the complete
ApplicationAdapter class,
you should add it to your
text file.
AppInfo appInfo = items.get
if(
R
R
appName
appIcon
}
return
}
}
public class ApplicationAdapter
private ArrayList
public ApplicationAdapter
super(context, textViewResourceId
this.items = items
}
@Override
public View getView
ViewGroup
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 21 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
We are done with the
utility classes so the next
step is to add some
methods to the
AppLauncher class itself.
The first one we're going
to add is a method called
getApps() which stores the
View
if(
view
}
AppInfo
if(
R
R
appName
appIcon
}
return
}
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 22 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
pacakageList from an
Applications object and
passes it off to Java
Runnable to be ran on a
thread.
If you look at the getApps()
method the last line before
the class ends is a method
called
this.runOnUiThread(returnRes),
now what this means is
that the main thread will
be locked while we pump
AppInfo objects into our
ListView via the
ArrayAdapter. If you are
experienced with
concurrent programming
private void getApps(){
try{
myApps
packageList
}
catch(Exception
Log
}
this.runOnUiThread
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 23 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
you might be wondering
why lock the
mainUIThread, the answer
is because our app can't do
anything until all objects
have been added to the
list. If we by chance were
dynamically loading things
from the Internet via
HTTP requests then we
would opt instead for a
lazy loader which spawns a
thread for each view
object pumped into the
ListVIew and the list would
slowly populate as each
item was fetched live from
the web. So anyways here
is our Runnable method
that checks first that the
packageList exists and
then uses an object from
our ApplicationAdapter to
fill up our ListView widget.
private Runnable returnRes
public void
if(
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 24 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
We're almost done so now
open up your Eclipse IDE
to the AppLauncher
project and click on the
AppLauncher.java class. If
you remember from earlier
where we left off go ahead
and add the data members
below to the AppLauncher
class; notice the line
numbers for reference.
For the onCreate() method
there are some things you
sould notice. First since
appAdapter
appAdapter
}
progressDialog
appAdapter
}
};
ApplicationAdapter appAdapter
ProgressDialog progressDialog
Runnable viewApps =
ArrayList packageList
Applications myApps
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 25 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
AppLauncher is a
ListActivity extension it
inherits the
setListAdapter() method.
Second we'll initialize the
viewApps Runnable to call
our getApps() within its
run(). This means that any
thread created with the
viewApps as it's runnable
will load up our packages
into the ListView. In
addition since getApps()
locks the mainUIThread
users of this app won't be
able to do anything until
the thread finishes.
public void onCreate(Bundle
super.onCreate
this.setContentView
packageList
appAdapter
packageList
this.setListAdapter
viewApps =
public
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 26 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Now that the thread has
started and the app has
been officially locked, how
do we notify the user? The
answer is with the
android.app.ProgressDialog
widget. Remember those
loading screen from
popular video games,
that's all ProgressDialogs
do.
Right now our app can
successfully load up a list
of Icons and application
names but how then do we
launch the apps the user
touches from our list? The
answer is via starting a
getApps
}
};
Thread appLoaderThread
appLoaderThread
progressDialog = ProgressDialog
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 27 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
new intent by overriding
the onListItemClick
method. So go open up
your text file that contains
the utility classes and
methods and add the
onListItemClick() method
to it.
Before you run the
AppLauncher, be sure to
copy and paste the classes
and methods into the
AppLauncher class so it
@Override
protected void onListItemClick
long
super.onListItemClick
AppInfo rowClicked
position
Intent startApp
ComponentName
rowClicked
rowClicked
startApp.setComponent
startApp.setAction
startActivity
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 28 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
resembles the complete
file below.
org.example.hello;
java.util.ArrayList;
java.util.Collections;
java.util.List;
android.app.ListActivity;
android.app.ProgressDialog;
android.content.ComponentName
android.content.Context;
android.content.Intent;
android.content.pm.ActivityInfo
android.content.pm.PackageInfo
android.content.pm.PackageManager
android.content.pm.ResolveInfo
android.graphics.drawable.Drawable
android.os.Bundle;
android.util.Log;
android.view.LayoutInflater;
android.view.View;
android.view.ViewGroup;
android.widget.ArrayAdapter;
android.widget.ImageView;
android.widget.ListView;
android.widget.TextView;
class AppLauncher extends ListActivity
ApplicationAdapter appAdapter
ProgressDialog progressDialog
Runnable viewApps = null;
ArrayList packageList = null
Applications myApps = null;
public void onCreate(Bundle savedInstanceState
super.onCreate(savedInstanceState
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 29 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
this.setContentView(
packageList = new ArrayList
appAdapter = new ApplicationAdapter
packageList
this.setListAdapter(
viewApps = new Runnable
public void run
getApps
}
};
Thread appLoaderThread
"AppLoaderThread"
appLoaderThread.start
progressDialog = ProgressDialog
"Hold on..."
}
public class Applications{
private ArrayList packageList
private List activityList
private Intent mainIntent
private PackageManager
public Applications(
packMan = packManager
packageList
activityList
this.addClassNamesToPackageList
}
public ArrayList getPackageList
return packageList
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 30 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
}
public List getActivityList
return activityList
}
private ArrayList createPackageList
ArrayList pList
List packs = getPackageManager
).getInstalledPackages
for(int i = 0; i
PackageInfo packInfo
if((!getSysPackages
continue
}
AppInfo newInfo
newInfo.appName
getPackageManager
newInfo.packageName
newInfo.versionName
newInfo.versionCode
newInfo.icon
getPackageManager
pList.add(newInfo
}
return pList;
}
private List createActivityList
List aList =
Collections.
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 31 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
return aList
}
private void packageDebug
if(null == packageList
return
}
for(int i =
Log.
packageList
packageList
packageList
packageList
packageList
}
}
private void activityDebug
if(null == activityList
return
}
for(int i =
ActivityInfo
i
Log.
}
}
private void addClassNamesToPackageList
if(null == activityList
return
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 32 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
}
String tempName
for(int i =
tempName
for(
j
packageList
j
}
}
}
}
public class AppInfo{
private String appName
private String packageName
private String className
private String versionName
private Integer versionCode
private Drawable icon
public String getAppName
return appName
}
public String getPackageName
return packageName
}
public String getClassName
return className
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 33 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
public String getVersionName
return versionName
}
public Integer getVersionCode
return versionCode
}
public Drawable getIcon
return icon;
}
}
public class ApplicationAdapter
private ArrayList items
public ApplicationAdapter
ArrayList
super(context, textViewResourceId
this.items = items;
}
@Override
public View getView(int position
ViewGroup parent
View view = convertView
if(view == null
LayoutInflater
view
}
AppInfo appInfo
if(appInfo !=
TextView
R
ImageView
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 34 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
R
if(appName
appName
}
if(appIcon
appIcon
}
}
return view;
}
}
private void getApps(){
try{
myApps = new
packageList
}
catch(Exception exception
Log.e("BACKGROUND PROC:"
}
this.runOnUiThread(returnRes
}
private Runnable returnRes =
public void run(){
if(packageList
appAdapter
for(
appAdapter
}
}
progressDialog
appAdapter.notifyDataSetChanged
}
};
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 35 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Enjoy your AppLauncher.
@Override
protected void onListItemClick
long id){
super.onListItemClick
AppInfo rowClicked =
position
Intent startApp = new
ComponentName component
rowClicked
rowClicked
startApp.setComponent
startApp.setAction(Intent
startActivity(startApp
}
4/9/14 11:28 PMBuild An Application Launcher For Android | Taywils.me
Page 36 of 36http://www.taywils.me/2011/07/05/buildanapplicationlauncherwithandroid.html
Install Python,Numpy andPandas onWindows 71 comment • a yearago
sutm —Thanks for
Java SparkFrameworkTutorial1 comment • 3months ago
Diego Torres— Thanks.
ALSO ON TAYWILS.ME
Comments Community Login
Sort by Best Share
Join the discussion…
• Reply •
felipetio • 6 months ago
Have a project source? Thx 13
• Reply •
Paul Marcellana• 3 months ago
May you please provide aproject source. I need itbadly. Thanks
4
• Reply •
Sagara S.Dev• 2 months ago
for PackageInfo packInfo =packs.get(i); i am gettingType Mismatch: can notconvert from object toPackage info error. anysuggetions?
2
WHAT'S THIS?
Favorite
Share ›
Share ›
Share ›
Copyright © 2014 Demetrious TaylorWilson. All rights reserved.