目錄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 |