-3

Env desc: Androidバージョン:6.0.1、DBはお客様が作成し、外部ストレージに保存されており、タスク完了後にSqlite DBのデータが収集されます。外部SDカードに格納されたSQLite DBを記述できますか? SOS

異なるサービス論理ごとにdbを読み書きする必要があります。

問題:

Could not open the database in read/write mode. 

java.lang.RuntimeException: Failure delivering result ResultInfo{[email protected]:requestPermissions:, request=10, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.example.xx.sqlitedemo/com.example.xx.sqlitedemo.MainActivity}: 
android.database.sqlite.SQLiteException: not an error (code 0): Could not open the database in read/write mode. 

コード:

SQLiteDatabase.openOrCreateDatabase 

権限が要求されています

new File(dbpath).exists(); 

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

DBファイルをデバッグモードでコードを下回ることにより、チェック存在しています

DBPATHがある:

"/storage/4B53-98D9/System/System.db" 

ダイナミック権限を持っている、問題がまだ存在していました。

のAndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.xx.sqlitedemo"> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
    <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/> 
    <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/> 
    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity android:name=".MainActivity"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

MainActivity.java

2017年3月5日に更新
package com.example.xx.sqlitedemo; 

import android.Manifest; 
import android.content.Context; 
import android.content.ContextWrapper; 
import android.content.pm.PackageManager; 
import android.database.Cursor; 
import android.database.DatabaseErrorHandler; 
import android.database.DefaultDatabaseErrorHandler; 
import android.database.sqlite.SQLiteCursor; 
import android.database.sqlite.SQLiteCursorDriver; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteDatabaseCorruptException; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.database.sqlite.SQLiteQuery; 
import android.os.Build; 
import android.os.Environment; 
import android.support.annotation.NonNull; 
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.widget.Toast; 

import java.io.File; 

public class MainActivity extends AppCompatActivity { 

    private static final int EXTERNAL_STORAGE_REQ_CODE = 10; 
    private static final int MOUNT_UNMOUNT_FILESYSTEMS = 20; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
//  requestMountPermission(); 
     requestStoragePermission(); 

     int o = 0; 
    } 


    private void requestMountPermission() { 

     if (ContextCompat.checkSelfPermission(this, Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) != PackageManager.PERMISSION_GRANTED) { 

      if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)) { 
       Toast.makeText(this, "please give me the permission", Toast.LENGTH_SHORT).show(); 
      } else { 
       ActivityCompat.requestPermissions(this, 
         new String[]{Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS}, 
         MOUNT_UNMOUNT_FILESYSTEMS); 
      } 
     } else { 
      requestStoragePermission(); 
      int i = 1; 
     } 
    } 

    public void requestStoragePermission() { 

     if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { 

      if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { 
       Toast.makeText(this, "please give me the permission", Toast.LENGTH_SHORT).show(); 
      } else { 

       ActivityCompat.requestPermissions(this, 
         new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 
         EXTERNAL_STORAGE_REQ_CODE); 
      } 
     } else { 
      openSQLiteDataBase(); 
      int i = 1; 
     } 
    } 

    private void openSQLiteDataBase() { 
     //   SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase("/storage/4B53-98D9/System/System.db", new CustomCursorFactory(), new CustomDbErrorHandler()); 
     DatabaseHelper helper = new DatabaseHelper(this,"System.db"); 
     SQLiteDatabase database = helper.getReadableDatabase(); 
     int ii = 0; 
     Cursor cursor = database.query(null,null,null,null,null,null,null,null); 

     database.close(); 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
     switch (requestCode) { 
      case EXTERNAL_STORAGE_REQ_CODE: 
       if (grantResults.length > 0 
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

        openSQLiteDataBase(); 

        // permission was granted, yay! Do the 
        // contacts-related task you need to do. 

       } else { 

        // permission denied, boo! Disable the 
        // functionality that depends on this permission. 
       } 
      break; 
      case MOUNT_UNMOUNT_FILESYSTEMS: 

       break; 
     } 

    } 

    class CustomCursorFactory implements SQLiteDatabase.CursorFactory { 
     @Override 
     public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery, String editTable, SQLiteQuery query) { 
      if (Build.VERSION.SDK_INT < 11) { 
       return new SQLiteCursor(db, masterQuery, editTable, query); 
      } else { 
       return new SQLiteCursor(masterQuery, editTable, query); 
      } 
     } 
    } 

    class CustomDbErrorHandler implements DatabaseErrorHandler { 
     DefaultDatabaseErrorHandler __d = new DefaultDatabaseErrorHandler(); 
     boolean __once = false; 

     @Override 
     public void onCorruption(SQLiteDatabase dbObj) { 
      if (__once) { 
       throw new SQLiteDatabaseCorruptException("db corrupted and cannot be recovered"); 
      } 

      __once = true; 
      __d.onCorruption(dbObj); 
     } 
    } 
    class DatabaseContext extends ContextWrapper { 

     private static final String DEBUG_CONTEXT = "DatabaseContext"; 

     public DatabaseContext(Context base) { 
      super(base); 
     } 

     @Override 
     public File getDatabasePath(String name) { 
      File sdcard = Environment.getExternalStorageDirectory(); 
      String path = this.getFilesDir().getAbsolutePath(); 
      String dbfile = "/storage/4B53-98D9/System/System.db"; //sdcard.getAbsolutePath() + File.separator+ "databases" + File.separator + name; 
      if (!dbfile.endsWith(".db")) { 
       dbfile += ".db" ; 
      } 

      File result = new File(dbfile); 

      if (!result.getParentFile().exists()) { 
       result.getParentFile().mkdirs(); 
      } 

      return result; 
     } 

     /* this version is called for android devices >= api-11. thank to @damccull for fixing this. */ 
     @Override 
     public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) { 
      return openOrCreateDatabase(name,mode, factory); 
     } 

     /* this version is called for android devices < api-11 */ 
     @Override 
     public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) { 
      SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null); 
      // SQLiteDatabase result = super.openOrCreateDatabase(name, mode, factory); 
       Log.w(DEBUG_CONTEXT, "openOrCreateDatabase(" + name + ",,) = " + result.getPath()); 
      return result; 
     } 
    } 

    public class DatabaseHelper extends SQLiteOpenHelper { 
     private static final int DATABASE_VERSION = 1; 

     DatabaseHelper(final Context context, String databaseName) { 
      super(new DatabaseContext(context), databaseName, null, DATABASE_VERSION); 
     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 

     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

     } 
    } 
} 

