ساخت database روی external storage اندروید 10+
سلام. ساخت دیتابیس روی external storage رو طبق آموزش های انجام دادم. در اندروید 9 و پایین تر هیچ مشکلی ندارم ولی در اندروید 10+ نه تنها دیتابیس ساخته نمیشه بلکه کلا هیچ فایلی روی external storage ساخته نمی شه. لطفا راهنمایی کنید.
manifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.miplan">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage">
</uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MiPlan">
<activity
android:name=".SplashActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="false" />
<activity
android:name=".LogoActivity"
android:exported="true">
</activity>
</application>
</manifest>
//MyDatabaseHelper.java :
package com.example.miplan;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class MyDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "myDatabase.SqLite";
private static final int DB_VERSION = 1;
public MyDatabaseHelper(@Nullable Context context) {
super(context, SplashActivity.DB_DIR + "/" + DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String query = " CREATE TABLE 'person' (" +
"'personId' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , " +
"'firstName' TEXT, " +
"'lastName' TEXT, " +
"'gender' INTEGER, " +
"'email' TEXT UNIQUE, " +
"'phoneNumber' TEXT UNIQUE)";
//db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
//SplashActivity.java :
package com.example.miplan;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
@SuppressLint("CustomSplashScreen")
public class SplashActivity extends AppCompatActivity {
public static String SDCARD = Environment.getExternalStorageDirectory().getAbsolutePath();
public static String BRAND = SDCARD + "/Self-learn";
public static String APP_DIR = BRAND + "/MiPlan";
public static String DB_DIR = APP_DIR + "/db";
public static SQLiteDatabase database;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_begin);
int grantResult = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (grantResult == PackageManager.PERMISSION_GRANTED) {
createAppDir();
} else {
askUserForPermission();
}
}
private void askUserForPermission() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 100:
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("خطا").setMessage("دسترسی به حافطه خارجی برای این برنامه ضروری است").setPositiveButton("دوباره بپرس", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
askUserForPermission();
}
}).setCancelable(false).create().show();
} else {
createAppDir();
}
break;
}
}
private void createAppDir() {
File file = new File(DB_DIR);
if (!file.exists()) {
file.mkdirs();
createDatabase();
}
createDatabase();
}
public void createDatabase() {
MyDatabaseHelper dbHelper = new MyDatabaseHelper(SplashActivity.this);
database = dbHelper.getWritableDatabase();
Log.i("testtt", "this line is working well...");
openWelcomeActivity();
}
private void openWelcomeActivity() {
Intent intent = new Intent(this, LogoActivity.class);
startActivity(intent);
this.finish();
}
ارور لاگ کت هم اینه : Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14 SQLITE_CANTOPEN): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)

با سلام، من خودم تا جایی ک میدونم روی اندروید های 10 به بالا میخاید فایل ذخیره کنید یکم حساس تره قبل شده... البته تو این روش دیگ نمیخاد از کاربر مجوز بگیرین ک ذخیره کنم یا نکنم فقط کافیه مجوز رو داخل منیفیست ذکر کنید.. ولی یکم محدودیت داره میتونید داخل داکیومنت های خود گوگل مطالعه کنید..
ولی با استفاده از ادرس های زیر میتونید رو این ادرس ها ذخیره کنید فایل هاتون رو و بخونید..
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)
و مسیر های دیگ که میتونید لیستشو مشاهده کنید برروی حافظه فایل ذخیره کنید. من دوتا نمونه مسیر رو براتون گذاشتم.
یعنی این بخش کدتون:
public static String SDCARD = Environment.getExternalStorageDirectory().getAbsolutePath();
به این شکل تغییر کنه:
public static String SDCARD = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
موفق باشید
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .