Get alarm infomation and changing it in android 4.

2019-02-16 03:23发布

i am trying to retrieve alarm information from content provider using following code

final String tag_alarm = "tag_alarm";
Uri uri = Uri.parse("content://com.android.deskclock/alarm")
Cursor c = getContentResolver().query(uri, null, null, null, null);
Log.i(tag_alarm, "no of records are" + c.getCount());
Log.i(tag_alarm, "no of columns are" + c.getColumnCount());
if (c != null) {
    String names[] = c.getColumnNames();
    for (String temp : names) {
        System.out.println(temp);
    }
    if (c.moveToFirst()) {
        do {
            for (int j = 0; j < c.getColumnCount(); j++) {
                Log.i(tag_alarm, c.getColumnName(j);
                        + " which has value " + c.getString(j));
            }
        } while (c.moveToNext());
    }
}

it is giving me error permission denial i copied this code from curious answer from query Get alarm infomation in the Nguyen's comment he pointed a solution "If i embed this code in Android source code and run image file, it can pass "permission denied" error and retrieve alarm information. Anyway, thanks your tip :) " how to embed a code in android source code and run image file ?? please explain i always create a project in eclipse and then code and run it as run application.please explain this trick

3条回答
SAY GOODBYE
2楼-- · 2019-02-16 04:14

Look at the definition of the content provider in AndroidManifest.xml

<provider android:name="AlarmProvider"
                android:authorities="com.android.deskclock"
                android:exported="false" />

The exported is false, which means a 3rd-party app cannot access it. Permission denial as a result.

how to embed a code in android source code and run image file

It means you modify the Android source(Provided by google). I don't think it's useful in your case.

You can do that in a rooted device, by directly modify the contents in sqlite database. I don't think there is a solution to work on all existing Android platforms.

In general, sqlite database files are under /data/data/app-package-name/databases/database-name, so in this example, it should be /data/data/com.android.deskclock/databases/com.android.deskclock or something similar. You can pull the file out by adb pull and open it using SqliteExplorer to check whether it is what you want.

For how to modify this db file, check Using your own SQLite database in Android applications

查看更多
萌系小妹纸
3楼-- · 2019-02-16 04:18

In my opinion, because of each manufacturer had implemented their own Clock App, So default AlarmClockApp of Android will be replaced depend on each manufacturer, that makes your code can not be run successful if Android Os had been modified by Manufacturers. So I think we can not handle all the devices in this case, instead of that, we should handler it by manufacturer of devices. With Samsung devices, it's ClockPackage and in androidManifest :

   <provider
        android:name=".alarm.AlarmProvider"
        android:authorities="com.samsung.sec.android.clockpackage"
        android:exported="true"
        android:readPermission="com.sec.android.app.clockpackage.permission.READ_ALARM"
        android:writePermission="com.sec.android.app.clockpackage.permission.WRITE_ALARM" >
    </provider>

So we can read data of alarm in Samsung devices by :

add permission in manifest:

<uses-permission android:name="com.sec.android.app.clockpackage.permission.READ_ALARM" />

then get Uri by below :

Uri uri = Uri.parse("content://com.samsung.sec.android.clockpackage/alarm");

Use Uri :

    Cursor c = getContentResolver().query(uri, null, null, null, null);
    if (c == null) { // that mean devices is not belong to Samsung manufacturer,
                    // we should use an other uri (don't for get to add permission)
        AlarmLog.w("Can not read cursor");

    }
    AlarmLog.i(tag_alarm, "no of records are " + c.getCount());
    AlarmLog.i(tag_alarm, "no of columns are " + c.getColumnCount());
    if (c != null) {
        String names[] = c.getColumnNames();
        for (String temp : names) {
            AlarmLog.d(tag_alarm, temp);
        }
        if (c.moveToFirst()) {
            do {
                for (int j = 0; j < c.getColumnCount(); j++) {
                    AlarmLog.i(tag_alarm, c.getColumnName(j)
                            + " which has value " + c.getString(j));
                }
            } while (c.moveToNext());
        }
    }

Hope it's helpful and receive code for others manufactures.

查看更多
Melony?
4楼-- · 2019-02-16 04:20

As said there's no way to do this without root, but you can monitor when the next alarm is and when the value changes with the following value:

Settings.System.getUriFor(Settings.System.NEXT_ALARM_FORMATTED).toString()

This will give you a string with the next alarm.

查看更多
登录 后发表回答