Android Studio: file written to another directory - java

I am using an app to create a csv file which I would then like to export and read on the phone. However, the location that I am saving it to is not viewable and is making it hard to transfer.
Is there a way of saving this to a more accesible location such as /documents on the phone?
(I am very new to Java so sorry if this is an obvious question)
Thanks!
public void submit(View v)
{
String nline = System.getProperty("line.separator");
String fname = firstName.getText().toString() + ",";
String sname = surname.getText().toString() + ",";
String gender = genderSpin.getSelectedItem().toString() + ",";
String eaddress = email.getText().toString() + ",";
String mnum = mobile.getText().toString() + ",";
String fos = course.getText().toString() + ",";
String prole = proleSpin.getSelectedItem().toString();
FileOutputStream file = null;
if(fname.length() <= 1 || sname.length() <= 1 || eaddress.length() <= 1){
Toast.makeText(this, "Please enter all mandatory fields", Toast.LENGTH_SHORT).show();
}
else {
try {
file = openFileOutput(fileName, MODE_APPEND);
file.write(fname.getBytes());
file.write(sname.getBytes());
file.write(gender.getBytes());
file.write(eaddress.getBytes());
if (mnum.length() < 11) {
mnum = "null,";
file.write(mnum.getBytes());
}
if (fos.length() <= 1) {
fos = "null,";
file.write(fos.getBytes());
}
file.write(prole.getBytes());
file.write(nline.getBytes());
firstName.getText().clear();
surname.getText().clear();
genderSpin.setSelection(0);
email.getText().clear();
mobile.getText().clear();
course.getText().clear();
proleSpin.setSelection(0);
Toast.makeText(this, "Successfully Submitted", Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (file != null) {
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

First add WRITE_EXTERNAL_STORAGE to your manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Now you need request permission you can do it like this.
if(!checkPermission()){
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
WRITE_PERMISSION);
}
}
else {
// Permission already granted
}
Once the permission has been granted you can save file.
Following is the working MainActivity.class
package co.introtuce.nex2me.writefle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class MainActivity extends AppCompatActivity {
public static final int WRITE_PERMISSION=0xff;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=findViewById(R.id.mid);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
requestPermission();
}
});
}
public void requestPermission(){
if(!checkPermission()){
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
WRITE_PERMISSION);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
else {
afterPermisiion();
}
}
public boolean checkPermission(){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == WRITE_PERMISSION){
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//Permisiion Granted
afterPermisiion();
return;
}
}
requestPermission();
}
public void afterPermisiion(){
submit();
}
public boolean saveFile(String csv_contents, Context context){
OutputStream outputStream = null;
try{
File root = Environment.getExternalStorageDirectory();
if(root == null){
Log.d("SAVE_PHONE", "Failed to get root");
return false;
}
// create a directory
File saveDirectory = new File(root,"appName/files/csv" );
// create direcotory if it doesn't exists
// create direcotory if it doesn't exists
if(!saveDirectory.exists()) if ( !saveDirectory.mkdirs()){
Toast.makeText(context,"sorry could not create directory"+saveDirectory.getAbsolutePath(), Toast.LENGTH_LONG).show();
return false;
}
outputStream = new FileOutputStream( saveDirectory + "myfile.csv"); // filename.png, .mp3, .mp4 ...
if(outputStream != null){
Log.e( "SAVE_PHONE", "Output Stream Opened successfully");
}
byte[] bytes = csv_contents.getBytes();
outputStream.write( bytes, 0, bytes.length );
outputStream.close();
return true;
}catch (Exception e){
Log.d("EXCEPTION_IN",e.toString());
return false;
}
}
public void submit()
{
String nline = System.getProperty("line.separator");
String fname = "Name" + ",";
String sname = "Surname" + ",";
String gender = "gn" + ",";
String eaddress = "email" + ",";
String mnum = "num" + ",";
String fos = "fos" + ",";
String prole = "prole";
FileOutputStream file = null;
if(fname.length() <= 1 || sname.length() <= 1 || eaddress.length() <= 1){
Toast.makeText(this, "Please enter all mandatory fields", Toast.LENGTH_SHORT).show();
}
String csv_contents = nline+""+fname+sname+gender+eaddress+mnum+fos+prole;
if(saveFile(csv_contents,this)){
//File has saved
// DO something
Toast.makeText(this,"File has been saved",Toast.LENGTH_LONG).show();
}
else{
//Could not save file
// DO something
}
}
}
This will save cvs file in FileManager like /storage/emulated/0/appName/files/csv location. You can modify this location.

Related

Request permission in real device and file.list cannot work

