Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android5.0開發范例大全 讀書筆記(六),android5.0范例

Android5.0開發范例大全 讀書筆記(六),android5.0范例

編輯:關於android開發

Android5.0開發范例大全 讀書筆記(六),android5.0范例


(六)與系統交互

6.1後台通知

1.關於後台通知,下面展示6種樣式。值得一提的是,筆者的小米5只能顯示基本樣式,雷軍真是良心廠商啊。

2.首先上布局xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
>

    <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/options_group">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Rich Styles"/>
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/option_basic"
            android:text="Basic Notification"
            android:checked="true"/>
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/option_bigtext"
            android:text="BigText Style"
            />
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/option_bigpicture"
            android:text="BigPicture Style"
            />
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/option_inbox"
            android:text="Inbox Style"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Secured Styles"/>
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/option_private"
            android:text="Public Version LockScreen" />
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/option_secret"
            android:text="Secret LockScreen" />
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/option_headsup"
            android:text="Heads-Up Notification" />
    </RadioGroup>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Post a Notification"
        android:onClick="onPostClick"/>
</LinearLayout>

3.接著是完整代碼

ublic class NotificationActivity extends AppCompatActivity {
    private RadioGroup mOptionsGroup;
    private static Handler mHandle = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);
        mOptionsGroup = (RadioGroup) findViewById(R.id.options_group);

    }

    public void onPostClick(View view) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        final int noteId = mOptionsGroup.getCheckedRadioButtonId();
        Notification note = null;
        switch (noteId) {
            case R.id.option_basic:
            case R.id.option_bigtext:
            case R.id.option_bigpicture:
            case R.id.option_inbox:
                note = buildStyledNotification(noteId);
                break;
            case R.id.option_private:
            case R.id.option_secret:
            case R.id.option_headsup:

                note = buildSecuredNotification(noteId);
                break;
        }
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(noteId, note);
    }

    private Notification buildStyledNotification(int type) {
        Intent launchIntent = new Intent(this, NotificationActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, launchIntent, 0);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(NotificationActivity.this);
        builder.setSmallIcon(R.mipmap.ic_launcher)
                .setTicker("something happen")
                .setWhen(System.currentTimeMillis())
                .setAutoCancel(true)
                .setDefaults(Notification.DEFAULT_SOUND)
                .setContentTitle("we are finished")
                .setContentText("click here")
                .setContentIntent(contentIntent);

        switch (type) {
            case R.id.option_basic:
                return builder.build();
            case R.id.option_bigtext:
                builder.addAction(android.R.drawable.ic_menu_call, "Call", contentIntent);
                builder.addAction(android.R.drawable.ic_menu_recent_history, "History", contentIntent);

                NotificationCompat.BigTextStyle textStyle = new NotificationCompat.BigTextStyle(builder);
                textStyle.bigText("BigText Mode");
                return textStyle.build();
            case R.id.option_bigpicture:
                builder.addAction(android.R.drawable.ic_menu_compass, "View Location", contentIntent);

                NotificationCompat.BigPictureStyle pictureStyle = new NotificationCompat.BigPictureStyle(builder);
                pictureStyle.bigPicture(BitmapFactory.decodeResource(getResources(), R.mipmap.cat));
                return pictureStyle.build();
            case R.id.option_inbox:
                NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(builder);
                inboxStyle.setSummaryText("4 new tasks")
                        .addLine("make dinner")
                        .addLine("call mom")
                        .addLine("call handsome")
                        .addLine("call father");
                return inboxStyle.build();
            default:
                throw new IllegalArgumentException("Unknown Type");
        }
    }

    private Notification buildSecuredNotification(int type) {
        Intent launchIntent = new Intent(this, NotificationActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, launchIntent, 0);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(NotificationActivity.this);
        builder.setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("account balance update")
                .setContentText("your account balance is -250")
                .setStyle(new NotificationCompat.BigTextStyle().bigText("Your account balance is-250 please pay"))
                .setContentIntent(contentIntent);


        switch (type) {
            case R.id.option_private:
                Notification publicNote = new Notification.Builder(this)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setContentTitle("Account Notification")
                        .setContentText("an important message")
                        .setContentIntent(contentIntent)
                        .build();
                return builder.setPublicVersion(publicNote).build();

            case R.id.option_secret:
                return builder.setVisibility(Notification.VISIBILITY_SECRET).build();
            case R.id.option_headsup:
                return builder.setDefaults(Notification.DEFAULT_SOUND)
                        .setPriority(Notification.PRIORITY_HIGH)
                        .build();
            default:
                throw new IllegalArgumentException("Unknown Type");
        }
    }
}

 6.3定時執行周期任務

