4

I am trying to download an Android app from a server using the DownloadManager class, install it and then detect when the installation is completed. I am using two receivers: one to detect the download process and the other to detect the install process. The first receiver works properly, but the second doesn't. What I am doing wrong?

DownloadManager dm = (DownloadManager) DownloadApplicationActivity.this.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request req = new DownloadManager.Request(Uri.parse(MY_LINK));
req.setTitle(MY_TITLE)
                .setDescription("Downloading ....")
                // download the package to the /sdcard/downlaod path.
                .setDestinationInExternalPublicDir(
                        Environment.DIRECTORY_DOWNLOADS,
                        MY_PATH);
        long enqueue = dm.enqueue(req);
BroadcastReceiver receiver= new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
        Query query = new Query();
        query.setFilterById(enqueue);
        Cursor c =dm.query(query);
        if (c.moveToFirst()) {
            int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
            if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
                // show a notification bar.
                NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
                Notification notification = new Notification(R.drawable.icon,"",System.currentTimeMillis());

                notification.flags |= Notification.FLAG_AUTO_CANCEL;
                notification.flags |= Notification.FLAG_NO_CLEAR;
                Intent i = new Intent(Intent.ACTION_VIEW);
                // when the notification is clicked, install the app.
                        i.setDataAndType(Uri.fromFile(new File(Environment
                                .getExternalStorageDirectory() + APP_PATH)),"application/vnd.android.package-archive");
                        PendingIntent pendingIntent = PendingIntent.getActivity(
                                activity, 0, i, 0);
                        notification.setLatestEventInfo(activity, MY_TEXT, MY_TEXT,pendingIntent);
                        notification.number += 1;
                        notificationManager.notify( 0, notification);
                        //i want to detect the app's installation, I register a ne receiver
                        registerReceiver(installReceiver,new IntentFilter(Intent.ACTION_PACKAGE_ADDED));
            }
        }           
};  

BroadcastReceiver installReceiver= new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
        Uri data = intent.getData();
        String packageName = data.getEncodedSchemeSpecificPart();
        Log.i("The installed package is: ", "" + packageName);

            }
        }           
};
Kara
  • 6,115
  • 16
  • 50
  • 57
b.i
  • 1,087
  • 4
  • 22
  • 43
  • refer this previous post http://stackoverflow.com/questions/11392183/how-to-check-if-the-application-is-installed-or-not-in-android-programmatically/11392276#11392276 – Aerrow Jul 09 '12 at 11:31
  • The post you gave checks whether the app is installed or not. what I want is to detect the installation after it is completed. – b.i Jul 09 '12 at 11:33

2 Answers2

8

I solved my problem, I added

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_INSTALL);
intentFilter.addDataScheme("package");

before the line :

registerReceiver(installReceiver, intentFilter);
b.i
  • 1,087
  • 4
  • 22
  • 43
  • The .addDataScheme() line is what I was missing! Do you need something similar for ACTION_PACKAGE_REMOVED? Where the hell is all of this documented? – gonzobrains May 28 '13 at 23:07
  • instead you can also add those to your Manifest file so that your code can be much more easier to track. – Olgun Kaya Oct 04 '13 at 16:57
0

You can try the code below. This way you can get all activities that can be called by an intent and if you know the activity name and it is present in list retrieved by queryIntentActivities()..you know it is installed.

public void callQrScan()
    {
    Intent intent1 = new Intent("com.google.zxing.client.android.SCAN");    

    if(isCallable(intent1)== true){



    Context context = getApplicationContext();
    CharSequence text = "Scan Niet Gelukt";
    int duration = Toast.LENGTH_SHORT;

    Toast toast = Toast.makeText(context, text, duration);
    toast.show();
    }
    else{
        Context context = getApplicationContext();
        CharSequence text = "Scan Niet Gelukt";
        int duration = Toast.LENGTH_SHORT;

        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
    }


    Button tempbutton = (Button)findViewById(R.id.Button03);

    tempbutton.setOnClickListener(new OnClickListener()
    {
        public void onClick(final View v)
    {
                callQrScan();
    }
    });

    }

    private boolean isCallable(Intent intent1) {  
                List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent1,   
            PackageManager.MATCH_DEFAULT_ONLY);  
        if(list.size() > 0)
                return true ;  
        else
            return false;

    }

Hope it helps :)

Abhilasha
  • 929
  • 1
  • 17
  • 37