I have 2 problems with Android app.
First of all I created Python Server and Android Java Client.
The main purpose is to send some commands from Python to Java.
So, my problems are here:-
1- When I call directory.list() not all files appears like images, I mean that images cannot appear to me but other files appears normally on Emulator and Real device.
2- When I run my code on Emulator, every thing is fine like send and receive data from and to Python and Java, and Java ask me about permission and wait until I accept or dinay, but when I run the same code on real device, all works fine instead of this line :-
else if(command.split(" ")[0].trim().equals("download"))
the program crashes and say "droidApp stopped".
I don't know if the error with in request permission from user or not because the request screen don't appear to me on real device which is appeared on Emulator, and I can't connect my real device with laptop because of problem with my hardware usb.
I'm sorry for my bad way of deliver my problem, but that is how can I describe it.
This is my full Java code:-
package droid.client;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Toast;
import java.net.InetAddress;
import java.net.Socket;
import java.io.*;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Base64;
public class MainActivity extends Activity {
private int STORAGE_PERMISSION_CODE = 1;
private Socket socket;
boolean sendData = true; // Flag to indicate whether data should be sent
//String Str = "HelloServer";
private static final int SERVERPORT = 2307;
private static final String SERVER_IP = "192.168.1.8";
private static boolean GET_FILE_PERMISSION = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
}
class ClientThread implements Runnable {
//String path = "/sdcard";
String path = Environment.getExternalStorageDirectory().toString() + "/Download";
File directory = new File(path);
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
DataInputStream Input = new DataInputStream(socket.getInputStream());
//DataOutputStream Output = new DataOutputStream(socket.getOutputStream());
FileInputStream getFileStream = null;
int bufLength = 4096;
byte[] buffer = new byte[4096];
byte[] data;
String ack;
while (socket.isConnected()){
String command = Input.readLine();
String Str = "";
if(command.equals("ls"))
{
directory = new File(path);
String[] files = directory.list();
for (int i = 0; i < files.length; i++)
{
Str += (files[i] + "\n");
}
}
else if(command.split(" ")[0].equals("cd"))
{
String subPath = command.split(" ")[1];
if(subPath.equals(".."))
{
String[] filePath = path.split("/");
if(filePath.length > 1)
{
for(int i = 0; i < filePath.length - 1; i++)
{
if(i == filePath.length - 2)
Str += filePath[i];
else
Str += filePath[i] + '/';
}
path = Str;
Str = "[+] Successful, new path is : " + path;
}
else
{
Str = "[-] Error, no back available.";
}
}
else
{
directory = new File(path);
String[] files = directory.list();
for (int i = 0; i < files.length; i++) {
if (files[i].equals(subPath)) {
path += '/' + subPath;
Str = "[+] Successful, new path is : " + path;
break;
}
if(i + 1 == files.length)
{
Str = "[-] Error, no such file or directory.";
break;
}
}
}
}
else if(command.split(" ")[0].trim().equals("download"))
{
String fileName = command.split(" ")[1].trim();
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "You have already granted this permission!",
Toast.LENGTH_SHORT).show();
} else {
requestStoragePermission();
}
getFileStream = new FileInputStream(path + "/" + fileName);
ByteArrayOutputStream out = new ByteArrayOutputStream();
int readLength;
while ((readLength = getFileStream.read(buffer, 0, bufLength)) != -1) {
out.write(buffer, 0, readLength);
}
data = out.toByteArray();
String imageString = Base64.getEncoder().encodeToString(data);
int firstIndex = 0;
int lastIndex = 4096;
int lengthOfFile = imageString.length();
while(lengthOfFile > 0)
{
if(lengthOfFile >= 4096)
{
sendMessage(imageString.substring(firstIndex,lastIndex));
firstIndex += 4096;
lastIndex += 4096;
lengthOfFile -= 4096;
}
else
{
lastIndex = (lastIndex - 4096) + lengthOfFile;
lengthOfFile = 0;
sendMessage(imageString.substring(firstIndex,lastIndex));
}
ack = Input.readLine();
}
Str = "DONE";
//out.close();
getFileStream.close();
}
sendMessage(Str);
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
private void sendMessage(String Str){
try {
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println(Str);
out.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void requestStoragePermission() {
while(GET_FILE_PERMISSION) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE))
{
new AlertDialog.Builder(this).setTitle("Permission needed").setMessage("This permission is needed because of this and that").setPositiveButton("ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.create().show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
//GET_FILE_PERMISSION = false;
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission GRANTED", Toast.LENGTH_SHORT).show();
GET_FILE_PERMISSION = false;
} else if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
Toast.makeText(this, "Permission DENIED", Toast.LENGTH_SHORT).show();
}
}
}
}

Application has Stoppped (Android Studio Bluetooth)

