Missing permission for Android document folder - java

I'm trying to access files in the android document folder. The code below works as long as the current installation of the app has created the files. After reinstalling the app or adding documents any other way the app can't access the files anymore. The file list shows up empty. Upon creating a new file, the newly created file is listed and accessible. I suspect my app is not allowed to use files in the document folder, if they are not created by the app itself - how do i change the permissions accordingly? Saving the files in the app folder is not an option.
The API version is 29.
package com.example.pos1;
import static com.example.example.pos1.*;
import static org.apache.commons.io.FilenameUtils.removeExtension;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
private Button startnPButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestStoragePermission();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startnPButton = (Button) findViewById(R.id.nPButton);
startnPButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openNew();
}
});
ImportMA();
}
private void requestStoragePermission()
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, PackageManager.PERMISSION_GRANTED);
}
public void openNew() {
Intent intent = new Intent(this, neuesProjekt.class);
startActivity(intent);
}
public void loadexisting() {
Intent intent = new Intent(this, NeueWohnung.class);
startActivity(intent);
}
public void ImportMA()
{
ListView listView=findViewById(R.id.listview);
List<String> list = new ArrayList<>();
ArrayAdapter arrayAdapter = new ArrayAdapter(getApplicationContext(), android.R.layout.simple_list_item_1,list);
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
File[] files = path.listFiles();
if (files.length>0)
{
for(int i = 0; i < files.length; i++)
{
System.out.println(files[i].getName());
list.add(removeExtension(files[i].getName()));
}
}
else
{
list.add("No elements!");
}
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String x = (String) listView.getItemAtPosition(position);
String filepath = new String (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)+"/"+x+".xls");
setFilepath(filepath);
setName(x);
Toast.makeText(getApplicationContext(),
"Projekt: "+getName(), Toast.LENGTH_SHORT)
.show();
loadexisting();
}
});
}
}

Related

FileUtils: readLines and writeLines methods not found

I'm new to Android Studio, so I followed directions to a video and an error constantly comes up that the methods ReadLines and writeLines do not exist.
I tried importing methods but none of them worked.
I assume this implementation was the one responsible for those methods, and it is in the correct location (app file) based on the instructions, but there is no error messages around it.
Video: https://www.youtube.com/watch?v=qP4U_4QvojQ&list=PLrT2tZ9JRrf6cHOlMkbmTMFt0RzpJiRGX&index=4
implementation 'commons-io:commons-io:2.6'
Here's the MainActivity.java code that uses the methods
package com.example.simpletodo;
import android.os.Bundle;
import android.os.FileUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ArrayList items;
Button btnAdd;
EditText etItem;
RecyclerView rvItems;
ItemsAdapter itemsAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnAdd = findViewById(R.id.btnAdd);
etItem = findViewById(R.id.etItem);
rvItems = findViewById(R.id.rvItems);
loadItems();
ItemsAdapter.OnLongClickListener onLongClickListener = new ItemsAdapter.OnLongClickListener(){
#Override
public void onItemLongClicked(int position){
//Delete the item from the model
items.remove(position);
//Notify the adapter
itemsAdapter.notifyItemRemoved(position);
Toast.makeText(getApplicationContext(), "Item is removed", Toast.LENGTH_SHORT).show();
saveItems();
}
};
itemsAdapter = new ItemsAdapter(items);
rvItems.setAdapter(itemsAdapter);
rvItems.setLayoutManager(new LinearLayoutManager(this));
btnAdd.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
String todoItem = etItem.getText().toString();
//Add item to the model
items.add(todoItem);
//Notify adapter that an item is inserted
itemsAdapter.notifyItemInserted(items.size() - 1);
etItem.setText("");
Toast.makeText(getApplicationContext(), "Item was added", Toast.LENGTH_SHORT).show();
saveItems();
}
});
}
private File getDatafile(){
return new File(getFilesDir(), "data.txt");
}
//This function will load items by reading every line of the data file
private void loadItems(){
try {
items = new ArrayList<>(FileUtils.readLines(getDatafile(), Charset.defaultCharset()));
}
catch (IOException e) {
Log.e("MainActivity", "Error reading items", e);
items = new ArrayList<>();
}
}
//This function saves items by writing them into the data file
private void saveItems(){
try {
FileUtils.writeLines(getDatafile(), items);
}
catch (IOException e){
Log.e("MainActivitiy", "Error writing items", e);
}
}
}
Try:
import org.apache.commons.io.FileUtils;
instead of
import android.os.FileUtils;
According to the documentation, android.os.FileUtils does not have readLines()
or writeLines() methods.

