Aplikacja Android Studio wykorzystujaca pliki txt

0

Witam Wszytkich!
Mam problem z moją aplikacja, gdy chcę do wybranego pliku.txt dopisać dane wyskakuje błąd:
"/document/primary:Download/textfile.txt:open failed: ENOENT(No such file or directory)"
Aplikacja ma uprawnienia na zapis i odczyt (WRITE_EXTERNAL_STORAGE itp). Sprawdzałem też w róznych folderach na urządzeniu.
W kodzie jest troche bałaganu, ale prosze nie zwracać na to uwagi:)
Kod MainActivity:

public class MainActivity extends AppCompatActivity {

    EMDKWrapper emdkWrapper = null;
    Button btnScanPage, btnCreateFile, btnViewFile, btnChooseFile;
    TextView tvFilePath;
    Uri uri = null;

    String name = "";
    String type = "text/plain";
    String typeExcel = "application/vnd.ms-excel";
    String typeExcelXLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

    String filePath = "";

    static final int READ_REQUEST_CODE = 42;
    static final int WRITE_REQUEST_CODE = 43;

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

        ActionBar actionBar = getSupportActionBar();
        actionBar.setIcon(R.mipmap.weilandt_logo);
        actionBar.setTitle(R.string.app_name);
        actionBar.setDisplayUseLogoEnabled(true);
        actionBar.setDisplayShowHomeEnabled(true);

        tvFilePath = (TextView) findViewById(R.id.tvFilePath);

        btnScanPage = (Button) findViewById(R.id.btnScanPage);
        btnScanPage.setVisibility(View.GONE);
        btnScanPage.setOnClickListener((view)-> {
            chooseFile();
            Intent intent = new Intent(MainActivity.this, ScanActivity.class);
            intent.putExtra(Intent.EXTRA_TEXT, filePath);
            startActivity(intent);
        });

        btnViewFile = (Button) findViewById(R.id.btnViewFile);
        btnViewFile.setOnClickListener((view)-> viewFile());

        btnCreateFile = (Button) findViewById(R.id.btnCreateFile);
        btnCreateFile.setOnClickListener((view)-> createFile(type, name));

        btnChooseFile = (Button) findViewById(R.id.btnChooseFile);
        btnChooseFile.setOnClickListener((view)-> chooseFile());

