Max Devtec
Max Devtec

Reputation: 21

Android - PackageManager returns null when using a variable for getLaunchIntentForPackage()

Im making a customizable app shortcut(imagebutton) that displays the appicon and launches the app onclick. you can select the app you want to be displayed as shortcut from a popup window in another activity. im achieving this by saving the selected packagename to shared preferences as a string variable and using the getApplicationIcon() and getLaunchIntentForPackage methods in the activity of the shortcut to apply the selected app via packagename.

My Code

ReceiveActivity with the shortcut

public class ReceiveActivity extends AppCompatActivity {

    private ImageButton appDisplay;
    private Drawable icon;
    private PackageManager packageManager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_receive);

        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        String packageNameReceive = sharedPreferences.getString("fabKey", "default value");

        try {
            icon = packageManager.getApplicationIcon(packageNameReceive);
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(e);
        }

        appDisplay = findViewById(R.id.appDisplay);
        appDisplay.setBackground(icon);
        appDisplay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent appLaunch = packageManager.getLaunchIntentForPackage(packageNameReceive);
                startActivity(appLaunch);
            }
        });

    }

MainActivity where the input from popup gets saved

public class MainActivity extends Activity implements AppChooserListener  {

    private Button buttonTest;
    private TextView textviewSelected;
    private AppChooserListener activity;
    private Button checkButton;


    private String packageNameSave;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        activity = this;

        buttonTest = findViewById(R.id.button1);
        checkButton = findViewById(R.id.checkButton);

        textviewSelected = findViewById(R.id.textview2);

        buttonTest.setOnClickListener(v -> {

            // The method to display the dialog
            AppChooserDialog.show(v.getContext(), activity);

        });
        checkButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent checkIntent = new Intent(MainActivity.this, ReceiveActivity.class);
                startActivity(checkIntent);
            }
        });
    }

    @Override
    public void onAppChooserSelected(AppItem value) {
        packageNameSave = value.getPackageName();
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("fabKey", packageNameSave);
        editor.apply();


    }


}

Logs

    Process: com.example.appchooserold, PID: 25734
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.appchooserold/com.example.appchooserold.ReceiveActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.drawable.Drawable android.content.pm.PackageManager.getApplicationIcon(java.lang.String)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3677)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3814)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2309)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:942)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.drawable.Drawable android.content.pm.PackageManager.getApplicationIcon(java.lang.String)' on a null object reference
        at com.example.appchooserold.ReceiveActivity.onCreate(ReceiveActivity.java:34)
        at android.app.Activity.performCreate(Activity.java:8311)
        at android.app.Activity.performCreate(Activity.java:8290)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1385)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3658)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3814) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2309) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loopOnce(Looper.java:201) 
        at android.os.Looper.loop(Looper.java:288) 
        at android.app.ActivityThread.main(ActivityThread.java:7944) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:942) 

I didnt add the dialog because getting the packagename from it was successful. I discovered after some research that this is related to some changes in higher api levels of android, and i found some solutions like adding queries for VIEW and BROWSABLE in manifest but adding them didnt resolve my issue.

Upvotes: 0

Views: 775

Answers (1)

Max Devtec
Max Devtec

Reputation: 21

I found a solution

        appDisplay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                packageManager = getPackageManager();
                Intent appLaunch = packageManager.getLaunchIntentForPackage(packageNameReceive);
                appLaunch.setAction(Intent.ACTION_MAIN);
                appLaunch.addCategory(Intent.CATEGORY_LAUNCHER);
                appLaunch.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(appLaunch);
            }
        });

I replaced getPackageManager with an Instance of packagemanager via packageManager = getPackageManager() in the onclick method. I dont know how that works tho.

Upvotes: 0

Related Questions