بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]
پرسش و پاسخ

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

مدیریت گفتگو
Vampire 11 سال پیش
آخرین تغییر: 11 سال پیش

من از یک کد ساده استفاده می کنم که داخل فروم هم وجود داره، و کارش اینه که در کلاس 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);
}
}

نظرات

jamal2012 11 سال پیش
کسی از دوستان جواب این دوستمونو نمیدونه مشکل منم هست
jamal2012 11 سال پیش
کسی از دوستان جواب این دوستمونو نمیدونه مشکل منم هست
javac 11 سال پیش
با یک سرچ تو stackoverflow به نتیجه میرسید//stackoverflow.com/questions/3382996/how-to-unzip-files-programmatically-in-android

پاسخ‌ها 3

hamidd 11 سال پیش

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

 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 سال پیش

من هم مثل شما از کدی استفاده میکونم که میگه اگر 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;
}
}
}

نظرات

jamal2012 11 سال پیش
البته اینم بگم فایل 9 مگی من وقتی زیپ میکونم تو بهترین حالت 2 مگ حجمشه
Vampire 11 سال پیش

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

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

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

نظرات

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

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