1.AlarmManager用來管理和執行任務,可以在程序沒有運行的時候執行。並且有多種啟動和計算時間的方式

  定義一個廣播接收者,在其中附加需要執行的操作

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Calendar now=Calendar.getInstance();
        DateFormat format= SimpleDateFormat.getTimeInstance();
        Toast.makeText(context,format.format(now.getTime()),Toast.LENGTH_SHORT).show();
    }

}

  通過AlarmManager設置時間任務

public void start(View view) {
        Toast.makeText(this,"Scheduled",Toast.LENGTH_SHORT).show();
        manager.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()+ interval, interval,mAlarmIntent);

    }

  為了方便,下面寫出全部代碼

  其中start是間隔一段時間執行任務

  clock是在指定時間執行任務

public class AlarmActivity extends AppCompatActivity {
private PendingIntent mAlarmIntent;
    private AlarmManager manager;
    private long interval;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_timing);
        Intent launchIntent=new Intent(this,AlarmReceiver.class);
        mAlarmIntent=PendingIntent.getBroadcast(this,0,launchIntent,0);
        manager = (AlarmManager) getSystemService(ALARM_SERVICE);
        interval = 5*1000;
    }

    public void start(View view) {
        Toast.makeText(this,"Scheduled",Toast.LENGTH_SHORT).show();
        manager.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()+ interval, interval,mAlarmIntent);

    }

    public void stop(View view) {
        Toast.makeText(this,"Canceled",Toast.LENGTH_SHORT).show();
        manager.cancel(mAlarmIntent);
    }

    public void clock(View view) {
        long oneDay=24*3600*1000;
        long firstTime;
        Calendar startTime=Calendar.getInstance();
        startTime.set(Calendar.HOUR_OF_DAY,17);
        startTime.set(Calendar.MINUTE,18);
        startTime.set(Calendar.SECOND,0);
        Calendar now=Calendar.getInstance();
        if(now.before(startTime)){
            firstTime=startTime.getTimeInMillis();
            System.out.println(firstTime);
        }else {
            startTime.add(Calendar.DATE,1);
            firstTime=startTime.getTimeInMillis();
        }
        manager.setRepeating(AlarmManager.RTC_WAKEUP,firstTime,oneDay,mAlarmIntent);

    }
}

2.JobScheduler也可以實現類似的功能

   1.首先自定義一個service繼承自JobService

public class WorkService extends JobService

  在內部放一個handler來進行簡單的隊列處理

   private Handler mJobProcessor=new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            JobParameters parameters= (JobParameters) msg.obj;
            System.out.println(parameters.getJobId());
            doWork();
            jobFinished(parameters,false);
        return true;
        }
    });

  實現onStartJob()方法,

 @Override
    public boolean onStartJob(JobParameters params) {
        mJobProcessor.sendMessageDelayed(Message.obtain(mJobProcessor,MSG_JOB,params),7500);
        return true;
    }

  實現onStopJob()方法

 @Override
    public boolean onStopJob(JobParameters params) {
        mJobProcessor.removeMessages(MSG_JOB);
        return false;
    }

  實現具體處理任務的doWork()方法

 private void doWork() {
        Calendar now=Calendar.getInstance();
        DateFormat formatter= SimpleDateFormat.getTimeInstance();
        Toast.makeText(this,formatter.format(now.getTime()),Toast.LENGTH_SHORT).show();
    }

  2.在主函數中調用JobScheduler