program just shuts down if I don't delete arraylist, it should show my songs, but program won't open

https://www.youtube.com/watch?v=D9--BF-W0AY
I did using this video (Android Studio). But it doesn't work because of "private ArrayList readSongs(File root){}", I think... All program just won't turn on....
"MainActivity.java"
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.os.Environment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.io.File;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity{
private ListView listView;
private String songNames[];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
final ArrayList<File> songs = readSongs(Environment.getExternalStorageDirectory());
songNames = new String[songs.size()];
for(int i = 0; i < songs.size(); ++i){
songNames[i] = songs.get(i).getName().toString().replace(".mp3","");
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.song_layout, R.id.textView,songNames);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
startActivity(new Intent(MainActivity.this, AudioPlayer.class).putExtra("position", i).putExtra("list", songs));
}
});
}
private ArrayList<File> readSongs(File root){
ArrayList<File> arrayList = new ArrayList<File>();
File files[] = root.listFiles();
for(File file : files){
if(file.isDirectory()){
arrayList.addAll(readSongs(file));
}else{
if(file.getName().endsWith(".mp3")){
arrayList.add(file);
}
}
}
return arrayList;
}
}
scan sd card root path in main thread will consume too much time ,maybe trigger ANR,you should invoke your method asynchronized.

Write to a text file in one activity and read into ListView in another?

So I'm relatively new to Android Studio. I'm just working on a small QR Code scanner. Basically, what I'm trying to do is add whatever the QR code result is to a text file then be able to load that text file into in another activity.
I have already added the necessary permissions to the AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
This is MainActivity.java
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.hardware.camera2.CameraManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.google.zxing.Result;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import me.dm7.barcodescanner.zxing.ZXingScannerView;
public class MainActivity extends AppCompatActivity implements ZXingScannerView.ResultHandler {
private ZXingScannerView mScannerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mScannerView = new ZXingScannerView(this); // Programmatically initialize the scanner view
setContentView(mScannerView);
mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results.
mScannerView.startCamera(); // Start camera
}
#Override
public boolean onCreateOptionsMenu (Menu menu)
{
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
int selectedId = item.getItemId();
switch (selectedId)
{
case R.id.mniHistory:
startActivity(new Intent(MainActivity.this, ResultsActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onPause() {
super.onPause();
mScannerView.stopCamera(); // Stop camera on pause
}
#Override
public void handleResult(final Result rawResult) {
// Do something with the result here
Log.e("handler", rawResult.getText()); // Prints scan results
Log.e("handler", rawResult.getBarcodeFormat().toString()); // Prints the scan format (qrcode)
// Alert Box (the one that asks if you want to send)
AlertDialog.Builder builder1 = new AlertDialog.Builder(this);
builder1.setTitle("Scan Result");
builder1.setMessage(rawResult.getText() + "\n" + "Would you like to send this?");
builder1.setCancelable(true);
builder1.setPositiveButton(
"Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// ADD SCAN TO TEXT FILE
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("History.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(rawResult.getText());
outputStreamWriter.close();
} catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
// DONE ADDING TO HISTORY
dialog.cancel();
}
});
builder1.setNegativeButton(
"No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
mScannerView.resumeCameraPreview(MainActivity.this);
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
}
The file is not writing for some reason. It doesn't appear in the phone's storage.
Anyway, here's ResultsActivity.java
ResultsActivity.java (Meant to display the scan history)
import android.content.Intent;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class ResultsActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_results);
ArrayList<String> completeList = new ArrayList<String>();
ListView listView1;
listView1 = (ListView) findViewById(R.id.ResultsListView);
try {
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/History.txt";
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "Cp1252"), 100);
String line;
// ArrayList<String> lines = new ArrayList<String>();
while ((line = br.readLine()) != null) {
completeList.add(line);
}
br.close();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, completeList);
listView1.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Am I reading the Text File into the ListView properly, by the way? Just wondering.
But anyway, my main question is writing into the internal storage and that doesn't seem to be working. Any ideas as to what is going on?
First, you shouldn't use such approach - to share simple string between components you can use many inmemory things, such as intents, services, broadcasts and so on. It is simpler to use the SharedPreferences at least.
Regarding your questions, the mistake is in this two lines of snippets:
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("History.txt", Context.MODE_PRIVATE));
At this line, you are opening stream to write data into private file (such files are stored within internal application folder).
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/History.txt";
And here you try to find the file within external storage (it is just a different folder)
So, to find your file, you can use corresponding method openFileInput
Hope, it'll help.