I try to make communication between two devices by using Bluteooth but always the application stopped when i try to test it.
I just try to send simple string (for exemple 'A') but also I have errors.
Also i can't turn on/off bluetooth manually.
the error is : Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothAdapter.isEnabled()' on a null object reference
at com.example.pfe.reglages.onCreate(reglages.java:53).
I need help because it's my project to get graduated
Thank you.
entrainement.java
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Handler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
import android.os.Message;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import static android.bluetooth.BluetoothAdapter.getDefaultAdapter;
import static android.content.ContentValues.TAG;
public class entrainement extends AppCompatActivity {
private boolean CONTINUE_READ_WRITE = true;
private boolean CONNECTION_ENSTABLISHED = false;
private boolean DEVICES_IN_LIST = true;
private static String NAME = "pfe.fawez";
private static UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
Button btn6, btn7, btn8, btn16, btn9, btn5;
EditText txt;
TextView logview;
ListView lv;
ArrayList<String> listItems;
ArrayAdapter<String> listAdapter;
private BluetoothAdapter adapter;
private BluetoothSocket socket;
private InputStream is;
private OutputStream os;
private BluetoothDevice remoteDevice;
private Set<BluetoothDevice> pairedDevices;
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.entrainement);
btn6 = findViewById(R.id.button6);
btn7 = findViewById(R.id.button7);
btn8 = findViewById(R.id.button8);
btn16 = findViewById(R.id.button16);
btn9 = findViewById(R.id.button9);
btn5 = findViewById(R.id.button5);
txt = findViewById(R.id.editText2);
logview = findViewById(R.id.textView14);
lv = (ListView)findViewById(R.id.listView);
listItems = new ArrayList<String>(); //shows messages in list view
listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listItems);
lv.setAdapter(listAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() //list onclick selection process
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
if(DEVICES_IN_LIST)
{
String name = (String) parent.getItemAtPosition(position);
selectBTdevice(name); //selected device will be set globally
//Toast.makeText(getApplicationContext(), "Selected " + name, Toast.LENGTH_SHORT).show();
//do not automatically call OpenBT(null) because makes troubles with server/client selection
}
else //message is selected
{
String message = (String) parent.getItemAtPosition(position);
txt.setText(message);
}
}
/*adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null) //If the adapter is null, then Bluetooth is not supported
{
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_SHORT).show();
finish();
return;
}
list(null);*/
});
btn9.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = txt.getText().toString();
byte[] b = textToSend.getBytes();
try {
os.write(b);
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
logview.append("\nConnection !\n");
}
});
btn6.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "R";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
btn16.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "L";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
btn7.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "X";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
btn8.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "Y";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
}
private Runnable writter = new Runnable() {
#Override
public void run() {
while (CONTINUE_READ_WRITE) //reads from open stream
{
try
{
os.flush();
Thread.sleep(2000);
} catch (Exception e)
{
Log.e(TAG, "Writer failed in flushing output stream...");
CONTINUE_READ_WRITE = false;
}
}
}
};
public void list(View v) //shows paired devices to UI
{
CONNECTION_ENSTABLISHED = false; //protect from failing
listItems.clear(); //remove chat history
listAdapter.notifyDataSetChanged();
pairedDevices = adapter.getBondedDevices(); //list of devices
for(BluetoothDevice bt : pairedDevices) //foreach
{
listItems.add(0, bt.getName());
}
listAdapter.notifyDataSetChanged(); //reload UI
}
public void selectBTdevice(String name) //for selecting device from list which is used in procedures
{
if(pairedDevices.isEmpty()) {
list(null);
Toast.makeText(getApplicationContext(), "Selecting was unsucessful, no devices in list." ,Toast.LENGTH_SHORT ).show();
}
for(BluetoothDevice bt : pairedDevices) //foreach
{
if(name.equals(bt.getName()))
{
remoteDevice = bt;
Toast.makeText(getApplicationContext(), "Selected " + remoteDevice.getName(), Toast.LENGTH_SHORT ).show();
}
}
}
public void openBT(View v) //opens right thread for server or client
{
if(adapter == null)
{
adapter = getDefaultAdapter();
Log.i(TAG, "Backup way of getting adapter was used!");
}
CONTINUE_READ_WRITE = true; //writer tiebreaker
socket = null; //resetting if was used previously
is = null; //resetting if was used previously
os = null; //resetting if was used previously
if(pairedDevices.isEmpty() || remoteDevice == null)
{
Toast.makeText(this, "Paired device is not selected, choose one", Toast.LENGTH_SHORT).show();
return;
}
}
public void closeBT(View v) //for closing opened communications, cleaning used resources
{
/*if(adapter == null)
return;*/
CONTINUE_READ_WRITE = false;
CONNECTION_ENSTABLISHED = false;
if (is != null) {
try {is.close();} catch (Exception e) {}
is = null;
}
if (os != null) {
try {os.close();} catch (Exception e) {}
os = null;
}
if (socket != null) {
try {socket.close();} catch (Exception e) {}
socket = null;
}
try {
Handler mHandler = new Handler();
mHandler.removeCallbacksAndMessages(writter);
mHandler.removeCallbacksAndMessages(serverListener);
mHandler.removeCallbacksAndMessages(clientConnecter);
Log.i(TAG, "Threads ended...");
}catch (Exception e)
{
Log.e(TAG, "Attemp for closing threads was unsucessfull.");
}
Toast.makeText(getApplicationContext(), "Communication closed" ,Toast.LENGTH_SHORT).show();
list(null); //shows list for reselection
txt.setText(getResources().getString(R.string.demo));
}
private Runnable serverListener = new Runnable()
{
public void run()
{
try //opening of BT connection
{
android.util.Log.i("TrackingFlow", "Server socket: new way used...");
socket =(BluetoothSocket) remoteDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(remoteDevice,1);
socket.connect();
CONNECTION_ENSTABLISHED = true; //protect from failing
} catch(Exception e) //obsolete way how to open BT
{
try
{
android.util.Log.e("TrackingFlow", "Server socket: old way used...");
BluetoothServerSocket tmpsocket = adapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
socket = tmpsocket.accept();
CONNECTION_ENSTABLISHED = true; //protect from failing
android.util.Log.i("TrackingFlow", "Listening...");
}
catch (Exception ie)
{
Log.e(TAG, "Socket's accept method failed", ie);
ie.printStackTrace();
}
}
Log.i(TAG, "Server is ready for listening...");
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
listItems.clear(); //remove chat history
listItems.add(0, String.format(" Server opened! Waiting for clients..."));
listAdapter.notifyDataSetChanged();
}});
try //reading part
{
is = socket.getInputStream();
os = socket.getOutputStream();
new Thread(writter).start();
int bufferSize = 1024;
int bytesRead = -1;
byte[] buffer = new byte[bufferSize];
while(CONTINUE_READ_WRITE) //Keep reading the messages while connection is open...
{
final StringBuilder sb = new StringBuilder();
bytesRead = is.read(buffer);
if (bytesRead != -1) {
String result = "";
while ((bytesRead == bufferSize) && (buffer[bufferSize-1] != 0))
{
result = result + new String(buffer, 0, bytesRead - 1);
bytesRead = is.read(buffer);
}
result = result + new String(buffer, 0, bytesRead - 1);
sb.append(result);
}
android.util.Log.e("TrackingFlow", "Read: " + sb.toString());
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
Toast.makeText(entrainement.this, sb.toString(), Toast.LENGTH_SHORT).show();
listItems.add(0, String.format("< %s", sb.toString())); //showing in history
listAdapter.notifyDataSetChanged();
}
});
}
}
catch(IOException e){
Log.e(TAG, "Server not connected...");
e.printStackTrace();
}
}
};
private Runnable clientConnecter = new Runnable()
{
#Override
public void run()
{
try
{
socket = remoteDevice.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
CONNECTION_ENSTABLISHED = true; //protect from failing
Log.i(TAG, "Client is connected...");
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
listItems.clear(); //remove chat history
listItems.add(0, String.format(" ready to communicate! Write something..."));
listAdapter.notifyDataSetChanged();
}});
os = socket.getOutputStream();
is = socket.getInputStream();
new Thread(writter).start();
Log.i(TAG, "Preparation for reading was done");
int bufferSize = 1024;
int bytesRead = -1;
byte[] buffer = new byte[bufferSize];
while(CONTINUE_READ_WRITE) //Keep reading the messages while connection is open...
{
final StringBuilder sb = new StringBuilder();
bytesRead = is.read(buffer);
if (bytesRead != -1)
{
String result = "";
while ((bytesRead == bufferSize) && (buffer[bufferSize-1] != 0))
{
result = result + new String(buffer, 0, bytesRead - 1);
bytesRead = is.read(buffer);
}
result = result + new String(buffer, 0, bytesRead - 1);
sb.append(result);
}
android.util.Log.e("TrackingFlow", "Read: " + sb.toString());
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
Toast.makeText(entrainement.this, sb.toString(), Toast.LENGTH_SHORT).show();
listItems.add(0, String.format("< %s", sb.toString()));
listAdapter.notifyDataSetChanged();
}
});
}
}
catch (IOException e)
{
Log.e(TAG, "Client not connected...");
e.printStackTrace();
}
}
};
}
reglages.java
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Set;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class reglages extends AppCompatActivity {
private static final int REQUEST_ENABLE_BT = 0;
private static final int REQUEST_DISCOVER_BT = 1;
TextView mStatusBlueTv, mPairedTv;
ImageView mBlueIv;
Button mOnBtn, mOffBtn, mDiscoverBtn, mPairedBtn;
BluetoothAdapter mBlueAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reglages);
mStatusBlueTv = findViewById(R.id.statusBluetoothTv);
mPairedTv = findViewById(R.id.pairedTv);
mBlueIv = findViewById(R.id.bluetoothIv);
mOnBtn = findViewById(R.id.onBtn);
mOffBtn = findViewById(R.id.offBtn);
mDiscoverBtn = findViewById(R.id.discoverableBtn);
mPairedBtn = findViewById(R.id.pairedBtn);
//adapter
mBlueAdapter = BluetoothAdapter.getDefaultAdapter();
//check if bluetooth is available or not
if (mBlueAdapter == null){
mStatusBlueTv.setText("Bluetooth is not available");
}
else {
mStatusBlueTv.setText("Bluetooth is available");
}
//set image according to bluetooth status(on/off)
if (mBlueAdapter.isEnabled()){
mBlueIv.setImageResource(R.drawable.ic_action_on);
}
else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
//on btn click
mOnBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mBlueAdapter.isEnabled()){
showToast("Turning On Bluetooth...");
//intent to on bluetooth
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_ENABLE_BT);
}
else {
showToast("Bluetooth is already on");
}
}
});
//discover bluetooth btn click
mDiscoverBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mBlueAdapter.isDiscovering()){
showToast("Making Your Device Discoverable");
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(intent, REQUEST_DISCOVER_BT);
}
}
});
//off btn click
mOffBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mBlueAdapter.isEnabled()){
mBlueAdapter.disable();
showToast("Turning Bluetooth Off");
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
else {
showToast("Bluetooth is already off");
}
}
});
//get paired devices btn click
mPairedBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mBlueAdapter.isEnabled()){
mPairedTv.setText("Paired Devices");
Set<BluetoothDevice> devices = mBlueAdapter.getBondedDevices();
for (BluetoothDevice device: devices){
mPairedTv.append("\nDevice: " + device.getName()+ ", " + device);
}
}
else {
//bluetooth is off so can't get paired devices
showToast("Turn on bluetooth to get paired devices");
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case REQUEST_ENABLE_BT:
if (resultCode == RESULT_OK){
//bluetooth is on
mBlueIv.setImageResource(R.drawable.ic_action_on);
showToast("Bluetooth is on");
}
else {
//user denied to turn bluetooth on
showToast("could't on bluetooth");
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
//toast message function
private void showToast(String msg){
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
Then change this lines:
//check if bluetooth is available or not
if (mBlueAdapter == null){
mStatusBlueTv.setText("Bluetooth is not available");
}
else {
mStatusBlueTv.setText("Bluetooth is available");
}
//set image according to bluetooth status(on/off)
if (mBlueAdapter.isEnabled()){
mBlueIv.setImageResource(R.drawable.ic_action_on);
}
else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
To this:
//check if bluetooth is available or not
if (mBlueAdapter == null) {
mStatusBlueTv.setText("Bluetooth is not available");
mBlueIv.setImageResource(R.drawable.ic_action_off);
} else {
mStatusBlueTv.setText("Bluetooth is available");
//set image according to bluetooth status(on/off)
if (mBlueAdapter.isEnabled()) {
mBlueIv.setImageResource(R.drawable.ic_action_on);
} else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
}
And each time you check isEnabled check for null first, changing:
if (mBlueAdapter.isEnabled()){
to:
if (mBlueAdapter != null && mBlueAdapter.isEnabled()) {
This way you'll prevent having NullPointers when the Bluetooth is not available (mBlueAdapter == null) as you can not check isEnabled() in this cases.

External storage: can't query a file that I have read access to

I am using a "ACTION_OPEN_DOCUMENT" intent to choose a file and open it.
This works just fine when I go to read the file.
However, when the file resides on EXTERNAL storage, and I run a query to obtain the file name, my program crashes. If the file resides on INTERNAL storage, I have no issues.
I DO have (and check for) external storage access permissions.
I have the query enclosed in a try{}, but the exception is not caught. I am developing on a Chrome book, so I am unable to run the debugger on it. But I have isolated the issue to the result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); statement.
I know that access to files on external storage has been limited, but I would think that if I can read a file that I should also be able to query it as well.
Here is my code:
package com.muddco.demo3;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.OpenableColumns;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class MainActivity extends AppCompatActivity {
Activity mAct;
TextView rvalue, fnamevalue;
Button btn1, btn2;
Uri fileUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = findViewById(R.id.btn1);
btn2 = findViewById(R.id.btn2);
rvalue = findViewById(R.id.readResult);
fnamevalue = findViewById(R.id.textView2);
mAct = this;
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*
* Launch a file picker
*/
Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(Intent.createChooser(intent, "Select a GPX file"), 1);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*
* Get and display file name
*/
String fname = getFileName(fileUri);
fnamevalue.setText(fname);
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission granted and now can proceed
Toast.makeText(MainActivity.this, "Permission granted", Toast.LENGTH_SHORT).show();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
// add other cases for more permissions
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
InputStream inputStream = null;
Uri uri = null;
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 1) {
// Process GPX file
uri = data.getData();
try {
inputStream = getBaseContext().getContentResolver().openInputStream(uri);
rvalue.setText(readFile(inputStream));
} catch (FileNotFoundException e) {
Toast.makeText(this, "File not found: " + uri.toString(), Toast.LENGTH_SHORT).show();
}
//String fName = getFileName(uri);
//Toast.makeText(mAct, "Filename: "+fName, Toast.LENGTH_LONG).show();
fileUri = uri;
btn2.setVisibility(View.VISIBLE);
}
}
}
/*
* Read a FileStream
*
*/
String readFile(InputStream is) {
String ret = "";
String line = null;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
ret += line + "\n";
}
br.close();
} catch (Exception e) {
// if any I/O error occurs
e.printStackTrace();
ret = "Exception!";
}
return ret;
}
/*
* Obtain the filename from a URI
*/
public String getFileName(Uri uri) {
String result = "<empty>";
Cursor cursor;
if (uri.getScheme().equals("content")) {
ContentResolver cr = getContentResolver();
try {
cursor = cr.query(uri, null, null, null, null);
} catch (Exception e) {
Toast.makeText(this, "Cursor exception: " + e.toString(), Toast.LENGTH_LONG).show();
return null;
}
try {
if (cursor != null && cursor.moveToFirst()) {
//
// THE NEXT STATEMENT CRASHES WHEN FILE RESIDES ON EXTERNAL STORAGE
//
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
else {
Toast.makeText(mAct, "Bad cursor", Toast.LENGTH_SHORT).show();
return "Bad Cursor";
}
} catch (Exception e) {
Toast.makeText(this, "Cursor exception: " + e.toString(), Toast.LENGTH_LONG).show();
return "Cursoe Exception";
} finally {
cursor.close();
}
}
else
result="Non content URI";
return result;
}
}
When I press the first button, the file requestor pops up and I select my test text file. The contents of the file are listed in a textbox, then a second button is made visible. When that second button is pressed, I query the file and place the filename in a second textbox.
The entire project, along with the test.txt file I am using to test, can be found here

