-3

I want to use File chooser in my app. It crashes in the part where I want to append selected text to the view, specifically when I want to form setOnClickListener for TextView. Below is the mainactivity of the app;

package de.kai_morich.simple_bluetooth_terminal;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentManager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener {

    private static final int PERMISSION_REQUEST_CODE = 100;
    Button read;
    TextView output;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        read = findViewById(R.id.read);
        output = findViewById(R.id.output);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportFragmentManager().addOnBackStackChangedListener(this);
        if (savedInstanceState == null)
            getSupportFragmentManager().beginTransaction().add(R.id.fragment, new DevicesFragment(), "devices").commit();
        else
            onBackStackChanged();
        read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String state = Environment.getExternalStorageState();
                if (Environment.MEDIA_MOUNTED.equals(state)) {
                    if (Build.VERSION.SDK_INT >= 23) {
                        if (checkPermission()) {
                            File sdcard = Environment.getExternalStorageDirectory();
                            File dir = new File(sdcard.getAbsolutePath() + "/text/");
                            if(dir.exists()) {
                                File file = new File(dir, "sample.txt");
                                FileOutputStream os = null;
                                StringBuilder text = new StringBuilder();
                                try {
                                    BufferedReader br = new BufferedReader(new FileReader(file));
                                    String line;
                                    while ((line = br.readLine()) != null) {
                                        text.append(line);
                                        text.append('\n');
                                    }
                                    br.close();
                                } catch (IOException e) {
                                    //You'll need to add proper error handling here
                                }
                                output.setText(text);
                            }
                        } else {
                            requestPermission(); // Code for permission
                        }
                    } else {
                        File sdcard = Environment.getExternalStorageDirectory();
                        File dir = new File(sdcard.getAbsolutePath() + "/text/");
                        if(dir.exists()) {
                            File file = new File(dir, "sample.txt");
                            FileOutputStream os = null;
                            StringBuilder text = new StringBuilder();
                            try {
                                BufferedReader br = new BufferedReader(new FileReader(file));
                                String line;
                                while ((line = br.readLine()) != null) {
                                    text.append(line);
                                    text.append('\n');
                                }
                                br.close();
                            } catch (IOException e) {
                                //You'll need to add proper error handling here
                            }
                            output.setText(text);
                        }
                    }
                }
            }
        });
    }

    private boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE);
        if (result == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            return false;
        }
    }
    private void requestPermission() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
            Toast.makeText(MainActivity.this, "Write External Storage permission allows us to read files. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.e("value", "Permission Granted, Now you can use local drive .");
            } else {
                Log.e("value", "Permission Denied, You cannot use local drive .");
            }
            break;
        }
    }


    @Override
    public void onBackStackChanged() {
        getSupportActionBar().setDisplayHomeAsUpEnabled(getSupportFragmentManager().getBackStackEntryCount()>0);
    }

    @Override
    public boolean onSupportNavigateUp() {
        onBackPressed();
        return true;
    }

}

below is the error code that I recieve, I am not sure how to fix NullPointerException error;

2020-09-15 10:41:06.244 9578-9578/de.kai_morich.simple_bluetooth_terminal E/AndroidRuntime: FATAL EXCEPTION: main
    Process: de.kai_morich.simple_bluetooth_terminal, PID: 9578
    java.lang.RuntimeException: Unable to start activity ComponentInfo{de.kai_morich.simple_bluetooth_terminal/de.kai_morich.simple_bluetooth_terminal.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2750)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2811)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6316)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
        at de.kai_morich.simple_bluetooth_terminal.MainActivity.onCreate(MainActivity.java:57)
        at android.app.Activity.performCreate(Activity.java:6757)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2703)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2811) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6316) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762) 
Ali Ülkü
  • 84
  • 8
  • You need to call `setContentView(R.layout.activity_main);` **before** you use `findViewById` ... 'cos if you don't, `findViewById` will return `null`. – Stephen C Sep 15 '20 at 08:00
  • https://stackoverflow.com/questions/3264610/findviewbyid-returns-null – Stephen C Sep 15 '20 at 08:04

2 Answers2

2

your stacktrace says that you are setting setOnClickListener on null object. you are setting this listener only once on read Button, so it is null for shure

inside onCreate you have these lines:

@Override
protected void onCreate(Bundle savedInstanceState) {
    read = findViewById(R.id.read);
    output = findViewById(R.id.output);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ...

first two rows are trying to findViewById, but there are no views at all at this moment, because setContentView is called later. you should have super call in very first line (always) and setContentView in second (for most cases). after setting content (layout) you may look for your inflated Views

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

    read = findViewById(R.id.read);
    output = findViewById(R.id.output);
    ...
snachmsm
  • 15,392
  • 2
  • 25
  • 59
-1

i think in your code read = findViewById(R.id.buttonName) is missing

umar ali Khan
  • 28
  • 2
  • 5