Playing a video in android

Im implementing a video playback in android im completely new to android, and this is the bit of code i have gathered so far.
according to the logic it should play a video. don't know where im doing wrong.
package com.themetanoia.readfilefromsdc;
import java.io.File;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.MediaController;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
import android.widget.AdapterView.OnItemClickListener;
public class ReadFileFromSDCActivity extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Get the file path for external storage
String a = Environment.getExternalStorageDirectory().getAbsolutePath();
final String finalPath = a+"/Videos";
//Define new file function
File f=new File(finalPath);
if(f.isDirectory()){
//Define arrayadapter
setListAdapter(new ArrayAdapter<String>(this, R.layout.listview,files));
//Define listview
ListView listview = getListView();
listview.setTextFilterEnabled(true);
//Onclick list item event
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//get selected items
String selectedValue = (String) getListAdapter().getItem(position);
Uri uri = Uri.parse(finalPath);
MediaController mediaController = new MediaController(getBaseContext());
mediaController.setAnchorView(mVideoView);
Uri video = Uri.parse(finalPath+"/"+selectedValue);
mVideoView.setMediaController(mediaController);
mVideoView.setVideoURI(video);
mVideoView.start();
}
});
}
}
}
<VideoView
android:id="#+id/videoView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
VideoView vv = (VideoView) findViewById(R.id.videoView1);
uri = "your video uri";
vv.setVideoURI(Uri.parse(uri));
vv.start();
vv.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
finish();
}
});

Using TextView on Android Problem

import android.app.Activity;
import android.app.ListActivity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class textfile extends ListActivity {
// private static final int PICKFILE_RESULT_CODE = 0;
private List<String> items = null;
private File currentDirectory;
private ArrayAdapter<String> fileList;
Intent myIntent = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
currentDirectory = new File("/sdcard/myfolder");
getFiles(currentDirectory.listFiles());
setContentView(R.layout.main);
}
protected void onListItemClick (AdapterView<?> parent, ListView l, View v, int position, long id)
{
int selectedRow = (int)id;
currentDirectory = new File(items.get(selectedRow));
if(currentDirectory.isDirectory()){
getFiles(currentDirectory.listFiles());
} else{
//if the selected file is not a directory. get the filename
currentDirectory.getPath();
}
Intent myIntent = null;
if(((TextView) v).getText().equals("sdcard/myfolder/anskey.txt")){
myIntent = new Intent(v.getContext(), dialog.class);
}
startActivity(myIntent);
}
private void getFiles(File[] files){
items = new ArrayList<String>();
for(File file : files){
items.add(file.getPath());
}
fileList = new ArrayAdapter<String>(this,R.layout.list_item, items);
setListAdapter(fileList);
}
}
In this program i am displaying directory structure display "sdcard/myfolder" as a list.
now what i want to do is that when i click on "sdcard/myfolder/anskey.txt" dialog.class activity should open.
there is no exception but on clicking "sdcard/myfolder/anskey.txt" ,the dialog.class activity is not opening.
From what I can see, your onListItemClick() signature is not right. It should be:
protected void onListItemClick(ListView l, View v, int position, long id)
This is the first thing you will want to correct. There could be other issues with your code.
I didn't see you assigned the Listener to the listView and I didn't see you declared your class to implement onListItemClickListener as well, so the implementation of onListItemListener is just another method. Follow this simple tutorial to accomplish that

Categories