I have an app that opens up a file picker and it outputs the path of that file in a Toast Message.
But I would like to change it such that the file that I pick is passed as a parameter to a function.
My activity looks like this:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.btn_picker);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, 7);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
switch (requestCode) {
case 7:
if (resultCode == RESULT_OK) {
String PathHolder = data.getData().getPath();
Toast.makeText(MainActivity.this, "The Files path is: "+ PathHolder, Toast.LENGTH_LONG).show();
}
break;
}
}
}
And it does what it is supposed to do but instead of outputting the file path, I would like to call the function
importToFile()
From the manage class.
I would like to do something like this:
manage.importToFile(File1)
Where File1 is the file I selected from the file picker.
How can I do that.
Thanks in advance.
You can use File class in android to work with files. Create an instance of File using the path of the selected file and pass it to that method of yours. Something like this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
switch (requestCode) {
case 7:
if (resultCode == RESULT_OK) {
// as #Taseer Ahmad said its not a good way to get path of the file.
//String PathHolder = data.getData().getPath();
String PathHolder = getPath(this, data.getData());
if (!TextUtils.isEmpty(PathHolder)) {
File file = new File(PathHolder);
manager.importToFile(file);
Toast.makeText(MainActivity.this, "The Files path is: "+ PathHolder, Toast.LENGTH_LONG).show();
}
}
break;
}
}
EDIT
As #Taseer Ahmad said, data.getData().getPath() is not a safe way to get path of the selected file. This code is copied from here.
public static String getPath(Context context, Uri uri) throws URISyntaxException {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { "_data" };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Eat it
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
Related
My requirement is the end-user must be able to upload files into the application from internal or external storage and finally display the name of the file in the page.
Actual result: Now I've fetched the file name from the storage and displayed the name in my page.
Expected Result: The end user must be able to load image or video files from external or internal storage to the application and finally display their name in the page.
But don't have any idea about how to load read the file from storage and store it in a arrayList.
Code for fetching the file name
public class ServiceDetails extends AppCompatActivity {
private Button next, attachment_one;
private ImageButton attach_file;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_details);
next = findViewById(R.id.submit);
attachment_one = findViewById(R.id.attachmentOne);
attach_file = findViewById(R.id.attachFile);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ServiceDetails.this, ServiceAddress.class);
startActivity(intent);
}
});
attach_file.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M &&
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 10001);
}
new MaterialFilePicker()
.withActivity(ServiceDetails.this)
.withRequestCode(1)
.withFilter(Pattern.compile(".*\\.(mkv|wmv|avi|mpeg|swf|mov|mp4|jpg|jpeg)$"))
.withHiddenFiles(true) // Show hidden files and folders
.start();
}
});
attachment_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
attachment_one.setVisibility(View.INVISIBLE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
String file_path = data.getStringExtra(FilePickerActivity.RESULT_FILE_PATH);
String file_array[] = file_path.split("/");
String file_name = file_array[file_array.length - 1];
// Do anything with file
if(attachment_one.getText().toString().isEmpty()) {
attachment_one.setVisibility(View.VISIBLE);
attachment_one.setText(file_name);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 10001: {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(ServiceDetails.this, "Permission granted", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(ServiceDetails.this, "Permission not granted", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
}
I'm new to android and kindly help me providing solution for this answer. Million thanks in advance!
Image showing file attachment option
As you are willing to load the title of video/images, and other file related information from the External Storage. You have to use this code and also make sure don't forget to create a Arraylist with model(required to extract information and find to the listview).
//ContentResolver and contentProvider as well as cursor
String[] projection = new String[]{
MediaStore.Video.Media._ID,
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.SIZE,
MediaStore.Video.Media.DATE_MODIFIED
};
String selection = null;
String[] selectionargs = null;
String orderBy = MediaStore.Video.Media.DISPLAY_NAME + " Desc";
Uri content_uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = getContentResolver().query(content_uri, projection, selection, selectionargs, orderBy);
if (cursor != null) {
cursor.moveToPosition(0);
}
while (true) {
long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
Uri VideoUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id);
Log.d("uri", "onCreate: video path " + VideoUri);
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));
float size = cursor.getFloat(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
// loading a thumbnail from the content resolver
// Load thumbnail of a specific media item.
Bitmap thumbnail = null;
try {
thumbnail = getApplicationContext().getContentResolver().loadThumbnail(VideoUri, new Size(200, 200), null);
Log.d("thumbnail", "onCreate: Lodaing a thumbnail");
} catch (IOException e) {
Log.d("thumbnail", "onCreate: Showing Error on thumbnail");
e.printStackTrace();
}
videolist.add(new Video(thumbnail, VideoUri, title, size));
if (!cursor.isLast()) {
cursor.moveToNext();
} else {
Log.d("lastItem", "onCreate: last uri is encountered");
break;
}
}
cursor.close();
I want to make an application that allows me to choose a file from SDcard (.apk file), then send it by HTTP Post to a web service.
The problem is that even if I can choose the file, I can't convert it in a byte array because my application is looking for it in its private folders, not in SDcard.
I used Intent to access to FileManager and choose a file from storage. Then, a toast notification shows me its path.
public class MainActivity extends AppCompatActivity {
Button button1;
Intent intent;
String PathHolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, 1);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
PathHolder = data.getData().getPath();
File file = new File(PathHolder);
String FileName = file.getName();
Toast.makeText(MainActivity.this, PathHolder, Toast.LENGTH_LONG).show();
try {
byte[] bArray = new byte[(int) file.length()];
FileInputStream inputStream = new FileInputStream(file);
inputStream.read(bArray);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
}
After
FileInputStream inputStream = new FileInputStream(f);
My application throws an Exception and the response is :
File Not Found
The variable f, on which you are constructing the FileInputStream of is never assigned or am I wrong? I think you should change f to file.
So I'm completely new to Android programming and I'm starting off by trying to make an app that allows users to edit audio files. Here is my code so far, which makes a user upload an audio file and play it:
public class MainActivity extends Activity {
final int ACTIVITY_CHOOSE_FILE = 1;
public String filePath;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) this.findViewById(R.id.uploadbutton);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent chooseFile;
Intent intent;
chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("audio/mpeg");
intent = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(intent, ACTIVITY_CHOOSE_FILE);
}
});
Button playButton = (Button)findViewById(R.id.playbutton);
playButton.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mp.setDataSource(getApplicationContext(), Uri.parse(filePath));
} catch (IOException e) {
e.printStackTrace();
}
try {
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mp.start();
}
});
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACTIVITY_CHOOSE_FILE: {
if (resultCode == RESULT_OK) {
Uri uri = data.getData();
filePath = uri.getPath();
getFilePath(filePath);
TextView URI_Text = (TextView)findViewById(R.id.file_URI);
URI_Text.setText(filePath);
}
}
}
}
public String getFilePath (String filePath) {
return filePath;
}
}
However, I'm getting the error code E/Surface: getSlotFromBufferLocked: unknown buffer: 0xab756e00
What am I doing wrong?
That error is not related to any of your code from your question. However, you are going wrong in other places.
getPath() is useless. The Uri should be treated as an opaque handle. Calling getPath() on a Uri, and expecting a file to be at that path, is akin to expecting there to be a /questions/33843271/error-when-trying-to-play-audio-file-from-uri path on your computer's hard drive, just because your browser happens to be showing a URL with that path.
Also, your access to the data represented by that Uri is short-lived. This is reminiscent of Web development, where you might be able to stream data from some URL for a while, but eventually your session times out. Saving the Uri is pointless. Either consume the data now (via a ContentResolver and openInputStream()), or don't bother with the data at all.
I want to pick a video file from gallery (first part of my code) and upload it to a server using Retrofit-neglect it for this question please. So, I want to pass a File from the first part to the second one but it gives me the error mentioned in the title.
MainActivity:
public class MainActivity extends Activity
{
private static int RESULT_LOAD_VIDEO = 1;
String decodableString;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn_load = (Button) findViewById(R.id.buttonLoadVideo);
btn_load.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
loadVideoFromGallery(btn_load);
}
});
}
/*
* PICK THE VIDEO AND EXTRACT ITS ADDRESS
*/
public void loadVideoFromGallery(View view)
{
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_VIDEO);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
try {
// When a video is picked
if (requestCode == RESULT_LOAD_VIDEO && resultCode == RESULT_OK
&& null != data)
{
// Get the video from data
Uri selectedVideo = data.getData();
String[] filePathColumn = { MediaStore.Video.Media.DATA };
Cursor cursor = getContentResolver().query(selectedVideo,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
decodableString = cursor.getString(columnIndex);
Log.i("mok","ds: " + decodableString);//ds: /storage/extSdCard/DCIM/Camera/20151112_142950.mp4
Log.i("mok","svp: " + selectedVideo.getPath());//svp: /external/video/media/253
Log.i("mok","fpc0: " + filePathColumn[0]);//fpc0: _data
cursor.close();
File file = new File(selectedVideo.getPath());
upload(file);
} else
{
Toast.makeText(this, "You haven't picked any video",
Toast.LENGTH_LONG).show();
}
} catch (Exception e)
{
e.printStackTrace();
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
.show();
}
}
/*
* UPLOAD THE SELECTED VIDEO TO THE SRVER
*/
public void upload(File file)
{
final String BASE_URL = "http://192.168.1.7/";
Retrofit retrofit = new Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
UploadApiService service = retrofit.create(UploadApiService.class);
MediaType MEDIA_TYPE = MediaType.parse("video/mp4");
RequestBody requestBody = RequestBody.create(MEDIA_TYPE, file);
Call<ResponseBody> call = service.uploadVideo("desc", requestBody);
call.enqueue(new Callback<ResponseBody>(){
#Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit)
{
// TODO Auto-generated method stub
if (response.isSuccess())
{
Log.i("mok","S");
ResponseBody rb = response.body();
}
else
{
Log.i("mok","F");
com.squareup.okhttp.ResponseBody rb = response.errorBody();
}
}
#Override
public void onFailure(Throwable t)
{
t.printStackTrace();
Log.i("mok",t.getCause()+"");
Log.i("mok","T");
finish();
}
});
}
}
Just I had to use File file = new File(decodableString). The error is gone (the question answered) so I posted this answer, but the solution for uploading the file is not working properly (that's another issue).
I am using the android lock pattern library for a project of mine when I print the output pattern in a toast I get all garbage values like [C245faa3a8
I got the library and the code from https://code.google.com/p/android-lockpattern/
here is my code.
public class PatternTest extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// This is your preferred flag
Intent intent = new Intent(LockPatternActivity.ACTION_CREATE_PATTERN,
null, getBaseContext(), LockPatternActivity.class);
startActivityForResult(intent, REQ_CREATE_PATTERN);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
char[] pattern = null;
switch (requestCode) {
case REQ_CREATE_PATTERN: {
if (resultCode == RESULT_OK) {
pattern = data
.getCharArrayExtra(LockPatternActivity.EXTRA_PATTERN);
}
break;
}// REQ_CREATE_PATTERN
}
Toast.makeText(getApplicationContext(),pattern.toString(),
Toast.LENGTH_LONG).show();
}
}
use new String(byte[]) instead of toString():
Toast.makeText(getApplicationContext(),new String(pattern),
Toast.LENGTH_LONG).show();