        if (Build.MANUFACTURER.contains("Zebra Technologies") || Build.MANUFACTURER.contains("Motorola Solutions")) {
            emdkWrapper = new EMDKWrapper();
            emdkWrapper.getEMDKManager();
            btnScanPage.setVisibility(View.VISIBLE);

        } else {
            Toast.makeText(MainActivity.this, "Non-Zebra! No Scan Barcodes option!", Toast.LENGTH_LONG).show();
        }
    }

    void viewFile () {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        startActivityForResult(intent, READ_REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK){
            if (data != null) {
                uri = data.getData();
            }
        }
    }

    void chooseFile() {
        if (uri != null) {
            filePath = uri.getPath();
            tvFilePath.setText(filePath);
        }

    }

    void createFile(String mimeType, String fileName) {
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType(mimeType);
        intent.putExtra(Intent.EXTRA_TITLE, fileName);
        startActivityForResult(intent, WRITE_REQUEST_CODE);
    }

    class EMDKWrapper implements EMDKManager.EMDKListener {

        EMDKManager emdkManager = null;

        void getEMDKManager(){
            EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this);

            if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS){
                Toast.makeText(MainActivity.this, "Failed to request EMDKManager", Toast.LENGTH_LONG).show();
            }
        }

        void release(){
            if (emdkManager != null){
                emdkManager.release();
                emdkManager = null;
            }
        }

        @Override
        public void onOpened(EMDKManager emdkManager) {
            this.emdkManager = emdkManager;

            Toast.makeText(MainActivity.this, "EMDK ready!", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onClosed() {
            if (emdkManager != null){
                emdkManager.release();
                emdkManager = null;
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (emdkWrapper != null){
            emdkWrapper.release();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()){
            case R.id.aboutUs:
                startActivity(new Intent(this, AboutUsActivity.class));
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

Kod ScanActivity:

public class ScanActivity extends AppCompatActivity implements EMDKManager.EMDKListener, Scanner.StatusListener, Scanner.DataListener {

    private EMDKManager emdkManager = null;
    private BarcodeManager barcodeManager = null;
    private Scanner scanner = null;
    private TextView statusTextView = null;
    private TextView dataView = null;
    private int dataLength = 0;
    private TextView tvChoosenFilePath, tvtest;

    String filePath;
    String fileName;
    File file;
    String barcodeToSave;

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

        ActionBar actionBar = getSupportActionBar();
        actionBar.setTitle(R.string.scanPage);
        actionBar.setDisplayUseLogoEnabled(true);
        actionBar.setDisplayShowHomeEnabled(true);

        statusTextView = (TextView) findViewById(R.id.textViewStatus);
        dataView = (TextView) findViewById(R.id.dataView);
        tvChoosenFilePath = (TextView) findViewById(R.id.tvChoosenFilePath);
        tvtest = (TextView) findViewById(R.id.tvtest);

        filePath = getIntent().getStringExtra(Intent.EXTRA_TEXT);
//        tvChoosenFilePath.setText(filePath);
        file = new File(filePath);
        fileName = file.getName();
        tvChoosenFilePath.setText(fileName);


        EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this);
        if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
            statusTextView.setText("EMDKManager Request Failed!");
        }
    }

    private void initializeScanner() throws ScannerException {
        if (scanner == null) {
            barcodeManager = (BarcodeManager) this.emdkManager.getInstance(EMDKManager.FEATURE_TYPE.BARCODE);
            scanner = barcodeManager.getDevice(BarcodeManager.DeviceIdentifier.DEFAULT);
            scanner.addDataListener(this);
            scanner.addStatusListener(this);
            scanner.triggerType = Scanner.TriggerType.HARD;
            scanner.enable();
            scanner.read();
        }
    }

    @Override
    public void onOpened(EMDKManager emdkManager) {

        this.emdkManager = emdkManager;
        try {
            initializeScanner();
        } catch (ScannerException e) {
            Toast.makeText(ScanActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }

        Toast.makeText(this, "Press Hard Scan Button to start scanning...", Toast.LENGTH_LONG).show();
    }

    private class AsyncDataUpdate extends AsyncTask<ScanDataCollection, Void, String> {

        @Override
        protected String doInBackground(ScanDataCollection... params) {
            String statusStr = "";
            try {
                if (scanner.isReadPending()) {
                    scanner.cancelRead();
                }

                scanner.read();
                ScanDataCollection scanDataCollection = params[0];
                if ((scanDataCollection != null) && (scanDataCollection.getResult() == ScannerResults.SUCCESS)) {
                    ArrayList<ScanDataCollection.ScanData> scanData = scanDataCollection.getScanData();
                    for (ScanDataCollection.ScanData data : scanData) {
                        String barcodeData = data.getData();
                        ScanDataCollection.LabelType labelType = data.getLabelType();
                        statusStr = barcodeData + " " + labelType;
                    }
                }

            } catch (ScannerException e) {
                Toast.makeText(ScanActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
            }
            return statusStr;
        }

        @Override
        protected void onPostExecute(String result) {
            if (dataLength++ >= 0) {
                dataView.setText("");
                dataLength = 0;
            }

            dataView.append(result + "\n");
            saveBarcodeToFile();
            try {
                writeToFile(filePath, barcodeToSave, 1);
            } catch (IOException e) {
                Toast.makeText(ScanActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
    }

    void saveBarcodeToFile(){
        barcodeToSave = dataView.getText().toString();
        tvtest.setText(barcodeToSave);
//
//        if (file.exists()){
//            Toast.makeText(ScanActivity.this, "File exist!", Toast.LENGTH_SHORT).show();
//            try {
//                FileOutputStream fileOutputStream = openFileOutput(file.getName(), getApplicationContext().MODE_APPEND);
//                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
//                outputStreamWriter.append(barcodeToSave + "\n");
//                outputStreamWriter.flush();
//                outputStreamWriter.close();
//                fileOutputStream.close();
//            } catch (Exception e){
//                Toast.makeText(ScanActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
//            }
//        } else {
//            Toast.makeText(ScanActivity.this, "File not exist!", Toast.LENGTH_SHORT).show();
//        }
    }

    void writeToFile(String filePath, String data, int position) throws IOException {
        RandomAccessFile myfile = new RandomAccessFile(filePath, "rw");
        myfile.seek(position);
        myfile.writeUTF(data);
        myfile.close();
    }

    private class AsyncStatusUpdate extends AsyncTask<StatusData, Void, String> {

        @Override
        protected String doInBackground(StatusData... params) {
            String statusStr = "";
            StatusData statusData = params[0];
            StatusData.ScannerStates state = statusData.getState();
            switch (state) {
                case IDLE:
                    statusStr = "The scanner enabled and its idle";
                    break;
                case SCANNING:
                    statusStr = "Scanning...";
                    break;
                case WAITING:
                    statusStr = "Waiting for trigger press..";
                    break;
                case DISABLED:
                    statusStr = "Scanner is not enabled";
                    break;
                default:
                    break;
            }
            return statusStr;
        }

        @Override
        protected void onPostExecute(String result) {
            statusTextView.setText(result);
        }
    }

    @Override
    public void onClosed() {
        if (this.emdkManager != null) {
            this.emdkManager.release();
            this.emdkManager = null;
        }
    }

    @Override
    public void onStatus(StatusData statusData) {
        new AsyncStatusUpdate().execute(statusData);
    }

    @Override
    public void onData(ScanDataCollection scanDataCollection) {
        new AsyncDataUpdate().execute(scanDataCollection);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (emdkManager != null) {
            emdkManager.release();
            emdkManager = null;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        try {
            if (scanner != null) {
                scanner.removeDataListener(this);
                scanner.removeStatusListener(this);
                scanner.disable();
                scanner = null;
            }
        } catch (ScannerException e) {
            Toast.makeText(ScanActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }
}

Próbowałem dokonać zapisu na dwa sposoby: FileOutputStream oraz RandomAccessFile.
Może ktoś podpowie co musze sprawdzić? Lub jakieś sugestie?

Dodam jeszcze, że plik i ścieżke do niego wybieram w MainActivity poprzez viewFile a potem przekazuje to do ScanActivity. Tylko nie wiem czy to dobrze robie, podejrzewam że tu może być gdzieś błąd.

Lub może ktoś zna jakiś przykład aplikacji na Androida "dopisujacej dane" do pliku wybranego/wskazanego przez użytkownika?

0

Jak dobrze pamiętam WRITE_EXTERNAL_STORAGE dotyczy tylko plików na zainstalowanej karcie pamięci SD. Standardowo z dysku systemowego możesz czytać i pisać jedynie w katalogu swojej aplikacji, poza tym katalogiem przy pomocy Javy nic raczej nie zrobisz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1