My app does not create new files unless restarted

The app records audio. Each time a check is performed so if a file is about to be created it does not replace the previous file with the same name, but creates a new one adding "(number)" to their name instead.
This is the code for it:
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
int entryNumber = 1;
File mFile = new File(mFileName + "/Recording (" + String.valueOf(entryNumber) + ")" + ".mp3");
while (mFile.exists()) {
entryNumber++;
mFile = new File(mFileName + "/Recording (" + String.valueOf(entryNumber) + ")" + ".mp3");
}
this.mFileName = mFile.getAbsolutePath();
Recording process:
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setOutputFile(mFileName);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
isRecording = true;
recordBtn.setText("Stop");
Toast.makeText(getApplicationContext(), "Recording Started", Toast.LENGTH_LONG).show();
I noticed a bug. The app does create new files only if it exits and starts again.
Should the user continue recording sound, the app will not create a new file but instead will write over the previous file replacing it. It is supposed to always create a new file appon recording.
FULL PROJECT CODE HERE:
package com.android.greg.garec;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.RECORD_AUDIO;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
public class MainActivity extends AppCompatActivity {
private Button recordBtn, playBtn;
private MediaRecorder mRecorder;
private MediaPlayer mPlayer;
private static final String LOG_TAG = MainActivity.class.getSimpleName();
private static String mFileName = null;
public static final int REQUEST_AUDIO_PERMISSION_CODE = 1;
boolean isRecording = false;
boolean isPlaying = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recordBtn = findViewById(R.id.btnRecord);
playBtn = findViewById(R.id.btnPlay);
playBtn.setEnabled(false);
playBtn.setVisibility(View.INVISIBLE);
////////////////////////////////////////////////////////////////////////////////////////////////////////
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
int entryNumber = 1;
File mFile = new File(mFileName + "/Recording_" + String.valueOf(entryNumber) + ".mp3");
while (mFile.exists()) {
// File exists, just increment number
entryNumber++;
}
// Only create the file when it does not exist
mFile = new File(mFileName + "/Recording_" + String.valueOf(entryNumber) + ".mp3");
try {
mFile.createNewFile();
}
catch (IOException e) {
e.printStackTrace();
}
this.mFileName = mFile.getAbsolutePath();
////////////////////////////////////////////////////////////////////////////////////////////////////////
//Record button actions
recordBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isRecording) {
playBtn.setEnabled(true);
playBtn.setVisibility(View.VISIBLE);
mRecorder.stop();
mRecorder.release();
mRecorder = null;
// Toast.makeText(getApplicationContext(), "Recording Stopped", Toast.LENGTH_LONG).show();
isRecording = false;
recordBtn.setText("Record");
} else {
if (CheckPermissions()) {
playBtn.setEnabled(false);
playBtn.setVisibility(View.INVISIBLE);
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setOutputFile(mFileName);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
isRecording = true;
recordBtn.setText("Stop");
// Toast.makeText(getApplicationContext(), "Recording Started", Toast.LENGTH_LONG).show();
} else {
RequestPermissions();
}
}
}
});
//Play button actions
playBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isPlaying) {
mPlayer.release();
mPlayer = null;
recordBtn.setEnabled(true);
playBtn.setEnabled(true);
// Toast.makeText(getApplicationContext(), "Playing Audio Stopped", Toast.LENGTH_SHORT).show();
isPlaying=false;
playBtn.setText("Play");
} else {
recordBtn.setEnabled(true);
playBtn.setEnabled(true);
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
// Toast.makeText(getApplicationContext(), "Recorded playback started", Toast.LENGTH_LONG).show();
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
isPlaying = false;
// Toast.makeText(MainActivity.this, "Recorded playback finished", Toast.LENGTH_SHORT).show();
playBtn.setEnabled(true);
playBtn.setVisibility(View.VISIBLE);
playBtn.setText("Play");
}
});
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
isPlaying=true;
playBtn.setText("Stop");
}
}
});
}
//Permission checks - requests
#Override
public void onRequestPermissionsResult ( int requestCode, String[] permissions, int[] grantResults){
switch (requestCode) {
case REQUEST_AUDIO_PERMISSION_CODE:
if (grantResults.length > 0) {
boolean permissionToRecord = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean permissionToStore = grantResults[1] == PackageManager.PERMISSION_GRANTED;
boolean permissionToRead = grantResults[2] == PackageManager.PERMISSION_GRANTED;
if (permissionToRecord && permissionToStore && permissionToRead) {
Toast.makeText(getApplicationContext(), "Permission Granted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Permission Denied", Toast.LENGTH_LONG).show();
}
}
break;
}
}
public boolean CheckPermissions () {
int result = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), RECORD_AUDIO);
int result2 = ContextCompat.checkSelfPermission(getApplicationContext(), READ_EXTERNAL_STORAGE);
return (result == PackageManager.PERMISSION_GRANTED) && (result1 == PackageManager.PERMISSION_GRANTED) && (result2 == PackageManager.PERMISSION_GRANTED);
}
private void RequestPermissions () {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{RECORD_AUDIO, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE}, REQUEST_AUDIO_PERMISSION_CODE);
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btnRecord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="100dp"
android:layout_marginTop="120dp"
android:layout_marginEnd="135dp"
android:layout_marginBottom="160dp"
android:text="Record" />
<Button
android:id="#+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="100dp"
android:layout_marginEnd="135dp"
android:layout_marginBottom="100dp"
android:text="Play" />
</RelativeLayout>
Manifest file:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.STORAGE"/>
new File() just create a new object, not an actual File on the file system.
Use createNewFile() to create an empty file (documentation):
File file = new File(mFileName + "/Recording (" + String.valueOf(entryNumber) + ")" + ".mp3");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Example that should work without replaceing existing files :
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
int entryNumber = 1;
File mFile = new File(mFileName + "/Recording (" + String.valueOf(entryNumber) + ")" + ".mp3");
while (mFile.exists()) {
// File exists, just increment number
entryNumber++;
}
// Only create the file when it does not exists
mFile = new File(mFileName + "/Recording (" + String.valueOf(entryNumber) + ")" + ".mp3");
try {
mFile.createNewFile()
}
catch (IOException e) {
e.printStacjTrace();
}
this.mFileName = mFile.getAbsolutePath();
Hope it helps!

