简体   繁体   中英

Error while saving files in External Android storage

When I open the activity, I request for the directory permission. Once the permission is allowed, I write the name and content of the file and then I press the save button. There is a confirmation dialog before saving the file. I choose YES there and then the following error appears.

2019-07-17 04:29:31.063 17879-17879/com.halimlab.catatanharian E/WindowManager: android.view.WindowLeaked: Activity com.halimlab.catatanharian.InsertAndViewActivity has leaked window DecorView@56fdc15[InsertAndViewActivity] that was originally added here
    at android.view.ViewRootImpl.<init>(ViewRootImpl.java:538)
    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:346)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
    at android.app.Dialog.show(Dialog.java:329)
    at androidx.appcompat.app.AlertDialog$Builder.show(AlertDialog.java:1007)
    at com.halimlab.catatanharian.InsertAndViewActivity.konfirmasiSave(InsertAndViewActivity.java:191)
    at com.halimlab.catatanharian.InsertAndViewActivity.onBackPressed(InsertAndViewActivity.java:197)
    at com.halimlab.catatanharian.InsertAndViewActivity.buatDanUbah(InsertAndViewActivity.java:177)
    at com.halimlab.catatanharian.InsertAndViewActivity$1.onClick(InsertAndViewActivity.java:188)
    at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6739)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:495)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:859)

Here is my code.

public class InsertAndViewActivity extends AppCompatActivity implements View.OnClickListener {

    public static final int REQUEST_CODE_STORAGE = 100;
    int eventID = 0;
    EditText edtFileName, edtContent;
    Button btnSimpan;
    boolean isEditable = false;
    String fileName = "";
    String tempCatatan = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_insert_and_view);

        // button back
        ActionBar menu = getSupportActionBar();
        menu.setDisplayShowHomeEnabled(true);
        menu.setDisplayHomeAsUpEnabled(true);

        // input
        edtFileName = findViewById(R.id.editFilename);
        edtContent = findViewById(R.id.editContent);

        // button
        btnSimpan = findViewById(R.id.btnSimpan);
        btnSimpan.setOnClickListener(this);

        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            fileName = extras.getString("filename");
            edtFileName.setText(fileName);
            getSupportActionBar().setTitle("Ubah Catatan");
        } else {
            getSupportActionBar().setTitle("Tambah Catatan");
        }

        eventID = 1;
        if (Build.VERSION.SDK_INT >= 23) {
            if (periksaIzin()) {
                bacaFile();
            }
        } else {
            bacaFile();
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btnSimpan :
                eventID = 2;
                if (!tempCatatan.equals(edtContent.getText().toString())) {
                    if (Build.VERSION.SDK_INT >= 23) {
                        konfirmasiSave();
                    }
                } else {
                    konfirmasiSave();
                }
                break;
        }
    }

    public boolean periksaIzin() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == getPackageManager().PERMISSION_GRANTED) {
                return true;
            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_STORAGE);
                return false;
            }
        } else {
            return true;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case  REQUEST_CODE_STORAGE :
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if (eventID == 1) {
                        bacaFile();
                    } else {
                        konfirmasiSave();
                    }
                }

                break;
        }
    }

    void bacaFile() {
        String path = Environment.getExternalStorageDirectory().toString() + "/halimlab.catatan";
        File file = new File(path, edtFileName.getText().toString());
        if (file.exists()) {
            StringBuilder text = new StringBuilder();
            try {
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = br.readLine();
                while (line != null) {
                    text.append(line);
                    line = br.readLine();
                }
                br.close();
            } catch (Exception e) {
                System.out.println("ERROR" + e.getMessage());
            }
            tempCatatan = text.toString();
            edtContent.setText(text.toString());
        }
    }

    void buatDanUbah() {
        String state = Environment.getExternalStorageState();
        if (!Environment.MEDIA_MOUNTED.equals(state)) {
            return;
        }
        String path = Environment.getExternalStorageDirectory().toString() + "/halimlab.catatan";
        File parent = new File(path);
        if (parent.exists()) {
            File file = new File(path, edtFileName.getText().toString());
            FileOutputStream outputStream = null;
            try {
                file.createNewFile();
                outputStream = new FileOutputStream(file);
                OutputStreamWriter streamWriter = new OutputStreamWriter(outputStream);
                streamWriter.append(edtContent.getText());
                streamWriter.flush();
                streamWriter.close();
                streamWriter.flush();
                streamWriter.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            parent.mkdir();
            File file = new File(path, edtFileName.getText().toString());
            FileOutputStream outputStream = null;
            try {
                file.createNewFile();
                outputStream = new FileOutputStream(file, false);
                outputStream.write(edtContent.getText().toString().getBytes());
                outputStream.flush();
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        onBackPressed();
    }

    void konfirmasiSave () {
        new AlertDialog.Builder(this)
                .setTitle("Simpan Catatan")
                .setMessage("Apakah anda akan menyimpan catatan ini ?")
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        buatDanUbah();
                    }
                })
                .setNegativeButton(android.R.string.no, null).show();
    }

    @Override
    public void onBackPressed() {
        if (!tempCatatan.equals(edtContent.getText().toString())) {
            konfirmasiSave();
        }

        super.onBackPressed();
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.home) {
            onBackPressed();
        }
        return super.onOptionsItemSelected(item);
    }
}

I have the necessary permissions in my AndroidManifest.xml .

<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE"/>

You need to modify the onBackPressed function like the following.

@Override
public void onBackPressed() {
    if (!tempCatatan.equals(edtContent.getText().toString()))
        konfirmasiSave();
    else super.onBackPressed(); // Do that in the else part.
}

Because in the konfirmasiSave function you are opening a dialog which is not being closed or any action is being taken upon it and hence you are calling the super.onBackPressed which is trying to return back to the previous activity and hence causing the window leak error.

And handle the value of the tempCatatan variable before exiting so that your onBackPressed function performs as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM