@Bob Kerns - thanks for the excellent post!

>From what I understand, you set up a receiver so that the browser
starts up whenever the upgrade package is installed. But I thought
only services (not activities) should be started from receivers???
Sorry, I'm a bit rusty on this side of Android.  And what happens if
the user opens the app directly once its installed (from the
notification bar or Market app)?

BTW, you can get the calling package using:
http://developer.android.com/intl/fr/reference/android/app/Activity.html#getCallingPackage()

@chris harper - you might want to consider:

1. not putting ANY logic in your character apps

and/or

2. not copying out the resources - just leave them there. i.e. from
within the main app, access the resources in the character apps every
time you need to show/play them. This forces the user to keep the
character apps installed, however.

If I were you, I would think (even more!) carefully about this
strategy where you could have 100+(?) character apps in the Market.
You could attract many one-star comments for "spamming" the Market.

As soon as you deploy this strategy you are stuck with it.

I'm ever-the-optimist and guess that since there has been so little
development in the Market app over the last 18 months, there will be
something big coming up pretty soon.

So, if I were you, I would wait a little longer. Maybe until the next
SDK update.

On Mar 26, 7:48 am, Bob Kerns <[email protected]> wrote:
> You don't get notified BEFORE an uninstall, just after.
>
> I think I may have a solution for you. I'm having trouble parsing this
> thread; it may overlap with other suggestions here.
>
> This suggestion is based on what I've done for the Free/Pro versions
> of my SmartVolume app. (Only the Free is up at the moment). The whole
> purpose of doing this app was to work out issues like this. It's
> slightly different from your situation, but I think it would work with
> a couple of changes.
>
> First, in the manifest of my base app (my Free version, your actual
> main app), I have the following receiver:
>
>         <receiver android:icon="@drawable/icon" android:enabled="true"
> android:label="UpgradeReceiver" android:name="XUpgradeReceiver">
>             <intent-filter android:icon="@drawable/icon">
>                 <action
> android:name="android.intent.action.PACKAGE_ADDED"/>
>                 <data android:scheme="package"
> android:pathPrefix='com.sfsmart.volume.'/>
>             </intent-filter>
>         </receiver>
>
> The 'X' in 'XUpgradeReceiver' has to do with how I configure two
> versions from the same set of sources, it's not particularly relevant
> here, though I think it's rather clever...
>
> My XUpgradeReceiver, together with some logging, cancelling a
> notification, and Flurry stuff, does this:
>
>         Intent upgrade = new Intent("com.sfsmart.volume.UPGRADE")
>             .addFlags(FLAG_ACTIVITY_NEW_TASK)
>             .putExtra("com.sfsmart.volume.FROM",
> context.getPackageName())
>             .putExtra("com.sfsmart.volume.FROM_TYPE",
> fromType.getPrettyName());
>         try {
>             context.startActivity(upgrade);
>         } catch (Exception ex) {
>             BaseVolumeApplication.error(TAG, ex);
>         }
>
> The FROM identifies what was just installed.
>
> Now, my new app (but your main app) handles the
> com.sfsmart.volume.UPGRADE intent with this:
>         <activity
> android:name="com.sfsmart.volume.app.UpgradedActivity">
>             <intent-filter android:icon="@drawable/icon">
>                 <action android:name="com.sfsmart.volume.UPGRADE"/>
>                 <category
> android:name="android.intent.category.DEFAULT"></category>
>             </intent-filter>
>         </activity>
>
> public class UpgradedActivity extends BaseBrowserActivity {
>     @Override
>     protected void onCreate(Bundle savedInstanceState) {
>         super.onCreate(savedInstanceState);
>         loadUrl("file:///android_asset/upgraded.xhtml");
>     }
>
>     @Override
>     public void onBackPressed() {
>         finish();
>     }
>
> }
>
> This actually launches a webview that's set up with some Javascript
> callbacks. It basically informs the user:
>
> Thank you for upgrading.
>
> You have upgraded to the version, and your settings have been copied
> from the *com.sfsmart.volume.FROM_TYPE* version. You no longer need
> the *com.sfsmart.volume.FROM_TYPE* version, and it has been disabled,
> to avoid conflicting with the version.
>
> It is best to remove it now. If you wish to do so later, you can do so
> through the Applications system settings.
>
> And gives him a button that says "Delete SmartVolume Free", which
> clicked, takes you to this code:
>
> public class JavaScriptHandler {
> ...
>  public void deletePackage(String pkg) {
>             Intent upgrade = new
> Intent("android.intent.action.DELETE")
>             .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
>             .setData(Uri.parse("package:" + pkg));
>             try {
>                 startActivity(upgrade);
>             } catch (Exception ex) {
>                 BaseVolumeApplication.error(TAG, ex);
>             }
>         }
> ...
>         public Object getExtra(String key) {
>             return getIntent().getExtras().get(key);
>         }
> ...
>
> }
>
> Which will then offer to delete the old version.
>
> In your case, you'd instead copy what you wanted out of your new one
> (which you can do if signed with the same key and given the same
> userid), and then delete the new one, instead of the old.
>
> The Javascript handler also also gives the script on the page access
> to the extras in the intent, which is how it fills in the appropriate
> spots in the text. You could also supply additional text and such in
> the manifest of the download, and pass it along this way.
>
> You might find this Javascript helpful:
> function fixupVar(name, val) {
>     val = String(val);
>     var nodes = document.getElementsByClassName(name);
>     for (var i = 0; i < nodes.length; i++) {
>         var node = nodes[i];
>         if ((node.localName == 'A') || (node.localName == 'a')) {
>             node.setAttribute('href',
> (node.getAttribute('href').replace(name, val) || val));
>         } else {
>             node.innerText = (node.innerText.replace(name, val) ||
> val);
>         }
>     }
>
> }
>
> That is, I use class names to denote where to look in the document for
> where to insert the text. Typically, I use <span class='varNAME'></
> span> (and not <span class='varNAME'/> for reasons of compatibility
> with some browser or other).
>
> In my testing, this works pretty smoothly. It does involve the user in
> two screens, but the first one is merely educational, so he doesn't
> freak when presented with a delete-this-specific app dialog!
>
> I think if a lot of us follow this path, users will also become more
> accustomed to it.
>
> It was important to handle in my case, because having both apps could
> conflict.
>
> Note with the pathPrefix intent filter, I'm not being notified of
> every install, just the relevant one, so this is low-impact.
>
> I use Intent.FLAG_ACTIVITY_NEW_TASK, because after deleting the old,
> that's the end of it. I'm not sure that'd be correct in your scenario,
> though I think it might be.
>
> What do you think?
>
> On Mar 25, 3:57 pm, Kevin Duffey <[email protected]> wrote:
>
>
>
> > Is there a way to be notified of uninstalls? I thought there wasnt?
>
> > On Thu, Mar 25, 2010 at 3:51 PM, westmeadboy <[email protected]>wrote:
>
> > > What is your specific reason for wanting to uninstall the character
> > > apps?
>
> > > You can make sure that they do not appear in the app drawer by using
> > > the relevant intent filter. That would only leave them visible to the
> > > user when they do something like Settings -> Applications or look in
> > > the Downloads of the Market app.
>
> > > On Mar 25, 11:09 pm, chris harper <[email protected]> wrote:
> > > > Thanks guys
>
> > > > Rob/Kevin
>
> > > > You guys are really give me some ideas here.
>
> > > > Thank you for the advice on score loop but I don’t think I can user it
> > > > because my app doesn’t keep scores or interact with my app on other
> > > phones.
> > > > It’s not really a game.
>
> > > > So I am not sure if that will benefit me? I looked though scoreloop but
> > > it
> > > > looks like it is for comparing scores with other users within a social
> > > > network. Am I right?
>
> > > > Rob – I was actually thinking right along that same track. Each install
> > > app
> > > > keeps a timer of itself when it was installed and asks to be uninstalled
> > > > after 48 hours, BUT makes it clear to the user that uninstalling the
> > > install
> > > > app does NOT remove the character from the main app.
>
> > > > Kevin -  you gave me a great idea very close to what you suggested. I do
> > > > have a server side set up. Like I said I have a website set up with a
> > > > shopping cart and everything where I WAS going to make people
> > > buy/download
> > > > my characters from there.
>
> > > > What if the install .apk not only installs the character like I stated
> > > but
> > > > also takes the user ID from the database on the phone (which both the
> > > > install .apk and the main program share the same sqlite DB) and it sends
> > > the
> > > > information to the sever like you suggested that this user ID OWNS this
> > > > character. So any updates to this character get sent to this user.  If
> > > they
> > > > uninstall the install app before the 48 hours (for the refund) then
> > > before
> > > > it uninstalls it updates the server they do not own this character
> > > anymore
> > > > and this character was removed.
>
> > > > If they remove the .apk install app after the 48 hours (via the prompt
> > > like
> > > > Rob suggested) they still own the character and get any updates. The
> > > > character is not tied with the .apk after the initial install.
>
> > > > They can still remove the character from the main app at any time and
> > > that
> > > > will also tell the server that they do not own the character anymore.
>
> > > > What do you guys think?
>
> > > > On Thu, Mar 25, 2010 at 3:38 PM, Kevin Duffey <[email protected]>
> > > wrote:
> > > > > I wonder if removing the .apks will bring up other issues, like
> > > updates?
> > > > > For example, maybe not for your specific app, but what if a character
> > > .apk
> > > > > has a bug in it.. you fix it.. but end users have uninstalled. Now 
> > > > > they
> > > will
> > > > > have to pay/reinstall again to get the updated toon even if they
> > > already
> > > > > paid/installed before.
>
> > > > > Honestly Chris I don't think this is a viable solution. It's "close",
> > > but
> > > > > not quite there due to the variations of issue that may arise from
> > > removing
> > > > > the .apk.
>
> > > > > Here's a thought.. do you have a server side at all? If not, do you
> > > know
> > > > > enough server side to do a quick appengine or, I found a host that
> > > charges I
> > > > > think $15 a month to host a web app on a tomcat 6 server (I'll have to
> > > dig
> > > > > it up again)... the idea is.. make a simple server side app that 
> > > > > stores
> > > a
> > > > > user's paid-for characters in a DB. That is.. the user goes to your
> > > site,
> > > > > pays for a toon. You then update (in some secure/encrypted manner) the
> > > DB
> > > > > for that user that they "own" that character. The next time they 
> > > > > launch
> > > the
> > > > > game, some how it pulls the server and down comes any new toons they
> > > paid
> > > > > for. You can even allow for an SMS push notification that if they 
> > > > > don't
> > > have
> > > > > a wifi/3G connection, but do have cell.. your game could listen for 
> > > > > SMS
> > > > > messages (or a separate service piece to your game) and your server
> > > piece
> > > > > can send an SMS message (not sure what API/service allows for this 
> > > > > to...
>
> read more »

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

To unsubscribe from this group, send email to 
android-developers+unsubscribegooglegroups.com or reply to this email with the 
words "REMOVE ME" as the subject.

Reply via email to