Unable to fetch file from google drive

I am working on a project where user can upload a document to my server. This file can be selected either from local storage or a cloud storage ,say google drive. When i click on the file from file chooser all i am receiving is an account info and doc info as a uri, When i tried to fetch doc from this URI it is showing FileNotFound . I have gone through Drive API also but It is a bit confusing to me. Following are the points i came accross while trying Google Drive API:
1. How to select file from local storage.
2. How do I get FileId form the selected file.
I tried with the following code snippet:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("**/");
startActivityForResult(intent, 1000);
and In onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
// The ACTION_OPEN_DOCUMENT intent was sent with the request code
// READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
// response to some other intent, and the code below shouldn't run at all.
if (requestCode == 1000 && resultCode == Activity.RESULT_OK) {
// The document selected by the user won't be returned in the intent.
// Instead, a URI to that document will be contained in the return intent
// provided to this method as a parameter.
// Pull that URI using resultData.getData().
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
Log.i("URI", "Uri: " + uri.toString());
try {
readTextFromUri(uri);
getMimeType(this,uri);
} catch (IOException e) {
e.printStackTrace();
}
// showImage(uri);
}
}
}
private String readTextFromUri(Uri uri) throws IOException {
// FileInputStream fileInputStream=new FileInputStream(uri.)
InputStream inputStream = getContentResolver().openInputStream(uri);
BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
// fileInputStream.close();
// parcelFileDescriptor.close();
return stringBuilder.toString();
}
Conclusion:
Can anyone please send me a link how to upload a document(I should even check the extension of the document) from both local storage and Google drive in a File chooser.
package com.example.ayyappaboddupalli.gdrive;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveClient;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveId;
import com.google.android.gms.drive.DriveResourceClient;
import com.google.android.gms.drive.OpenFileActivityOptions;
import com.google.android.gms.drive.query.Filters;
import com.google.android.gms.drive.query.SearchableField;
import com.google.android.gms.tasks.Continuation;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.TaskCompletionSource;
import com.google.api.services.drive.model.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Google drive";
private static final String SIGN_IN = "Sign In";
private static final String DOWNLOAD_FILE = "Download file";
private static final int REQUEST_CODE_SIGN_IN = 0;
private static final int REQUEST_CODE_OPEN_ITEM = 1;
private static final int REQUEST_WRITE_STORAGE = 112;
private GoogleSignInAccount signInAccount;
private Set<Scope> requiredScopes;
private DriveClient mDriveClient;
private DriveResourceClient mDriveResourceClient;
private OpenFileActivityOptions openOptions;
private TaskCompletionSource<DriveId> mOpenItemTaskSource;
private java.io.File storageDir;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.activity_main);
initialize();
requestPermission();
signInAccount = GoogleSignIn.getLastSignedInAccount(this);
if (signInAccount != null && signInAccount.getGrantedScopes().containsAll(requiredScopes)) {
initializeDriveClient(signInAccount);
} else {
// onDriveClientReady();
signIn();
}
Button button=(Button)findViewById(R.id.Submit);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onDriveClientReady();
}
});
}
private void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_SIGN_IN:
if (resultCode == RESULT_OK) {
Task<GoogleSignInAccount> getAccountTask = GoogleSignIn.getSignedInAccountFromIntent(data);
if (getAccountTask.isSuccessful()) {
initializeDriveClient(getAccountTask.getResult());
showMessage("Sign in successfully.");
// binding.btnSubmit.setText(DOWNLOAD_FILE);
} else {
showMessage("Sign in failed.");
}
} else {
showMessage("Sign in failed.");
}
break;
case REQUEST_CODE_OPEN_ITEM:
if (resultCode == RESULT_OK) {
DriveId driveId = data.getParcelableExtra(OpenFileActivityOptions.EXTRA_RESPONSE_DRIVE_ID);
mOpenItemTaskSource.setResult(driveId);
} else {
mOpenItemTaskSource.setException(new RuntimeException("Unable to open file"));
}
break;
}
}
private void initialize() {
requiredScopes = new HashSet<>(2);
requiredScopes.add(Drive.SCOPE_FILE);
requiredScopes.add(Drive.SCOPE_APPFOLDER);
openOptions = new OpenFileActivityOptions.Builder()
.setSelectionFilter(Filters.eq(SearchableField.MIME_TYPE, "application/pdf"))
.setActivityTitle("Select file")
.build();
}
private void initializeDriveClient(GoogleSignInAccount signInAccount) {
mDriveClient = Drive.getDriveClient(getApplicationContext(), signInAccount);
mDriveResourceClient = Drive.getDriveResourceClient(getApplicationContext(), signInAccount);
}
private void signIn() {
GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(Drive.SCOPE_FILE)
.requestScopes(Drive.SCOPE_APPFOLDER)
.build();
GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, signInOptions);
startActivityForResult(googleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}
private void onDriveClientReady() {
mOpenItemTaskSource = new TaskCompletionSource<>();
mDriveClient.newOpenFileActivityIntentSender(openOptions)
.continueWith(new Continuation<IntentSender, Void>() {
#Override
public Void then(#NonNull Task<IntentSender> task) throws Exception {
startIntentSenderForResult(
task.getResult(), REQUEST_CODE_OPEN_ITEM, null, 0, 0, 0);
return null;
}
});
Task<DriveId> tasks = mOpenItemTaskSource.getTask();
tasks.addOnSuccessListener(this,
new OnSuccessListener<DriveId>() {
#Override
public void onSuccess(DriveId driveId) {
retrieveContents(driveId.asDriveFile());
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
showMessage("File not selected.");
}
});
}
private void retrieveContents(final DriveFile file) {
// [START open_file]
final Task<DriveContents> openFileTask = mDriveResourceClient.openFile(file, DriveFile.MODE_READ_ONLY);
// [END open_file]
// [START read_contents]
openFileTask.continueWithTask(new Continuation<DriveContents, Task<Void>>() {
#Override
public Task<Void> then(#NonNull Task<DriveContents> task) throws Exception {
DriveContents contents = task.getResult();
Log.v(TAG, "File name : " + contents.toString());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
InputStream input = contents.getInputStream();
try {
java.io.File file = new java.io.File(getExternalFilesDir(null), "umesh.pdf");
Log.v(TAG, storageDir + "");
OutputStream output = new FileOutputStream(file);
try {
try {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
} finally {
output.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
showMessage("Download file successfully.");
return mDriveResourceClient.discardContents(contents);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
showMessage("Unable to download file.");
}
});
// [END read_contents]
}
private void requestPermission() {
String dirPath = getFilesDir().getAbsolutePath() + java.io.File.separator + "PDF";
storageDir = new java.io.File(dirPath);
if (!storageDir.exists())
storageDir.mkdirs();}}
//in gradle
implementation 'com.google.android.gms:play-services:11.8.0'
compile 'com.google.android.gms:play-services-auth:11.8.0'
compile 'com.google.api-client:google-api-client:1.23.0'
compile 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
compile 'com.google.apis:google-api-services-drive:v3-rev110-1.23.0'

Categories