目录html
第47章服务
服务(service)是一种Android组件。服务没有用户界面,而且在后台运行。它适用于长时间运行的操做。
47.1概览
1.服务和在其中声明服务的应用程序在相同的进程上运行,而且在应用程序的主线程上运行。
2.服务能够采起两种形式之一,它能够是启动的或绑定的。
若是一个组件启动了服务,它就是启动的。即使启动服务的组件已经再也不接受服务或者被销毁了,该服务还能够在后台无限期地运行。
若是应用程序组件绑定到服务,该服务就是绑定的。绑定的服务就像是客户端-服务器关系中的一台服务器,接受来自其余应用程序组件的请求,而且返回结果。
3.术语可访问性(accessibility),表示一个服务能够是私有的或公有的。公有的服务器能够由任何的应用程序调用,私有的服务器只可以由服务声明所在的相同的应用程序之中的组件来访问。
47.3声明服务
1.服务必须在清单中的
47.4服务示例
1.这个示例是一个Android应用程序,它容许你下载Web页面并将其离线存储,以便在不能链接到互联网的时候能够浏览它。这里有两个活动和一个服务。
2.代码清单47.1清单
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.urlservice" > <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ViewActivity" android:parentActivityName=".MainActivity" android:label="@string/title_activity_view" > </activity> <service android:name=".URLService" android:exported="true" /> </application> </manifest>
3.代码清单47.2主活动类android
package com.example.urlservice; import android.content.Intent; import android.os.Bundle; import android.os.StrictMode; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.EditText; import android.app.Activity; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_view) { Intent intent = new Intent(this, ViewActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); } public void fetchWebPages(View view) { EditText editText = (EditText) findViewById(R.id.urlsEditText); Intent intent = new Intent(this, URLService.class); intent.putExtra("urls", editText.getText().toString()); startService(intent); } }
4.代码清单47.3视图活动类git
package com.example.urlservice; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.webkit.WebView; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class ViewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view); Spinner spinner = (Spinner) findViewById(R.id.spinner); File saveDir = getFilesDir(); if (saveDir.exists()) { File dir = new File(saveDir, "URLService"); dir = saveDir; if (dir.exists()) { String[] files = dir.list(); ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, files); dataAdapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(dataAdapter); spinner.setOnItemSelectedListener( new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long id) { //open file Object itemAtPosition = adapterView .getItemAtPosition(pos); File file = new File(getFilesDir(), itemAtPosition.toString()); FileReader fileReader = null; BufferedReader bufferedReader = null; try { fileReader = new FileReader(file); bufferedReader = new BufferedReader(fileReader); StringBuilder sb = new StringBuilder(); String line = bufferedReader.readLine(); while (line != null) { sb.append(line); line = bufferedReader.readLine(); } WebView webView = (WebView) findViewById(R.id.webview); webView.loadData(sb.toString(), "text/html", "utf-8"); } catch (FileNotFoundException e) { } catch (IOException e) { } } @Override public void onNothingSelected(AdapterView<?> adapterView) { } }); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_view, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); return super.onOptionsItemSelected(item); } }
5.代码清单47.4服务类web
package com.example.urlservice; import android.app.IntentService; import android.content.Intent; import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.MalformedURLException; import java.net.URL; import java.util.StringTokenizer; public class URLService extends IntentService { public URLService() { super("URLService"); } @Override protected void onHandleIntent(Intent intent) { String urls = intent.getStringExtra("urls"); if (urls == null) { return; } StringTokenizer tokenizer = new StringTokenizer(urls); int tokenCount = tokenizer.countTokens(); int index = 0; String[] targets = new String[tokenCount]; while (tokenizer.hasMoreTokens()) { targets[index++] = tokenizer.nextToken(); } File saveDir = getFilesDir(); fetchPagesAndSave(saveDir, targets); } private void fetchPagesAndSave(File saveDir, String[] targets) { for (String target : targets) { URL url = null; try { url = new URL(target); } catch (MalformedURLException e) { e.printStackTrace(); } String fileName = target.replaceAll("/", "-") .replaceAll(":", "-"); File file = new File(saveDir, fileName); PrintWriter writer = null; BufferedReader reader = null; try { writer = new PrintWriter(file); reader = new BufferedReader( new InputStreamReader(url.openStream())); String line; while ((line = reader.readLine()) != null) { writer.write(line); } } catch (Exception e) { } finally { if (writer != null) { try { writer.close(); } catch (Exception e) { } } if (reader != null) { try { reader.close(); } catch (Exception e) { } } } } } }
47.5本章小结
服务是一个在后台运行的应用程序组件。尽管服务器是在后台运行的,但它并非一个进程,不会在一个单独线程上运行。相反,服务和调用该服务的应用程序的主线程上运行。
能够经过扩展android.app.Service或android.app.IntentService类来编写一个程序。sql
第48章广播接收器
Android系统老是会将在操做系统和应用程序运行期间发生的意图进行广播。此外,应用程序也能够广播用户定义的意图,能够经过在应用程序中编写广播接收器来利用这些广播。
48.1概览
广播接收器是一个应用程序组件,它监听一个特定意图广播,相似于监听事件的Java监听器。
48.2基于时钟的广播接收器
1.代码清单48.1MainActivity类数据库
package com.example.broadcastreceiverdemo1; import java.util.Calendar; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.text.format.DateFormat; import android.util.Log; import android.view.Menu; import android.widget.TextView; public class MainActivity extends Activity { BroadcastReceiver receiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onResume() { super.onResume(); setTime(); receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { setTime(); } }; IntentFilter intentFilter = new IntentFilter( Intent.ACTION_TIME_TICK); this.registerReceiver(receiver, intentFilter); } public void onPause() { this.unregisterReceiver(receiver); super.onPause(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } private void setTime() { Calendar calendar = Calendar.getInstance(); CharSequence newTime = DateFormat.format( "kk:mm", calendar); TextView textView = (TextView) findViewById( R.id.textView1); textView.setText(newTime); } }
48.3取消通知
1.代码清单48.2主活动的布局文件编程
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="setNotification" android:text="Set Notification" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="clearNotification" android:text="Clear Notification" /> </LinearLayout>
2.代码清单48.3MainActivity类android-studio
package com.example.cancelnotificationdemo; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.Menu; import android.view.View; public class MainActivity extends Activity { private static final String CANCEL_NOTIFICATION_ACTION = "cancel_notification"; int notificationId = 1002; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { NotificationManager notificationManager = (NotificationManager) getSystemService( NOTIFICATION_SERVICE); notificationManager.cancel(notificationId); } }; IntentFilter filter = new IntentFilter(); filter.addAction(CANCEL_NOTIFICATION_ACTION); this.registerReceiver(receiver, filter); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } public void setNotification(View view) { Intent cancelIntent = new Intent("cancel_notification"); PendingIntent cancelPendingIntent = PendingIntent.getBroadcast(this, 100, cancelIntent, 0); Notification notification = new Notification.Builder(this) .setContentTitle("Stop Press") .setContentText( "Everyone gets extra vacation week!") .setSmallIcon(android.R.drawable.star_on) .setAutoCancel(true) .addAction(android.R.drawable.btn_dialog, "Dismiss", cancelPendingIntent) .build(); NotificationManager notificationManager = (NotificationManager) getSystemService( NOTIFICATION_SERVICE); notificationManager.notify(notificationId, notification); } public void clearNotification(View view) { NotificationManager notificationManager = (NotificationManager) getSystemService( NOTIFICATION_SERVICE); notificationManager.cancel(notificationId); } }
48.4本章小结
广播接收器是监听意图广播的一个应用程序组件。要建立一个接收器,必须建立一个类来扩展android.content.BroadcastReceiver并实现其onReceive方法。要建立一个接收器,能够在应用程序的清单文件中添加一个receiver元素,或者经过调用Context.registerReceiver()编程来作到这一点。在任何状况下,都必须定义一个IntentFilter,它指定了哪一个意图致使该接收器被触发。服务器
第49章闹钟服务
49.2示例
1.代码清单49.1清单
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.alarmmanagerdemo1" > <uses-permission android:name="android.permission.WAKE_LOCK"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".WakeUpActivity" android:label="@string/title_activity_wake_up" > </activity> </application> </manifest>
2.代码清单49.2主活动的布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="5 Minute Alarm" android:id="@+id/button" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginTop="77dp" android:onClick="setAlarm"/> </RelativeLayout>
3.代码清单49.3 MainActivity类
package com.example.alarmmanagerdemo1; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Toast; import java.util.Calendar; import java.util.Date; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } public void setAlarm(View view) { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MINUTE, 5); Date fiveMinutesLater = calendar.getTime(); Toast.makeText(this, "The alarm will set off at " + fiveMinutesLater, Toast.LENGTH_LONG).show(); AlarmManager alarmMgr = (AlarmManager) getSystemService( Context.ALARM_SERVICE); Intent intent = new Intent(this, WakeUpActivity.class); PendingIntent sender = PendingIntent.getActivity( this, 0, intent, 0); alarmMgr.set(AlarmManager.RTC_WAKEUP, fiveMinutesLater.getTime(), sender); } }
4.代码清单49.4WakeUpActivity类
package com.example.alarmmanagerdemo1; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.WindowManager; public class WakeUpActivity extends Activity { private final int NOTIFICATION_ID = 1004; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Window window = getWindow(); Log.d("wakeup", "called. oncreate"); window.addFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); setContentView(R.layout.activity_wake_up); addNotification(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_wake_up, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } public void dismiss(View view) { NotificationManager notificationMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); notificationMgr.cancel(NOTIFICATION_ID); this.finish(); } private void addNotification() { NotificationManager notificationMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Notification notification = new Notification.Builder(this) .setContentTitle("Wake up") .setSmallIcon(android.R.drawable.star_on) .setAutoCancel(false) .build(); notification.defaults|= Notification.DEFAULT_SOUND; notification.defaults|= Notification.DEFAULT_LIGHTS; notification.defaults|= Notification.DEFAULT_VIBRATE; notification.flags |= Notification.FLAG_INSISTENT; notification.flags |= Notification.FLAG_AUTO_CANCEL; notificationMgr.notify(NOTIFICATION_ID, notification); } }
49.3本章小结
闹钟服务是Android开发者所可以使用的一项内建的服务。使用它,能够在随后调度一个操做。能够经过编程执行该操做,执行一次或重复地执行。
第50章内容提供者
内容提供者是用来封装要和其余应用程序共享的数据的一个Android组件。
50.1概览
1.要建立一个内容提供者,你须要扩展android.content.ContentProvider类,这个类提供CRUD方法,也就是用于建立、访问、更新和删除数据的方法。
2.内容提供者中的数据,经过一个独特的URI来引用。内容提供者的消费者,必须知道这个URL,才可以访问内容提供者的数据。
50.2ContentProvider类
50.2.1query方法(访问底层的数据)
50.2.2insert方法(添加一个数据项)
50.2.3update方法(能够使用u方法来更新一个数据项或一组数据项)
50.2.4delete方法(删除一个数据项或一组数据项)
50.3 建立一个内容提供者
1.代码清单50.1ContentProviderDemo1的清单
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.contentproviderdemo1" > <permission android:name="com.example.permission.READ_ELECTRIC_CARS" android:protectionLevel="normal"/> <permission android:name="com.example.permission.WRITE_ELECTRIC_CARS" android:protectionLevel="normal"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".activity.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".activity.AddElectricCarActivity" android:parentActivityName=".activity.MainActivity" android:label="@string/app_name" > </activity> <activity android:name=".activity.ShowElectricCarActivity" android:parentActivityName=".activity.MainActivity" android:label="@string/app_name" > </activity> <provider android:name=".provider.ElectricCarContentProvider" android:authorities="com.example.contentproviderdemo1" android:enabled="true" android:exported="true" android:readPermission="com.example.permission.READ_ELECTRIC_CARS" android:writePermission="com.example.permission.WRITE_ELECTRIC_CARS"> </provider> </application> </manifest>
2.代码清单50.2 内容提供者
package com.example.contentproviderdemo1.provider; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.util.Log; public class ElectricCarContentProvider extends ContentProvider { public static final Uri CONTENT_URI = Uri.parse("content://com.example.contentproviderdemo1" + "/electric_cars"); public ElectricCarContentProvider() { } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { String id = uri.getPathSegments().get(1); return dbMgr.deleteElectricCar(id); } @Override public String getType(Uri uri) { throw new UnsupportedOperationException("Not implemented"); } @Override public Uri insert(Uri uri, ContentValues values) { long id = getDatabaseManager().addElectricCar(values); return ContentUris.withAppendedId(CONTENT_URI, id); } @Override public boolean onCreate() { // initialize content provider on startup // for this example, nothing to do return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { if (uri.equals(CONTENT_URI)) { return getDatabaseManager() .getElectricCarsCursor(projection, selection, selectionArgs, sortOrder); } else { return null; } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { String id = uri.getPathSegments().get(1); Log.d("provider", "update in CP. uri:" + uri); DatabaseManager databaseManager = getDatabaseManager(); String make = values.getAsString("make"); String model = values.getAsString("model"); return databaseManager.updateElectricCar(id, make, model); } private DatabaseManager dbMgr; private DatabaseManager getDatabaseManager() { if (dbMgr == null) { dbMgr = new DatabaseManager(getContext()); } return dbMgr; }
3.代码清单50.3 数据库管理器
package com.example.contentproviderdemo1.provider; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class DatabaseManager extends SQLiteOpenHelper { public static final String TABLE_NAME = "electric_cars"; public static final String ID_FIELD = "_id"; public static final String MAKE_FIELD = "make"; public static final String MODEL_FIELD = "model"; public DatabaseManager(Context context) { super(context, /*db name=*/ "vehicles_db", /*cursorFactory=*/ null, /*db version=*/1); } @Override public void onCreate(SQLiteDatabase db) { String sql = "CREATE TABLE " + TABLE_NAME + " (" + ID_FIELD + " INTEGER, " + MAKE_FIELD + " TEXT," + MODEL_FIELD + " TEXT," + " PRIMARY KEY (" + ID_FIELD + "));"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); // re-create the table onCreate(db); } public long addElectricCar(ContentValues values) { Log.d("db", "addElectricCar"); SQLiteDatabase db = this.getWritableDatabase(); return db.insert(TABLE_NAME, null, values); } // Obtains single ElectricCar ContentValues getElectricCar(long id) { SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(TABLE_NAME, new String[] { ID_FIELD, MAKE_FIELD, MODEL_FIELD}, ID_FIELD + "=?", new String[] { String.valueOf(id) }, null, null, null, null); if (cursor != null) { cursor.moveToFirst(); ContentValues values = new ContentValues(); values.put("id", cursor.getLong(0)); values.put("make", cursor.getString(1)); values.put("model", cursor.getString(2)); return values; } return null; } public Cursor getElectricCarsCursor(String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = this.getReadableDatabase(); Log.d("provider:" , "projection:" + projection); Log.d("provider:" , "selection:" + selection); Log.d("provider:" , "selArgs:" + selectionArgs); return db.query(TABLE_NAME, projection, selection, selectionArgs, sortOrder, null, null, null); } public int updateElectricCar(String id, String make, String model) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(MAKE_FIELD, make); values.put(MODEL_FIELD, model); return db.update(TABLE_NAME, values, ID_FIELD + " = ?", new String[] { id }); } public int deleteElectricCar(String id) { SQLiteDatabase db = this.getWritableDatabase(); return db.delete(TABLE_NAME, ID_FIELD + " = ?", new String[] { id }); } }
4.代码清单50.4 Util类
package com.example.contentproviderdemo1; import android.net.Uri; public class Util { public static final Uri CONTENT_URI = Uri.parse("content://com.example.contentproviderdemo1" + "/electric_cars"); public static final String ID_FIELD = "_id"; public static final String MAKE_FIELD = "make"; public static final String MODEL_FIELD = "model"; }
5.代码清单50.5 MainActivity类
package com.example.contentproviderdemo1.activity; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.CursorAdapter; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import com.example.contentproviderdemo1.R; import com.example.contentproviderdemo1.Util; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView listView = (ListView) findViewById( R.id.listView); Cursor cursor = getContentResolver().query( Util.CONTENT_URI, /*projection=*/ new String[] { Util.ID_FIELD, Util.MAKE_FIELD, Util.MODEL_FIELD}, /*selection=*/ null, /*selectionArgs=*/ null, /*sortOrder=*/ "make"); startManagingCursor(cursor); ListAdapter adapter = new SimpleCursorAdapter( this, android.R.layout.two_line_list_item, cursor, new String[] {Util.MAKE_FIELD, Util.MODEL_FIELD}, new int[] {android.R.id.text1, android.R.id.text2}, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); listView.setAdapter(adapter); listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); listView.setOnItemClickListener( new OnItemClickListener() { @Override public void onItemClick( AdapterView<?> adapterView, View view, int position, long id) { Intent intent = new Intent( getApplicationContext(), ShowElectricCarActivity.class); intent.putExtra("id", id); startActivity(intent); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_add: startActivity(new Intent(this, AddElectricCarActivity.class)); return true; default: return super.onOptionsItemSelected(item); } } }
6.代码清单50.6 AddElectricCarActivity类
package com.example.contentproviderdemo1.activity; import android.app.Activity; import android.content.ContentValues; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.widget.EditText; import com.example.contentproviderdemo1.provider.ElectricCarContentProvider; import com.example.contentproviderdemo1.R; public class AddElectricCarActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add_electric_car); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.add_electric_car, menu); return true; } public void cancel(View view) { finish(); } public void addElectricCar(View view) { String make = ((EditText) findViewById( R.id.make)).getText().toString(); String model = ((EditText) findViewById( R.id.model)).getText().toString(); ContentValues values = new ContentValues(); values.put("make", make); values.put("model", model); getContentResolver().insert( ElectricCarContentProvider.CONTENT_URI, values); finish(); } }
7.代码清单50.7 ShowElectricCarActivity类
package com.example.contentproviderdemo1.activity; import android.app.Activity; import android.content.ContentValues; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.widget.EditText; import com.example.contentproviderdemo1.provider.ElectricCarContentProvider; import com.example.contentproviderdemo1.R; public class AddElectricCarActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add_electric_car); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.add_electric_car, menu); return true; } public void cancel(View view) { finish(); } public void addElectricCar(View view) { String make = ((EditText) findViewById( R.id.make)).getText().toString(); String model = ((EditText) findViewById( R.id.model)).getText().toString(); ContentValues values = new ContentValues(); values.put("make", make); values.put("model", model); getContentResolver().insert( ElectricCarContentProvider.CONTENT_URI, values); finish(); } }
50.4消费内容提供者
ContentResolveDemo1项目展现了如何从不一样的应用程序访问一个内容提供者,从同一程序和从一个外部应用程序访问一个内容提供者惟一的区别在于,必须在外部应用程序的清单中,请求访问提供者的许可。
1.代码清单50.8ContentResolveDemo1的清单
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.contentresolverdemo1" > <uses-permission android:name="com.example.permission.READ_ELECTRIC_CARS"/> <uses-permission android:name="com.example.permission.WRITE_ELECTRIC_CARS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.contentresolverdemo1.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest
https://gitee.com/EvelynYang/twelfth_weeks
在新建的AndroidProjects文件夹中运行脚本,第六周及以前都是在IdeaProjects文件夹里运行。
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 1/3 | 18/38 | |
第三周 | 500/1000 | 1/4 | 38/76 | |
第四周 | 1000/2000 | 1/5 | 20/96 | |
第五周 | 1000/3000 | 1/6 | 25/121 | |
第六周 | 1000/4000 | 1/7 | 25/146 | |
第七周 | 1000/5000 | 1/8 | 25/171 | |
第八周 | 1000/6000 | 1/9 | 15/186 | |
第九周 | 1000/7000 | 1/10 | 20/206 | |
第十周 | 1000/8000 | 1/11 | 20/226 | |
第十一周 | 1000/9000 | 1/12 | 10/236 | |
第十二周 | 1000/10000 | 1/13 | 15/251 |