آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

زیپ و اکسترکت دیتابیس، بجای کپی مستقیم

Vampire  11 سال پیش  11 سال پیش
0 0

من از یک کد ساده استفاده می کنم که داخل فروم هم وجود داره، و کارش اینه که در کلاس G قرار می گیره و اگر sd کارت وجود داشته باشه دیتابیس رو درون اون کپی می کنه و در غیر این صورت درون حافظه داخلی.

دیتابیس من سنگینه (حدود 25 مگابایت هست) میخوام این دیتابیس رو زیپ کنم و در asset قرار بدم و با همین الگوریتم تست حافظه و کپی ، ابتدا فایل زیپ رو کپی کنم و بعد اکسترکت کنم و از دیتابیس استفاده کنم. چه تغییراتی باید روی کد اعمال بشه؟

 

packageName = context.getPackageName();

 try {
DIR_APP = DIR_SDCARD + "/android/data/" + packageName;
new File(DIR_APP).mkdirs();
AssetManager manager = context.getAssets();
InputStream inputStream;
File file = new File(DIR_APP + "/db.db");
if ( !file.exists()) {
inputStream = manager.open("db.db");
HelperIO.copyFile(inputStream, DIR_APP + "/db.db");

}
if (file.exists()) {
database = SQLiteDatabase.openDatabase(DIR_APP + "/db.db", null, 0);
}
}
catch (Exception e) {
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getDir("file", Context.MODE_PRIVATE);
directory.mkdirs();

File mypath = new File(directory, "/db.db");
AssetManager manager = context.getAssets();
InputStream inputStream = null;
if ( !mypath.exists()) {
try {
inputStream = manager.open("db.db");
}
catch (IOException e1) {
e1.printStackTrace();
}
HelperIO.copyFile(inputStream, mypath + "/db.db");

}
if (mypath.exists()) {
database = SQLiteDatabase.openDatabase(mypath + "/db.db", null, 0);
}
}
0 0
کسی از دوستان جواب این دوستمونو نمیدونه مشکل منم هست (11 سال پیش)
0 0
کسی از دوستان جواب این دوستمونو نمیدونه مشکل منم هست (11 سال پیش)
0 0
با یک سرچ تو stackoverflow به نتیجه میرسید//stackoverflow.com/questions/3382996/how-to-unzip-files-programmatically-in-android (11 سال پیش)
0 0
لینک (11 سال پیش)
 برای این سوال 3 پاسخ وجود دارد.
پاسخ به سوال 
hamidd  11 سال پیش
+2 0

بعد از این که فایل را در حافظه کپی کردید متد زیر را فراخوانی کنید:

 private static void unzip(String zipFilePath, String outputLocation)
throws IOException {
try {
File f = new File(outputLocation);
if (!f.isDirectory()) {
f.mkdirs();
}
ZipInputStream zin = new ZipInputStream(
new FileInputStream(
zipFilePath));
try {
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
String path = outputLocation + ze.getName();

if (ze.isDirectory()) {
File unzipFile = new File(path);
if (!unzipFile.isDirectory()) {
unzipFile.mkdirs();
}
} else {
FileOutputStream fout = new FileOutputStream(path,
false);
try {
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
} finally {
fout.close();
}
}
}
} finally {
zin.close();
}
} catch (Exception e) {
Log.e("LOG", "Unzip exception", e);
}
}

این متد دو تا وروردی داره که به آرگومان (ورودی) اول باید مسیر فایل زیپ را بدید و به آرگومان دوم باید مسیری که می خواید فایل زیپ تون اون جا اکسترکت بشه را باید بدید.

 

پاسخ به سوال 
jamal2012  11 سال پیش
0 0

من هم مثل شما از کدی استفاده میکونم که میگه اگر sd card بود بریز تو sd card اگر هم نبود بریز تو حافظه داخلی گوشی ولی هرکاری میکونم درست بشو نیست ارور های مختلف میگیرم چطور میتونم کدم رو با کد شما هماهنگ کنم ممنون میشم کمکم کنید این روزا خیلی گیرم خیلی !

 public class G extends Application {

public static Context context;
public static LayoutInflater inflater;
public static Handler HANDLER = new Handler();
public static Activity currentActivity;

public static SQLiteDatabase database;
public static StructApplication selectedApplication;
public static StructApplicationFav selectedApplicationFav;

public static final String DIR_SDCARD = Environment.getExternalStorageDirectory().getAbsolutePath();
public static String DIR_APP = DIR_SDCARD + "/my_database";


@Override
public void onCreate() {

super.onCreate();
context = getApplicationContext();
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);


new File(DIR_APP).mkdirs();

prepareDB();

}


