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 @Override |
接下来讨论具体如何创建表、插入数据、删除表等等。调用 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) { public void openDatabase() { private SQLiteDatabase openDatabase(String dbfile) { |
然后在需要用到数据库的时候,用实例化一个DatabaseManager类,调用其openDatabase方法就可以返回一个
SQLiteDatabase对象了..如下:
代码
代码如下 |
复制代码 |
SQLiteDatabase db = new DBManager(this).openDatabase(); |