@greenappsが提供する方法は危険です:

Have a look at getExternalFilesDirs(). Look at the second item returned. 

That would then look like "/storage/4B53-98D9/Android/data/<package>/files/System.db". 

uninstaアプリでは、同時にデータが削除されました。

/storage/4B53-98D9/Android/data/<package> was deleted. 

誰もが私の質問に答えることができますか?

ありがとうございます!許可を要求するための

+0

marshmallow – user2025187

+0

のアクセス許可を確認すると、実行時のアクセス許可を与える必要があります。また、アプリの設定からアプリケーションにアクセス許可を与えることもできます。 – LearnPainLess

+2

[Android Marshmallow 6.0の実行時にリクエストパーミッション]の可能な複製(http://stackoverflow.com/questions/34150083/request-permission-at-runtime-for-android-marshmallow-6-0) –

答えて

0

、次のコード試してみてください。..

//check for WRITE_EXTERNAL_STORAGE permission 
     int hasAccessExternalStoragePermission = ContextCompat.checkSelfPermission(LoginActivity.this, 
       Manifest.permission.WRITE_EXTERNAL_STORAGE); 

    if (hasAccessExternalStoragePermission != PackageManager.PERMISSION_GRANTED) { 
     ActivityCompat.requestPermissions(LoginActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 
       REQUEST_CODE_ASK_PERMISSIONS); 
    } 

そして、次のようにそれを処理..

@Override 
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
     switch (requestCode) { 
      case REQUEST_CODE_ASK_PERMISSIONS: 
       if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
        Log.e(TAG, "Permission Granted...."); 
        createFile(); 
       }else{ 
        Log.e(TAG, "Permission Not Granted...."); 
       } 
     } 
    } 

私はあなたがこの方法shouldShowRequestPermissionRationaleを使用しているため、問題が来ていると思います。この方法の場合は、使用法をお読みくださいhere

+0

私たちはダイナミックパーミッションを取得しています... – Bob

+0

ダイナミックパーミッションを要求してコードを投稿してください... – Rohit

+0

すべてのコードが更新されました、ありがとう〜 – Bob

0

SDカードは読み取り専用ですので、書き込みモードで開くことができないというメッセージが表示されます。

あなたのアプリが書き込めるSDカードのアプリ固有のディレクトリにdbファイルを置くことができます。

getExternalFilesDirs()をご覧ください。返される2番目の項目を見てください。

これは"/storage/4B53-98D9/Android/data/<package>/files/System.db"のようになります。

+0

@gerenapps、お寄せいただきありがとうございます。はい、あなたは正しいです、それは今働きます。しかし、私は顧客にそれを提供することはできません、あなたは他の提案がありますか? – Bob

+0

なぜあなたは突然顧客に提供できないのですか? – greenapps

+0

お客様はdbを設定し、自己のパスを使用しますが、お客様はAndroid/data/com.xx.xxx.xx/files/system.dbのようなパスにデータを保存するのは混乱します。あなたの解決策は、顧客のための回避策のように、それは開発者にとっては大丈夫です。 – Bob

関連する問題