2016-07-06 99 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次這就是爲什麼我已經完成了這個轉換,它可以幫助我獲得所需的文件路徑。

試試這個我的朋友。

相關問題