Android出现"Read-only file system"解决办法?

05-22

Android-出现Read-only file system的解决方法

输入命令:

代码如下
复制代码

mount -o remount rw /system

(每次都要执行一次)

有的朋友说是是“/”的问题,命令改为:adb push AlarmClock.apk systemapp 即“/”改为“”即可。 adb push 电脑路径 模拟器路径 在电脑路径中必须用“” 而模拟器中必须是“/” 并且模拟器的跟路径是是只读的

操作设备文件系统上的文件结果遇到"... Read-only file system"。

解决办法:

1. 最简单的,adb remount

2. 不行的话,adb shell su之后将文件系统remount为读写权限: mount -o rw,remount /system。出于安全考虑,记得完事后remount回只读: mount -o ro,remount /system

3. 和方法2类似,mount -o rw,remount -t ext3 /dev/block/mmcblk1p21 /system

1. 使用命令:adb push AlarmClock.apk /system/app
提示:

代码如下
复制代码
failed to copy 'AlarmClock.apk' to '/system/app/AlarmClock.apk': Read-only file system

我们知道安卓系统中通话时长应该是归Callog管,所以建议去查查ContactProvider,或者是TelephonyProvider

Service测试

可以的通话开始的时候启动Service 记录当前时间A, 然后stopSelf(); 另外在通话结束的时候再次启动一下Service,再次获得当前时间B, 然后把时间A和B进行比较处理

String time = Long.toString(比较后处理的时间)

然后调用

代码如下
复制代码
Toast.makeText(this, time, Toast.LENGTH_SHORT).show();

使之显示出来 ,再stopSelf();

获取联系人通话时间的长短java代码

代码如下
复制代码
Cursor cursor = getContentResolver().query(Calls.CONTENT_URI,
new String[] { Calls.DURATION, Calls.TYPE, Calls.DATE },
null,
null,
Calls.DEFAULT_SORT_ORDER);
MainActivity.this.startManagingCursor(cursor);
boolean hasRecord = cursor.moveToFirst();
long incoming = 0L;
long outgoing = 0L;
int count = 0;
while (hasRecord) {
int type = cursor.getInt(cursor.getColumnIndex(Calls.TYPE));
long duration = cursor.getLong(cursor.getColumnIndex(Calls.DURATION));
switch (type) {
case Calls.INCOMING_TYPE:
incoming += duration;
break;
case Calls.OUTGOING_TYPE:
outgoing += duration;
default:
break;
}
count++;
hasRecord = cursor.moveToNext();
}
Toast.makeText(MainActivity.this,
"共计 " + count + "次通话 . 总通话时长 " + (incoming + outgoing) + "秒. 其中接听 " + incoming + " 秒, 拔打 "
+ outgoing + " 秒.",
Toast.LENGTH_LONG).show();

创建数据库

Android 不自动提供数据库。在 Android 应用程序中使用 SQLite,必须自己创建数据库,然后创建表、索引,填充数据。Android 提供了 SQLiteOpenHelper 帮助你创建一个数据库,你只要继承 SQLiteOpenHelper 类,就可以轻松的创建数据库。SQLiteOpenHelper 类根据开发应用程序的需要,封装了创建和更新数据库使用的逻辑。SQLiteOpenHelper 的子类,至少需要实现三个方法:

•构造函数,调用父类 SQLiteOpenHelper 的构造函数。这个方法需要四个参数:上下文环境(例如,一个 Activity),数据库名字,一个可选的游标工厂(通常是 Null),一个代表你正在使用的数据库模型版本的整数。
•onCreate()方法,它需要一个 SQLiteDatabase 对象作为参数,根据需要对这个对象填充表和初始化数据。
•onUpgrage() 方法,它需要三个参数,一个 SQLiteDatabase 对象,一个旧的版本号和一个新的版本号,这样你就可以清楚如何把一个数据库从旧的模型转变到新的模型。
下面示例代码展示了如何继承 SQLiteOpenHelper 创建数据库:

代码如下
复制代码

public class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context, String name, CursorFactory cursorFactory, int version)
{
super(context, name, cursorFactory, version);
}

@Override
public void onCreate(SQLiteDatabase db) {
// TODO 创建数据库后,对数据库的操作
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO 更改数据库版本的操作
}

@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
// TODO 每次成功打开数据库后首先被执行
}
}

接下来讨论具体如何创建表、插入数据、删除表等等。调用 getReadableDatabase() 或 getWriteableDatabase() 方法,你可以得到 SQLiteDatabase 实例,具体调用那个方法,取决于你是否需要改变数据库的内容:

代码如下
复制代码
db=(new DatabaseHelper(getContext())).getWritableDatabase();
return (db == null) ? false : true;

上面这段代码会返回一个 SQLiteDatabase 类的实例,使用这个对象,你就可以查询或者修改数据库。

当你完成了对数据库的操作(例如你的 Activity 已经关闭),需要调用 SQLiteDatabase 的 Close() 方法来释放掉数据库连接。

android系统下每个程序的数据存放在 /data/data/(package name)/ 目录下,数据库则是在/dababases/目录下..
所以,你只要用FileInputStream读取原数据库,再用FileOutputStream把读取到的东西写入到那个目录就可以了..

操作方法:
1. 把原数据库包括在项目源码的 res/raw 目录下.
2.创建一个类来控制database..如下:

代码

代码如下
复制代码

public class DatabaseManager{
private final int BUFFER_SIZE = 400000;
public static final String DB_NAME = "myDatabase.db"; //保存的数据库文件名
public static final String PACKAGE_NAME = "com.android.ImportDBTest";//包名
public static final String DB_PATH = "/data"
+ Environment.getDataDirectory().getAbsolutePath() + "/"
+ PACKAGE_NAME; //在手机里存放数据库的位置

private SQLiteDatabase database;
private Context context;

DBManager(Context context) {
this.context = context;
}

public void openDatabase() {
this.database = this.openDatabase(DB_PATH + "/" + DB_NAME);
}

private SQLiteDatabase openDatabase(String dbfile) {
try {
if (!(new File(dbfile).exists())) {  //判断数据库文件是否存在,若不存在则执行导入,否则直接打开数据库
InputStream is = this.context.getResources().openRawResource(
R.raw.myDatabase); //欲导入的数据库
FileOutputStream fos = new FileOutputStream(dbfile);
byte[] buffer = new byte[BUFFER_SIZE];
int count = 0;
while ((count = is.read(buffer)) > 0) {
fos.write(buffer, 0, count);
}
fos.close();
is.close();
}
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile,
null);
return db;
} catch (FileNotFoundException e) {
Log.e("Database", "File not found");
e.printStackTrace();
} catch (IOException e) {
Log.e("Database", "IO exception");
e.printStackTrace();
}
return null;
}

然后在需要用到数据库的时候,用实例化一个DatabaseManager类,调用其openDatabase方法就可以返回一个
SQLiteDatabase对象了..如下:
代码

代码如下
复制代码

SQLiteDatabase db = new DBManager(this).openDatabase();