I'm working on a mediaplayer application and am trying to have some default songs get put on the phone in case the user doesn't have any on their phone (I'm pulling the list of actual songs via mediastore).
So I have the songs put in the res/raw folder and fun the following code to copy them. It seems to be copying ok (since astro file browser and other apps see them fine) but the mediastore still can't find them.
I think it's something with the permissions on the file but I'm not sure what. Anybody know why?
InputStream song = getResources().openRawResource(R.raw.aquarel);
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), "aquarel.mp3");
Log.e(TAG, "File1: " + file.getPath());
OutputStream copySong = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int readvalue = 0;
readvalue = song.read(buffer);
while (readvalue > 0) {
copySong.write(buffer, 0, readvalue);
readvalue = song.read(buffer);
}
copySong.close();
"When you add files to Android’s filesystem these files are not picked
up by the MedaScanner automatically.
...
If you want your files to be added to the media library, you can do so
either by using the MediaStore content provider, or by using the
MediaScanner."
You can add them by sending a broadcast:
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
sendBroadcast(intent);
(Source)
Related
I have a number of pdf files (but I might extend the functionality to other document types as well) that I want to show in my app. Static images go in drawable folder, static text goes in the strings file. But where do I put pdf files?
I know I can host it on a server and have a one-time-download kind of thing, but for my app's use case that's impossible. The app is being designed for a very specific use case in mind and I absolutely need to bundle the pdf files along with the app.
Create directory named assets in your app and put your pdf files in that directory. use this to read and display pdf files.
I think you can keep your PDF file (or any other file type) inside assets folder. So while downloading the APK form store, it will download those files too. Only problem is it will increase the APP size.
Check the below answer how you can access the PDF file from the Assets using assetManager
https://stackoverflow.com/a/17085759/7023751
I'm answering my own question because other answers didn't fully work for me.
Like the other answers, I read the file from assets folder and created a file in internal storage. I used muPDF which works perfectly with file URI.
items is an ArrayList of file names.
try
{
AssetManager assetManager = getAssets();
InputStream in = assetManager.open(items.get(position));
byte[] buffer = new byte[in.available()];
in.read(buffer);
File targetFile = new File(getFilesDir(), items.get(position));
OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);
in.close();
outStream.flush();
outStream.close();
//Change below intent statements as per your code
Intent intent = new Intent(this, DocumentActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.fromFile(targetFile));
startActivity(intent);
}
catch (Exception e)
{
e.printStackTrace();
}
To be as succinct as possible:
-APK file is not corrupt.
-I can browse to the APK in the phone's file system and manually install it from there without issue.
-I am using the following code to kick off the install process. File location is confirmed correct:
public void installfromlocal()
{
String downloadfilelocation = getsharedresourcestring("updatepackagelocation");
Log.e("installing from",downloadfilelocation);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(downloadfilelocation)), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
So far what I could gather from a couple hours on the internet is that apparently I can't make my app install an APK programmatically from external storage. I can also apparently not copy the file to internal storage and install from there.
So what now? Additionally, I get no messages from Logcat. I only get a popup alerting me that there was an error parsing the apk.
I found a solution for me (not so clear why have this issue, but i solve it).
It seems to me that when downloading with DownloadManager you cant access to the downloaded file via URI, and you get access denied (and various file not found exception error) that's why PackageInstaller cannot read at all the manifest (and that's the parse error).
This is what i did, i hope that resolve you problem as well, i know it's not elegant to say the least.
Because of DownloadManager.COLUMN_LOCAL_FILENAME is deprecated i tried with COLUMN_LOCAL_URI to access the file and access its content (q is Cursor)
String strUri = q.getString(q.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
Uri apkUri = Uri.parse(strUri);
with this uri i can access and copy the file to a temp file in getExternalCacheDir()
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(apkUri, "r");
InputStream inFile = new FileInputStream(pfd.getFileDescriptor());
OutputStream outFile = new FileOutputStream(tmpFile);
//copy
byte[] buffer = new byte[1024];
int length;
while ((length = inFile.read(buffer)) > 0) {
outFile.write(buffer, 0, length);
}
outFile.flush();
inFile.close();
outFile.close();
Grab the file created and get its uri (that is accessible) and start the activity with that uri.
I hope it helps
You should use canonical path of the file. From the docs-
A canonical pathname is both absolute and unique. The precise definition of canonical form is system-dependent. This method first converts this pathname to absolute form if necessary, as if by invoking the getAbsolutePath() method, and then maps it to its unique form in a system-dependent way. This typically involves removing redundant names such as "." and ".." from the pathname, resolving symbolic links (on UNIX platforms), and converting drive letters to a standard case (on Microsoft Windows platforms).
I need to download some pdf files into data/data/com.**.* folder.
Those files are application specific and only application should read and display it that's the reason storing on data/data/com.**.* folder.
Please let me know how to download into that folder and open/read it in the application.
I know how to download it into SD card, but I do not have idea to downloading to application specific folder.
Please let me know some code examples to do this and also I need to know the capacity/size of the data/data/com.**.* folder.
As long as you want write your own applications Data folder, you can create a FileOutputStream like this FileOutputStream out = new FileOutputStream("/data/data/com.**.*/somefile"); than use that output stream to save file. Using the same way you can create a FileInputStream and read the file after.
You will get Permission Denied if you try to access another application's data folder.
I am not sure for capacity but you can calculate the size of the data folder using this
File dataFolder = new File("/data/data/com.**.*/");
long size = folderSize(dataFolder);
...
public static long folderSize(File directory) {
long length = 0;
for (File file : directory.listFiles()) {
if (file.isFile())
length += file.length();
else
lengthlong += folderSize(file);
}
return length;
}
Hi here i am attaching the link of a tutorial explained.
http://www.mysamplecode.com/2012/06/android-internal-external-storage.html
and there are many discussions going on internet that you should root your phone in order to access the data from data/data folder and I am also attaching some links about the discussion, I hope these are also some of the links that are related to your question
where do i find app data in android
How to access data/data folder in Android device?
and as well as some links that makes out the things without rooting your phone i mean
You can get access to /data/data/com*.* without rooting the device
http://denniskubes.com/2012/09/25/read-android-data-folder-without-rooting/
To Write file
FileOutputStream out = new FileOutputStream("/data/data/your_package_name/file_name.xyz");
To Read file
FileInputStream fIn = new FileInputStream(new File("/data/data/your_package_name/file_name.xyz"));
Now you have your input stream , you can convert it in your file according to the file type .
I am giving you example if your file is contain String data the we can do something like below ,
BufferedReader myReader = new BufferedReader(
new InputStreamReader(fIn));
String mDataRow = "";
String mBuffer = "";
while ((mDataRow = myReader.readLine()) != null) {
mBuffer += mDataRow + "\n";
}
Remember to add write file permission to AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
im trying to play a video from the raw folder with phonegap.
I modified the original plugin a little bit.
this is the code:
Uri uri = Uri.parse( "android.resource://" + getPackageName() + "/raw/"+R.raw.test);
// Uri uri = Uri.parse("http://www.test.sociato.de/test.mp4");
Intent intent = null;
// Display video player
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "video/*");
this.ctx.startActivity(intent);
The video is in the raw folder and is named test.mp4.
The code doesnt work.
I think that the url to the video isnt correct?
I would be very pleased of any help.
I wrestled with this one for awhile. The only way I could play a video from an Android resource was to copy it first to the sdcard. Here's my code:
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/myfolder");
if(dir.isDirectory() != true) {
dir.mkdirs();
InputStream ins = getResources().openRawResource(R.raw.myvid);
int size = ins.available();
// Read the entire resource into a local byte buffer.
byte[] buffer = new byte[size];
ins.read(buffer);
ins.close();
FileOutputStream fos = new FileOutputStream(new File(dir, "myvid.m4v"));
fos.write(buffer);
fos.close();
}
File myvid = new File(dir, "myvid.m4v");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(myvid), "video/*");
this.startActivity(intent);
I think you can't play video from application's private package to default video player,Because your default video player can't recognize this path.
To make it play you have to copy this video file in sdcard and then give URI of that file, in this case it works fine.
I have successfully played a video file that I loaded into the res/raw folder directly from that resource.
This was done in
Android 1.5
API Level 3
The file size was below 50M
My code snippet is as follows
Uri video= Uri.parse("android.resource://MYPACKAGENAME/" + R.raw.presence);
videoView.setMediaController(mediaController);
videoView.setVideoURI(video);
videoView.start();
The main issue I saw occurring was getting App to recognize the mp4 file in the raw folder
I am new to android development but this is what I did I hope it helps.
In the first line as I typed "R.raw" Eclipse showed it as an error I typed the period and expected Eclipse to show me a quick list of the resources but it was not there.
I read in another post to do a clean on the project and the resource list would be refreshed when I clicked PROJECT - CLEAN the resource was identified.
Another thing that I believe is required is that the file name MUST be lowercase only.
When it was in mixed case it would not show up.
Hope this helps.
This code from above:
Uri video= Uri.parse("android.resource://MYPACKAGENAME/" + R.raw.presence);
videoView.setMediaController(mediaController);
videoView.setVideoURI(video);
videoView.start();
worked great for me!
MYPACKAGENAME = full package name to work. I got stuck here for minute.
I have an Android (2.2) project in Eclipse (Helios). I want to add an MP3 file to the project so that the MP3 file is deployed to the device along with the application.
I then would like to open the file as a File object, which means I'd need to know the full path (?) to the file on the device, but I don't know how paths are specified in Android.
Apparently there is a bug in Froyo that prevents WAV playback.
Audio files should be placed in the "res/raw" directory of your project. Then use the id to play it (or attempt to play it)
MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_file_1);
mp.start();
Info: http://developer.android.com/guide/topics/media/index.html
Example (mp3): http://www.helloandroid.com/tutorials/musicdroid-audio-player-part-i
Ok, I saw this on the source of another projet, so I didn't really come up with it, but it works.
To add any file to a project, and later be able to use it, you need to put the file (binary, xml, or whatever) on the assets folder of your project.
In this example I will just copy the asset to the filesystem, so I can later access it as any other user file. You can access the assets directly too, take a look at Resources on the documentation.
public void copyfile(String fileName)
{
if (!new File(fileName).exists()){
try
{
InputStream localInputStream = getAssets().open(fileName);
FileOutputStream localFileOutputStream = getBaseContext().openFileOutput(fileName, MODE_PRIVATE);
byte[] arrayOfByte = new byte[1024];
int offset;
while ((offset = localInputStream.read(arrayOfByte))>0)
{
localFileOutputStream.write(arrayOfByte, 0, offset);
}
localFileOutputStream.close();
localInputStream.close();
// The next 3 lines are because I'm copying a binary that I plan
// to execute, so I need it to have execute permission.
StringBuilder command = new StringBuilder("chmod 700 ");
command.append(basedir + "/" + paramString);
Runtime.getRuntime().exec(command.toString());
Log.d(TAG, "File " + paramString + " copied successfully.");
}
catch (IOException localIOException)
{
localIOException.printStackTrace();
return;
}
}
else
Log.d(TAG, "No need to copy file " + paramString);
}
I believe there is probably a better way to copy the file, but this one works, and does not slow down my app even if it's called from onCreate (all files I copy are below 100kb though, so for bigger files, you probably want a separate thread)
Here is how to get the path to your files:
String path = getBaseContext().getFilesDir().getAbsolutePath();
If you want to write the file to another path, say "/sdcard/DCIM/appPictures", I believe you can use this code:
FileOutputStream outFile = FileOutputStream("/sdcard/DCIM/appPictures/" + fileName);
and then copy it byte by byte like in the example above.