2016-07-06 102 views
3

我创建一个应用程序仅用于私人用途......这不是那么重要,那么,尊重你的时间:PAndroid应用无法读取外部存储文件

我想提出的是一个应用程序,从数据库读取并播放声音。我已经创建了数据库,并且能够从res/raw文件夹中播放声音。但是,有数以千计的文件可以播放,并且一些新文件将成为应用程序的一部分,而其他文件将在未来删除。所以,添加一个简单的文件会让我每次下载整个应用程序(〜1 GB)(或者我错了?)。相反,我想读一个Excel文件,然后从SD卡播放声音。但是我不能......据我所知:

应用程序不允许写(删除,修改...)到外部存储 除了其特定的软件包的目录。

我把文件放到/存储/模拟/ 0 /安卓/数据/ my_package_folder /文件夹。我读过很多话题,没有任何帮助。

Environment.MEDIA_MOUNTED.equals(extStorageState) //returns true 
Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState) //returns false 

我试图创建新的文件对象或与媒体播放器播放声音的一些方法(如我以前说过的,有摆弄RES/RAW文件没问题),但file.exists总是返回虚假或声音不玩:

String filePath = getExternalFilesDir(null) + "/myfile.mp3"; //returns correct file path 
File file = new File(filePath); 

OR

File file = new File(getExternalFilesDir(null).getPath(), "myfile.mp3"); 

OR

MediaPlayer mp; 
mp = MediaPlayer.create(this, Uri.parse(getExternalFilesDir(null).getPath() + "/myfile.mp3")); 

中的minSdkVersion设置为19,所以我并不需要在清单该行:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

我已经包含了该行并没有什么改变:

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> 

我也试图与其他文件扩展名一起做。另外,从here解决方案没有帮助。我的手机是Samsung Galaxy Grand Prime(SM-G530FZ),Android v 5.0.2。请帮助! :)

+0

什么是你的targetSdk? – Nisarg

+0

targetSdkVersion 23 – kuznikowski

+0

检查我的答案是否有帮助:) – Nisarg

回答

0

您还必须具有权限READ_EXTERNAL_STORAGE;无论是写或读是不够的,当涉及到外部存储,你必须同时使用

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

您也可以阅读更多关于外部数据的declaration

写你看不懂的原因是因为您没有添加该权限。一个很好的规则是如果你只需要读取,只能使用读权限。但是,如果你需要写您需要的写入和读取权限

编辑:

当装载目录,试试这个:

file.setReadable(true); 
file.setWritable(true); 

注:值“文件”这里是目录,不是每个单独的文件(所有虽然工作正常)

从声明:

此权限从API级别19开始执行。在API级别19之前,未强制执行此权限,并且所有应用程序仍有权从外部存储读取数据。

如果我是正确的,这意味着允许必须是从API 19有及以上,但不API前19

+0

API 19,我不需要它......但好的,我再次检查过它,添加了WRITE和READ权限,没有任何帮助。 – kuznikowski

+0

你尝试过file.setReadable和file.setWritable吗? – Zoe

+0

那么,我在那里找到 - https://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE - “从API级别19开始,不需要此权限来读取/写入文件您的应用程序特定目录“ 编辑: 是的,setReadable和setWritable没有帮助。 – kuznikowski

1

如果您targetSdk是23比你要检查权限这样的棉花糖和上述装置

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { 
    checkPermission(); 
} 
else { 
} 


private void checkPermission() { 
     if (ContextCompat.checkSelfPermission(this, 
       Manifest.permission.WRITE_EXTERNAL_STORAGE) 
       != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, 
      Manifest.permission.READ_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED) {//Can add more as per requirement 

      ActivityCompat.requestPermissions(this, 
        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, 
        123); 

     } else { 

     } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, 
            String permissions[], int[] grantResults) 
    { 
    switch (requestCode) { 
     case 123: { 


if (grantResults.length > 0 
        && grantResults[0] == PackageManager.PERMISSION_GRANTED)  { 
    //Peform your task here if any 
    } else { 

     checkPermission(); 
    } 
     return; 
    } 
} 
} 
+0

您的意思是在那个开关中您的意思是“default”而不是“else”?不,没有什么改变;( – kuznikowski

+0

@kuznikowski检查编辑的答案对不起,这是我的错误 – Nisarg

+0

该死的,我是新来的,需要问一个愚蠢的问题......第一个IF必须放在我的onCreate void我猜?返回false所以其余的代码不会执行 – kuznikowski

4

下面是代码@Nisarg,不得不清洁一点:

import android.Manifest; 
import android.content.pm.PackageManager; 
import android.media.MediaPlayer; 
import android.os.Build; 
import android.os.Bundle; 
import android.os.Environment; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.Toast; 

import java.io.File; 

public class MainActivity extends AppCompatActivity implements OnClickListener { 

Button readExcelButton; 
static String TAG = "ExelLog"; 
MediaPlayer mpintro; 

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

    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { 
     Toast.makeText(this, "Permission checking", Toast.LENGTH_SHORT).show(); 
     checkPermission(); 
    } 

    readExcelButton = (Button) findViewById(R.id.readExcel); 
    readExcelButton.setOnClickListener(this); 

} 

public void onClick(View v) 
{ 
    switch (v.getId()) 
    { 
     case R.id.readExcel: 
      String filePath = getExternalFilesDir(null) + "/p0000.mp3"; 
      File file = new File(filePath); 
      file.setReadable(true); 
      file.setWritable(true); 

      if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) { 
       Toast.makeText(this, "Ext storage not available or read only", Toast.LENGTH_SHORT).show(); 
      } 
      else { 
       Toast.makeText(this, "Ext storage available", Toast.LENGTH_SHORT).show(); 
      } 

      if (file.exists()){ 
       Toast.makeText(this, "File found", Toast.LENGTH_SHORT).show(); 
      } 
      else { 
       Toast.makeText(this, getExternalFilesDir(null) + "/p0000.mp3 - File not found", Toast.LENGTH_LONG).show(); 
      } 

      break; 
    } 
} 

private void checkPermission() { 
    if (ContextCompat.checkSelfPermission(this, 
      Manifest.permission.WRITE_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, 
      Manifest.permission.READ_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED) {//Can add more as per requirement 

     ActivityCompat.requestPermissions(this, 
       new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, 
       123); 

    } else { 

    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case 123: { 

      if (grantResults.length > 0 
        && grantResults[0] == PackageManager.PERMISSION_GRANTED)  { 
       //Peform your task here if any 
      } else { 

       checkPermission(); 
      } 
      return; 
     } 
    } 
} 

public static boolean isExternalStorageReadOnly() { 
    String extStorageState = Environment.getExternalStorageState(); 
    if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) { 
     return true; 
    } 
    return false; 
} 

public static boolean isExternalStorageAvailable() { 
    String extStorageState = Environment.getExternalStorageState(); 
    if (Environment.MEDIA_MOUNTED.equals(extStorageState)) { 
     return true; 
    } 
    return false; 
} 

}

0
MyMediaPlayer=MediaPlayer.create(this,Uri.parse(String.valueOf(Uri.fromFile(f)))); 

在这个MyMediaPlayerMediaPlayer,||ly f对象是该文件 的对象,我们转换为URI,然后再URI串并最终字符串URI。

我这样做是因为当我们选择我们的选择路径时,它需要/// 3times /,但它只需要2次这就是为什么我已经完成了这个转换,它可以帮助我获得所需的文件路径。

试试这个我的朋友。

相关问题