public class JobSchedulerActivity extends AppCompatActivity {
    private static final int JOB_ID = 1;
    private JobScheduler scheduler;
    private JobInfo info;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_job_scheduler);
        scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
        long interval =  5 * 1000;
        info = new JobInfo.Builder(JOB_ID, new ComponentName(getPackageName(), WorkService.class.getName()))
                .setPeriodic(interval)
                .build();
    }

    public void start(View view) {

        int result = scheduler.schedule(info);
        if (result <= 0) {
            Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
        }
    }

    public void stop(View view) {
        scheduler.cancel(JOB_ID);
    }
}

6.4創建粘性操作

1.粘性操作是指當應用程序被用戶終止時也可以執行的一個或多個操作.

2.IntentService會將要執行的任務放到隊列中,然後逐個請求,全部處理完後終結自己

   以下是自定義IntentService的完整代碼

public class OperationsManager extends IntentService {
    public static final String ACTION_EVENT = "ACTION_EVENT";
    public static final String ACTION_WARNING = "ACTION_WARNING";
    public static final String ACTION_ERROR = "ACTION_ERROR";
    public static final String EXTRA_NAME = "eventName";

    private static final String LOGTAG = "com.joshua.log";
    private IntentFilter matcher;

    public OperationsManager() {
        super("OperationsManager");
        matcher = new IntentFilter();
        matcher.addAction(ACTION_EVENT);
        matcher.addAction(ACTION_WARNING);
        matcher.addAction(ACTION_ERROR);
    }


    @Override
    protected void onHandleIntent(Intent intent) {
        if (!matcher.matchAction(intent.getAction())) {
            Toast.makeText(this, "Invalid Request", Toast.LENGTH_SHORT).show();
        }
        switch (intent.getAction()) {
            case ACTION_EVENT:
                logEvent(intent.getStringExtra(EXTRA_NAME));
                break;
            case ACTION_WARNING:
                logWarning(intent.getStringExtra(EXTRA_NAME));
                break;
            case ACTION_ERROR:
                logError(intent.getStringExtra(EXTRA_NAME));
                break;
        }

    }

    private void logError(String name) {
        try {
            Thread.sleep(5000);
            Log.i(LOGTAG,name);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    private void logWarning(String name) {
        try {
            Thread.sleep(5000);
            Log.w(LOGTAG,name);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void logEvent(String name) {
        try {
            Thread.sleep(5000);
            Log.e(LOGTAG,name);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2.在activity中通過Intent調用IntentService

public class ReportActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_report);
        logEvent("CREATE");
    }

    @Override
    protected void onStart() {
        super.onStart();
        logEvent("START");
    }

    @Override
    protected void onResume() {
        super.onResume();
        logEvent("RESUME");
    }

    @Override
    protected void onPause() {
        super.onPause();
        logEvent("PAUSE");
    }

    @Override
    protected void onStop() {
        super.onStop();
        logEvent("STOP");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        logEvent("DESTROY");
    }

    private void logEvent(String event){
        Intent intent=new Intent(this,OperationsManager.class);
        intent.setAction(OperationsManager.ACTION_EVENT);
        intent.putExtra(OperationsManager.EXTRA_NAME,event);
        startService(intent);
    }

    private void logWarning(String event){
        Intent intent=new Intent(this,OperationsManager.class);
        intent.setAction(OperationsManager.ACTION_WARNING);
        intent.putExtra(OperationsManager.EXTRA_NAME,event);
        startService(intent);
    }
}

6.6分享內容

1.通過Intent啟動系統的其他相關程序

 public void share(View view) {
        Intent intent=new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.putExtra(Intent.EXTRA_TEXT,"分享");
        startActivity(Intent.createChooser(intent,"Share..."));
    }

6.10讀取設備媒體和文檔

1.通過Intent獲取感興趣的設備內容,比如image/video/audio

  不過筆者的小米5不管你調用的是什麼,它都給你彈出文件管理器的首頁……

intent = new Intent();
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){
            intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
        }else {
            intent.setAction(Intent.ACTION_GET_CONTENT);
        }
        intent.addCategory(Intent.CATEGORY_OPENABLE);

    }
    public void image(View view) {
       intent.setType("image/*");
        startActivityForResult(intent,REQUEST_IMAGE);
    }

    public void video(View view) {
        intent.setType("video/*");
        startActivityForResult(intent,REQUEST_VIDEO);
    }

    public void audio(View view) {
        intent.setType("audio/*");
        startActivityForResult(intent,REQUEST_AUDIO);
    }

6.16自定義任務棧

1.當程序A的A3界面被程序B的B3界面啟動後,按返回是返回B3還是A2呢?當然是B3啦,因為屬於程序A的任務棧並沒有被創建。

  因此如果想要返回A2,則必須啟動A的任務棧。

2.首先,創建一個根界面

public class RootActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_root);
    }

    public void next(View view) {
        Intent intent=new Intent(this,ItemsListActivity.class);
        startActivity(intent);
    }
}