private boolean prepareDB() {


try {
String state = Environment.getExternalStorageState();
InputStream is = context.getAssets().open("norooz.sqlite");

if (state.equals(Environment.MEDIA_MOUNTED))
{

File DB_PATH = new File(DIR_APP + "/norooz.sqlite");

Log.i("DB_PATHDB_PATHDB_PATHDB_PATHDB_PATHDB_PATH", "DB_PATH=" + DB_PATH);

if (DB_PATH.exists()) {

database = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
Log.i("databasedatabasedatabasedatabasedatabasedatabase", "database=" + database);

return true;

}
else {

if (copy(new FileOutputStream(DB_PATH), is)) {
database = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
return true;
}
else {
return false;
}
}
}
else {
Log.i("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "state=" + state);
DIR_APP = getFilesDir().toString();
File dbFile = new File(getFilesDir().toString() + "/" + "/norooz.sqlite");
if (dbFile.exists()) {
database = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
return true;
}
else {
FileOutputStream os = openFileOutput("norooz.sqlite", context.MODE_PRIVATE);
if (copy(os, is)) {
database = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
return true;
}
else {
return false;
}
}
}
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}


private boolean copy(OutputStream os, InputStream is) {
try {
int readed = 0;
byte[] buffer = new byte[8 * 1024];
while ((readed = is.read(buffer)) > 0) {
os.write(buffer, 0, readed);
}
try {
is.close();
}
catch (Exception e) {
e.printStackTrace();
}
try {
os.flush();
}
catch (Exception e) {
e.printStackTrace();
}
try {
os.close();
}
catch (Exception e) {
e.printStackTrace();
}
return true;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
0 0
البته اینم بگم فایل 9 مگی من وقتی زیپ میکونم تو بهترین حالت 2 مگ حجمشه (11 سال پیش)
پاسخ به سوال 
Vampire  11 سال پیش
0 0

 
من از کتابخونه ی: https://github.com/jgilfelt/android-sqlite-asset-helper
استفاده کردم مشکلم حل شد ولی الان یه مشکل کوچیک دارم

تا این دیتابیس کپی بشه روی گوشی کاربر تصویر صفحه سیاه باقی میمونه. چطوری می تونم یک progress هنگام کپی نمایش بدم ؟

کد های فراخوانی دیتابیس رو داخل کلاس G قرار دادم و در تمام کلاس ها فقط فراخوانی کردم

0 0
بخش تردها و همزمانی رو ببینید توضیح داده شده (11 سال پیش)
0 0
دیدم دوست عزیز، مشکل من اینجاست که میخوام درحالی که این دیتابیس کپی میشه یک پروکرس بار نمایش بدم ولی این کپی چون داخل کلاس G فراخوانی شده با اجرای برنامه شروع به کار میکنه و زمان می بره تا کپی بشه مخصوصاً روی دیوایس های ضعیف تر نزدیک 20 ثانیه زمان می بره و در این زمان صفحه سیاه می مونه تا کپی به اتمام برسه. توی کلاس G هم چون لایوتی نداریم، چیزی نمی تونیم نمایش بدیم. من حتی یک Toast ساده رو هم نمی تونم نمایش بدم. من یک ترد ساده رو هم تست کردم ولی متاسفانه برای بار اول که میخواد دیتابیس رو کپی کنه کرش میکنه و با اجرای دوم بالا میاد . (11 سال پیش)
+2 0
خوب به جای این که توی کلاس G کد ها رو بزارید توی یک اکتیویتی بزارید. یک splash screen درست کنید که بعد از کپی فایلها بسته بشه و اکتیویتی اولی برنامه رو اجرا کنه.ضمنا باید از ترد استفاده کنید تا برنامه نرم تر کار کنه و موقع کپی هنگ نکنه و progeressbar هم خوب نمایش داده بشه. (11 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .