我从android开发者网站下载了调度程序示例。我有两个包一个包有三个类 com.example.android.scheduler ---- sampleSchedulerService和SampleAlarmReceiver以及SampleBootReceiver 另一个包是com.example1,有MainActivity类。
SampleSchedulerrService.java代码如下
package com.example.android.scheduler;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* This {@code IntentService} does the app's actual work.
* {@code SampleAlarmReceiver} (a {@code WakefulBroadcastReceiver}) holds a
* partial wake lock for this service while the service does its work. When the
* service is finished, it calls {@code completeWakefulIntent()} to release the
* wake lock.
*/
public class SampleSchedulingService extends IntentService {
public SampleSchedulingService() {
super("SchedulingService");
}
public static final String TAG = "Scheduling Demo";
// An ID used to post the notification.
public static final int NOTIFICATION_ID = 1;
// The string the app searches for in the Google home page content. If the app finds
// the string, it indicates the presence of a doodle.
public static final String SEARCH_STRING = "doodle";
// The Google home page URL from which the app fetches content.
// You can find a list of other Google domains with possible doodles here:
// http://en.wikipedia.org/wiki/List_of_Google_domains
public static final String URL = "http://www.google.com";
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
@Override
protected void onHandleIntent(Intent intent) {
Log.i("EFAIR","in onhandleintent");
// sendNotification(getString(R.string.doodle_found));
sendNotification(intent);
/*// BEGIN_INCLUDE(service_onhandle)
// The URL from which to fetch content.
String urlString = URL;
String result ="";
// Try to connect to the Google homepage and download content.
try {
result = loadFromNetwork(urlString);
} catch (IOException e) {
Log.i(TAG, getString(R.string.connection_error));
}
// If the app finds the string "doodle" in the Google home page content, it
// indicates the presence of a doodle. Post a "Doodle Alert" notification.
if (result.indexOf(SEARCH_STRING) != -1) {
sendNotification(getString(R.string.doodle_found));
Log.i(TAG, "Found doodle!!");
} else {
sendNotification(getString(R.string.no_doodle));
Log.i(TAG, "No doodle found. :-(");
}*/
// Release the wake lock provided by the BroadcastReceiver.
SampleAlarmReceiver.completeWakefulIntent(intent);
// END_INCLUDE(service_onhandle)
}
// Post a notification indicating whether a doodle was found.
private void sendNotification(Intent intent) {
String msg=intent.getStringExtra("MSG");
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
/* PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);*/
PendingIntent contentIntent = PendingIntent.getActivity(this,(int) Math.random(),
intent.setClass(this,MainActivity.class),PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(getString(R.string.doodle_alert))
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify((int) Math.random(), mBuilder.build());
}
//
// The methods below this line fetch content from the specified URL and return the
// content as a string.
//
/** Given a URL string, initiate a fetch operation. */
private String loadFromNetwork(String urlString) throws IOException {
InputStream stream = null;
String str ="";
try {
stream = downloadUrl(urlString);
str = readIt(stream);
} finally {
if (stream != null) {
stream.close();
}
}
return str;
}
/**
* Given a string representation of a URL, sets up a connection and gets
* an input stream.
* @param urlString A string representation of a URL.
* @return An InputStream retrieved from a successful HttpURLConnection.
* @throws IOException
*/
private InputStream downloadUrl(String urlString) throws IOException {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Start the query
conn.connect();
InputStream stream = conn.getInputStream();
return stream;
}
/**
* Reads an InputStream and converts it to a String.
* @param stream InputStream containing HTML from www.google.com.
* @return String version of InputStream.
* @throws IOException
*/
private String readIt(InputStream stream) throws IOException {
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
for(String line = reader.readLine(); line != null; line = reader.readLine())
builder.append(line);
reader.close();
return builder.toString();
}
}
SampleAlarmReceiver.java如下
package com.example.android.scheduler;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
import java.util.Calendar;
/**
* When the alarm fires, this WakefulBroadcastReceiver receives the broadcast Intent
* and then starts the IntentService {@code SampleSchedulingService} to do some work.
*/
public class SampleAlarmReceiver extends WakefulBroadcastReceiver {
// The app's AlarmManager, which provides access to the system alarm services.
private AlarmManager alarmMgr;
// The pending intent that is triggered when the alarm fires.
private PendingIntent alarmIntent;
public void onReceive(Context context, Intent intent) {
Log.i("EFAIR","in onReceive ");
// BEGIN_INCLUDE(alarm_onreceive)
/*
* If your receiver intent includes extras that need to be passed along to the
* service, use setComponent() to indicate that the service should handle the
* receiver's intent. For example:
*
* ComponentName comp = new ComponentName(context.getPackageName(),
* MyService.class.getName());
*
* // This intent passed in this call will include the wake lock extra as well as
* // the receiver intent contents.
* startWakefulService(context, (intent.setComponent(comp)));
*
* In this example, we simply create a new intent to deliver to the service.
* This intent holds an extra identifying the wake lock.
*/
ComponentName comp = new ComponentName("com.example.android.scheduler",
SampleSchedulingService.class.getName());
// This intent passed in this call will include the wake lock extra as well as
// the receiver intent contents.
startWakefulService(context, (intent.setComponent(comp)));
/*Intent service = new Intent(context, SampleSchedulingService.class);
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, service);*/
// END_INCLUDE(alarm_onreceive)
}
// BEGIN_INCLUDE(set_alarm)
/**
* Sets a repeating alarm that runs once a day at approximately 8:30 a.m. When the
* alarm fires, the app broadcasts an Intent to this WakefulBroadcastReceiver.
* @param context
*/
public void setAlarm(Context context,int day,int mongth,int year,int hour,int minute) {
Log.i("EFAIR","in set alarm"+minute);
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, SampleAlarmReceiver.class);
//put the massage
intent.putExtra("MSG","your schedule is going on......");
alarmIntent = PendingIntent.getBroadcast(context,hour+minute+day, intent,0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// Set the alarm's trigger time to 8:30 a.m.
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
//calendar.add
/*
* If you don't have precise time requirements, use an inexact repeating alarm
* the minimize the drain on the device battery.
*
* The call below specifies the alarm type, the trigger time, the interval at
* which the alarm is fired, and the alarm's associated PendingIntent.
* It uses the alarm type RTC_WAKEUP ("Real Time Clock" wake up), which wakes up
* the device and triggers the alarm according to the time of the device's clock.
*
* Alternatively, you can use the alarm type ELAPSED_REALTIME_WAKEUP to trigger
* an alarm based on how much time has elapsed since the device was booted. This
* is the preferred choice if your alarm is based on elapsed time--for example, if
* you simply want your alarm to fire every 60 minutes. You only need to use
* RTC_WAKEUP if you want your alarm to fire at a particular date/time. Remember
* that clock-based time may not translate well to other locales, and that your
* app's behavior could be affected by the user changing the device's time setting.
*
* Here are some examples of ELAPSED_REALTIME_WAKEUP:
*
* // Wake up the device to fire a one-time alarm in one minute.
* alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
* SystemClock.elapsedRealtime() +
* 60*1000, alarmIntent);
*
* // Wake up the device to fire the alarm in 30 minutes, and every 30 minutes
* // after that.
* alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
* AlarmManager.INTERVAL_HALF_HOUR,
* AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);
*/
// Set the alarm to fire at approximately 8:30 a.m., according to the device's
// clock, and to repeat once a day.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
// Enable {@code SampleBootReceiver} to automatically restart the alarm when the
// device is rebooted.
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
// END_INCLUDE(set_alarm)
/**
* Cancels the alarm.
* @param context
*/
// BEGIN_INCLUDE(cancel_alarm)
public void cancelAlarm(Context context) {
// If the alarm has been set, cancel it.
if (alarmMgr!= null) {
alarmMgr.cancel(alarmIntent);
}
// Disable {@code SampleBootReceiver} so that it doesn't automatically restart the
// alarm when the device is rebooted.
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
// END_INCLUDE(cancel_alarm)
}
and SamplebootReceiver.java
package com.example.android.scheduler;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
* This BroadcastReceiver automatically (re)starts the alarm when the device is
* rebooted. This receiver is set to be disabled (android:enabled="false") in the
* application's manifest file. When the user sets the alarm, the receiver is enabled.
* When the user cancels the alarm, the receiver is disabled, so that rebooting the
* device will not trigger this receiver.
*/
// BEGIN_INCLUDE(autostart)
public class SampleBootReceiver extends BroadcastReceiver {
SampleAlarmReceiver alarm = new SampleAlarmReceiver();
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
alarm.setAlarm(context,0,0,0,12,45);
}
}
}
//END_INCLUDE(autostart)
and MainActivity.java
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example1;
import com.example.android.scheduler.R;
import com.example.android.scheduler.SampleAlarmReceiver;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
/**
* This sample demonstrates how to schedule an alarm that causes a service to
* be started. This is useful when you want to schedule alarms that initiate
* long-running operations, such as retrieving a daily forecast.
* This particular sample retrieves content from the Google home page once a day and
* checks it for the search string "doodle". If it finds this string, that indicates
* that the page contains a custom doodle instead of the standard Google logo.
*/
public class MainActivity extends Activity {
SampleAlarmReceiver alarm = new SampleAlarmReceiver();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv=(TextView) findViewById(R.id.sample_output);
try{
String msg=getIntent().getStringExtra("MSG");
tv.setText(msg);
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
// Menu options to set and cancel the alarm.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// When the user clicks START ALARM, set the alarm.
case R.id.start_action:
alarm.setAlarm(getApplicationContext(),0,0,0,16,35);
return true;
case R.id.start_action1:
alarm.setAlarm(getApplicationContext(),0,0,0,16,37);
return true;
case R.id.start_action2:
alarm.setAlarm(getApplicationContext(),0,0,0,16,19);
return true;
case R.id.start_action3:
alarm.setAlarm(getApplicationContext(),0,0,0,16,21);
return true;
case R.id.start_action4:
alarm.setAlarm(getApplicationContext(),0,0,0,16,23);
return true;
case R.id.start_action5:
alarm.setAlarm(getApplicationContext(),0,0,0,16,25);
return true;
// When the user clicks CANCEL ALARM, cancel the alarm.
case R.id.cancel_action:
alarm.cancelAlarm(this);
return true;
}
return false;
}
}
当我将MainAcivity.java放在与SampleAlarmReceiver相同的包中时,它工作正常。否则不行。我的问题是,当我把MainActivity.java放在单独的包中然后它不工作。任何身体都可以帮助。
答案 0 :(得分:0)
替换下面的清单内容。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.scheduler"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:theme="@style/Theme.Sample">
<activity android:name="com.example1.MainActivity"
android:label="@string/app_name"
android:uiOptions="splitActionBarWhenNarrow">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.example.android.scheduler.SampleAlarmReceiver"></receiver>
<receiver android:name="com.example.android.scheduler.SampleBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
<service android:name="com.example.android.scheduler.SampleSchedulingService" />
</application>
答案 1 :(得分:0)
除非您将选项android:exported="false"
更改为true
或将其添加(如果不存在且您的minSdk高于16),即minSdk 17及更高版本,否则它们必须位于同一个包中在AndroidManifest.xml中
http://developer.android.com/guide/topics/manifest/provider-element.html
机器人:导出
内容提供商是否可供其他应用程序使用:
true:提供程序可供其他应用程序使用。任何应用程序都可以使用提供程序的内容URI来访问它,具体取决于为提供程序指定的权限。
false:提供程序不可用于其他应用程序。设置android:exported="false"
以限制对应用程序的提供程序的访问。只有与提供者具有相同用户ID(UID)的应用程序才能访问它。
对于将android:minSdkVersion或android:targetSdkVersion设置为&#34; 16&#34;的应用程序,默认值为"true"
。或更低。对于将这些属性中的任何一个设置为&#34; 17&#34;或更高,默认为&#34; false&#34;。
你可以设置android:exported =&#34; false&#34;并且仍然通过使用权限属性设置权限来限制对提供者的访问。