3.接著,創建一個二級界面,其中重點是NavUtils的應用,可以創建任務棧

public class ItemsListActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
    private static final String[] ITEMS = {"Mon", "Dad", "Sister", "Brother", "Cousin"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_items_list);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        ListView list = new ListView(this);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, ITEMS);
        list.setAdapter(adapter);
        list.setOnItemClickListener(this);
        setContentView(list);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                Intent upIntent = NavUtils.getParentActivityIntent(this);
                if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
                    TaskStackBuilder.create(this)
                            .addParentStack(this)
                            .startActivities();
                } else {
                    NavUtils.navigateUpFromSameTask(this);
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Intent intent = new Intent(this, DetailsActivity.class);
        intent.putExtra(Intent.EXTRA_TEXT, ITEMS[position]);
        startActivity(intent);

    }
}

4.創建三級界面

public class DetailsActivity extends AppCompatActivity {
private static final String ACTION_NEW_ARRIVAL="com.examples.taskstack.ACTION_NEW_ARRIVAL";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        TextView textView=new TextView(this);
        textView.setGravity(Gravity.CENTER);
        String item=getIntent().getStringExtra(Intent.EXTRA_TEXT);
        textView.setText(item);
        setContentView(textView);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                Intent upIntent = NavUtils.getParentActivityIntent(this);
                if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
                    TaskStackBuilder.create(this)
                            .addParentStack(this)
                            .startActivities();
                } else {
                    NavUtils.navigateUpFromSameTask(this);
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

5.AndroidManifest中配置如下,為各級設置parent,其中4.1以後不需要使用meta-data

 <activity android:name=".day20161019.RootActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".day20161019.ItemsListActivity"
            android:parentActivityName=".day20161019.RootActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".day20161019.RootActivity" />
        </activity>
        <activity
            android:name=".day20161019.DetailsActivity"
            android:parentActivityName=".day20161019.ItemsListActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".day20161019.ItemsListActivity" />

            <intent-filter>
                <action android:name="com.examples.taskstack.ACTION_NEW_ARRIVAL" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

(七)總結

看過一個大神的博客,他說自己不覺得有多麼聰明,但別人總愛稱他是大神,可能只是因為自己在半年內看了50多本書吧,至於書該怎麼看,很簡單,敲一遍。

強,無敵。

於是閱讀《Android5.0開發范例大全》的時候,我也把部分代碼敲了一遍,很多時候怎麼看都看不懂的代碼,運行一下大多就能理解了。

不過因為個人水平太差,這文章寫出來估計沒幾個人能讀明白,實在汗顏。

接下來,我會開很多新書,繼續寫讀書筆記這個系列。

希望能多多進步吧。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved