Android开机向导setupwizard,设置系统语言,WiFi向导

Posted Ansen360

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android开机向导setupwizard,设置系统语言,WiFi向导相关的知识,希望对你有一定的参考价值。

Android的框架设计有考虑到开机向导这一场景,因此我们实现开机向导参考Android的Provision.apk Provision: MSM8976/repo/packages/apps/Provision 它的主要作用是作为开机引导用户进行一些基本设置.在原生的 android 系统中,provision非常的简单,只有一个空白的 activity,这个主要就是留给 厂商自己定制开机向导(像 OPPO,VIVO,小米等厂商会让你登陆和注册其账号帐号,连接WiFi等),因此我们得理解Android的设计意图而进行定制.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tomorrow_p.setupwizard">
    <!--android:sharedUserId="android.uid.system"-->
    <original-package android:name="com.android.provision" />
    <!-- For miscellaneous settings -->
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <!--<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/setupwizard_AppTheme">
        <activity
            android:name=".DefaultActivity"
            android:excludeFromRecents="true">
            <intent-filter android:priority="1">
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.tomorrow_p.setupwizard.SimActivity">
            <intent-filter>
                <action android:name="com.android.provision.SimActivity"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>
        </activity>
        <activity android:name="com.tomorrow_p.setupwizard.OpenActivity">
            <intent-filter>
                <action android:name="com.android.provision.OpenActivity"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>
        </activity>
    </application>
</manifest>

1. DefaultActivity是原生系统Provision中唯一的activity;配置了category.HOME属性,category.HOME是桌面程序的标记(Launcher程序都会配置);priority=1,配置优先级,这样就会在系统的Launcher之前启动. 2. Provision中的关键代码:

// Add a persistent setting to allow other apps to know the device has been provisioned.
        Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);

        // remove this activity from the package manager.
        PackageManager pm = getPackageManager();
        ComponentName name = new ComponentName(this, WelcomeActivity.class);
        pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);


这里代码主要设置DEVICE_PROVISIONED标记同时禁止本身Activity组件的功能 API: void setComponentEnabledSetting (ComponentName componentName, int newState, int flags)  componentName:组件名称  newState:组件新的状态,可以设置三个值,分别是如下:  不可用状态:COMPONENT_ENABLED_STATE_DISABLED  可用状态:COMPONENT_ENABLED_STATE_ENABLED  默认状态:COMPONENT_ENABLED_STATE_DEFAULT  flags:行为标签,值可以是DONT_KILL_APP或者0. 0说明杀死包含该组件的app  主要代码: 以下代码有注释掉跳转到注册和登录账户模块以及调用系统的WiFi设置向导模块 同时需要配置系统签名以及系统应用标识

package com.tomorrow_p.setupwizard;

import android.content.ComponentName;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Locale;

public class DefaultActivity extends BaseActivity implements View.OnClickListener 

    private static final String[] PLANETS = new String[]"English", "简体中文", "繁体中文";
    private String mCurrentStatus = PLANETS[1];


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        getActionBar().hide();
        setContentView(R.layout.setupwizard_activity_default);
        WheelView mWheelView = (WheelView) findViewById(R.id.wheelview);
        mWheelView.setOffset(1);
        mWheelView.setSeletion(1);
        mWheelView.setItems(Arrays.asList(PLANETS));
        mWheelView.setOnWheelViewListener(new WheelView.OnWheelViewListener() 
            @Override
            public void onSelected(int selectedIndex, String item) 
                mCurrentStatus = item;
            
        );
        Button next = (Button) findViewById(R.id.next);
        next.setOnClickListener(this);
    

    @Override
    public void onClick(View view) 
        switch (mCurrentStatus) 
            case "English":
                updateLanguage(Locale.US);
                break;
            case "简体中文":
                updateLanguage(Locale.SIMPLIFIED_CHINESE);
                break;
            case "繁体中文":
                updateLanguage(Locale.TRADITIONAL_CHINESE);
                break;
        
//        startWifiActivity();
        startActivity(new Intent(this,SimActivity.class));
        finish();


    

    private void startWifiActivity() 
        Intent startActivity = new Intent();
        startActivity.setComponent(new ComponentName("com.android.settings", "com.android.settings.wifi.WifiSetupActivity"));
        startActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(startActivity);
    //        Intent intent = new Intent();
    //        intent.setAction("android.net.wifi.PICK_WIFI_NETWORK");
    //        intent.putExtra("extra_prefs_show_button_bar", true);
    //        intent.putExtra("extra_prefs_set_next_text", "完成");
    //        intent.putExtra("extra_prefs_set_back_text", "返回");
    //        intent.putExtra("wifi_enable_next_on_connect", true);
    //        startActivity(intent);
    

    private void updateLanguage(Locale locale) 
        try 
            Class classActivityManagerNative = Class.forName("android.app.ActivityManagerNative");
            Method getDefault = classActivityManagerNative.getDeclaredMethod("getDefault");
            // IActivityManager iActMag = ActivityManagerNative.getDefault();
            Object objIActivityManager = getDefault.invoke(classActivityManagerNative);

            Class classIActivityManager = Class.forName("android.app.IActivityManager");
            // Configuration config = iActMag.getConfiguration();
            Method getConfiguration = classIActivityManager.getDeclaredMethod("getConfiguration");
            Configuration config = (Configuration) getConfiguration.invoke(objIActivityManager);
            config.locale = locale;
            // 此处需要声明权限:android.permission.CHANGE_CONFIGURATION
            // 会重新调用 onCreate();
            Class[] clzParams = Configuration.class;
            Method updateConfiguration = classIActivityManager.getDeclaredMethod("updateConfiguration", clzParams);
            // iActMag.updateConfiguration(config);
            updateConfiguration.invoke(objIActivityManager, config);
         catch (Exception e) 
            e.printStackTrace();
        
    


package com.tomorrow_p.setupwizard;

import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;

public class OpenActivity extends BaseActivity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        getActionBar().hide();
        setContentView(R.layout.setupwizard_activity_open);
        Button user = (Button) findViewById(R.id.btn_user);
        user.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                init();
                finish();
            
        );
    

    private void init() 
        // Add a persistent setting to allow other apps to know the device has been provisioned.
        Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
//        Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);

        // remove this activity from the package manager.
        PackageManager pm = getPackageManager();
        ComponentName name = new ComponentName(this, DefaultActivity.class);
        pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
    


package com.tomorrow_p.setupwizard;

import android.app.ActionBar;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class SimActivity extends BaseActivity implements View.OnClickListener 

    private static final String TAG = "SimActivity";
    protected ActionBar mActionBar;
    protected static final String SHOW_SKIP = "show_skip";

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.setupwizard_activity_sim);
        initActionBar();
        Button mContinue = (Button) findViewById(R.id.btn_continue);
        Button mShutdown = (Button) findViewById(R.id.btn_shutdown);
        mShutdown.setOnClickListener(this);
        mContinue.setOnClickListener(this);

    

    private void initActionBar() 
        mActionBar = getActionBar();
        mActionBar.setElevation(0);
        mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
        View customView = LayoutInflater.from(this).inflate(R.layout.setupwizard_actionbar, null);
        TextView actionBarTitle = (TextView) customView.findViewById(R.id.title);
        customView.findViewById(R.id.iv_back).setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                Intent startActivity = new Intent();
                startActivity.setComponent(new ComponentName("com.android.settings", "com.android.settings.wifi.WifiSetupActivity"));
                startActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(startActivity);
                finish();
            
        );
        actionBarTitle.setText(getResources().getString(R.string.check_sim));
        mActionBar.setCustomView(customView, new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, android.app.ActionBar.LayoutParams.MATCH_PARENT));
    

    @Override
    public void onClick(View view) 
        switch (view.getId()) 
            case R.id.btn_continue:
                try 
                    Intent startActivity = new Intent("com.qucii.usercenter.register.RegCheckMobileActivity");
                    startActivity.putExtra(SHOW_SKIP, true);
                    startActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(startActivity);
                 catch (Exception e) 
                    Log.e(TAG, e.getMessage());
                    startActivity(new Intent(this, OpenActivity.class));
                
                finish();
                break;
            case R.id.btn_shutdown:
                try 
                    Intent shutdown = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
                    shutdown.putExtra("android.intent.action.EXTRA_KEY_CONFIRM", false);
                    shutdown.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(shutdown);
                 catch (Exception e) 
                    e.printStackTrace();
                
                break;
        
    


package com.tomorrow_p.setupwizard;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class WheelView extends ScrollView 
    public static final String TAG = WheelView.class.getSimpleName();

    public static class OnWheelViewListener 
        public void onSelected(int selectedIndex, String item) 
        
    


    private Context context;
//    private ScrollView scrollView;

    private LinearLayout views;

    public WheelView(Context context) 
        super(context);
        init(context);
    

    public WheelView(Context context, AttributeSet attrs) 
        super(context, attrs);
        init(context);
    

    public WheelView(Context context, AttributeSet attrs, int defStyle) 
        super(context, attrs, defStyle);
        init(context);
    

    //    String[] items;
    List<String> items;

    private List<String> getItems() 
        return items;
    

    public void setItems(List<String> list) 
        if (null == items) 
            items = new ArrayList<String>();
        
        items.clear();
        items.addAll(list);

        // 前面和后面补全
        for (int i = 0; i < offset; i++) 
            items.add(0, "");
            items.add("");
        

        initData();

    


    public static final int OFF_SET_DEFAULT = 1;
    int offset = OFF_SET_DEFAULT; // 偏移量(需要在最前面和最后面补全)

    public int getOffset() 
        return offset;
    

    public void setOffset(int offset) 
        this.offset = offset;
    

    int displayItemCount; // 每页显示的数量

    int selectedIndex = 1;


    private void init(Context context) 
        this.context = context;

//        scrollView = ((ScrollView)this.getParent());
//        Log.d(TAG, "scrollview: " + scrollView);
        Log.d(TAG, "parent: " + this.getParent());
//        this.setOrientation(VERTICAL);
        this.setVerticalScrollBarEnabled(false);

        views = new LinearLayout(context);
        views.setOrientation(LinearLayout.VERTICAL);
        this.addView(views);

        scrollerTask = new Runnable() 

            public void run() 

                int newY = getScrollY();
                if (initialY - newY == 0)  // stopped
                    final int remainder = initialY % itemHeight;
                    final int divided = initialY / itemHeight;
//                    Log.d(TAG, "initialY: " + initialY);
//                    Log.d(TAG, "remainder: " + remainder + ", divided: " + divided);
                    if (remainder == 0) 
                        selectedIndex = divided + offset;

                        onSeletedCallBack();
                     else 
                        if (remainder > itemHeight / 2) 
                            WheelView.this.post(new Runnable() 
                                @Override
                                public void run() 
                                    WheelView.this.smoothScrollTo(0, initialY - remainder + itemHeight);
                                    selectedIndex = divided + offset + 1;
                                    onSeletedCallBack();
                                
                            );
                         else 
                            WheelView.this.post(new Runnable() 
                                @Override
                                public void run() 
                                    WheelView.this.smoothScrollTo(0, initialY - remainder);
                                    selectedIndex = divided + offset;
                                    onSeletedCallBack();
                                
                            );
                        


                    


                 else 
                    initialY = getScrollY();
                    WheelView.this.postDelayed(scrollerTask, newCheck);
                
            
        ;


    

    int initialY;

    Runnable scrollerTask;
    int newCheck = 50;

    public void startScrollerTask() 

        initialY = getScrollY();
        this.postDelayed(scrollerTask, newCheck);
    

    private void initData() 
        displayItemCount = offset * 2 + 1;

        for (String item : items) 
            views.addView(createView(item));
        

        refreshItemView(0);
    

    int itemHeight = 0;

    private TextView createView(String item) 
        TextView tv = new TextView(context);
        tv.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        tv.setSingleLine(true);
        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
        tv.setText(item);
        tv.setGravity(Gravity.CENTER);
        int padding = dip2px(15);
        tv.setPadding(padding, padding, padding, padding);
        if (0 == itemHeight) 
            itemHeight = getViewMeasuredHeight(tv);
            Log.d(TAG, "itemHeight: " + itemHeight);
            views.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight * displayItemCount));
            LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.getLayoutParams();
            this.setLayoutParams(new LinearLayout.LayoutParams(lp.width, itemHeight * displayItemCount));
        
        return tv;
    


    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) 
        super.onScrollChanged(l, t, oldl, oldt);

//        Log.d(TAG, "l: " + l + ", t: " + t + ", oldl: " + oldl + ", oldt: " + oldt);

//        try 
//            Field field = ScrollView.class.getDeclaredField("mScroller");
//            field.setAccessible(true);
//            OverScroller mScroller = (OverScroller) field.get(this);
//
//
//            if(mScroller.isFinished())
//                Log.d(TAG, "isFinished...");
//            
//
//         catch (Exception e) 
//            e.printStackTrace();
//        


        refreshItemView(t);

        if (t > oldt) 
//            Log.d(TAG, "向下滚动");
            scrollDirection = SCROLL_DIRECTION_DOWN;
         else 
//            Log.d(TAG, "向上滚动");
            scrollDirection = SCROLL_DIRECTION_UP;

        


    

    private void refreshItemView(int y) 
        int position = y / itemHeight + offset;
        int remainder = y % itemHeight;
        int divided = y / itemHeight;

        if (remainder == 0) 
            position = divided + offset;
         else 
            if (remainder > itemHeight / 2) 
                position = divided + offset + 1;
            

//            if(remainder > itemHeight / 2)
//                if(scrollDirection == SCROLL_DIRECTION_DOWN)
//                    position = divided + offset;
//                    Log.d(TAG, ">down...position: " + position);
//                else if(scrollDirection == SCROLL_DIRECTION_UP)
//                    position = divided + offset + 1;
//                    Log.d(TAG, ">up...position: " + position);
//                
//            else
                position = y / itemHeight + offset;
//                if(scrollDirection == SCROLL_DIRECTION_DOWN)
//                    position = divided + offset;
//                    Log.d(TAG, "<down...position: " + position);
//                else if(scrollDirection == SCROLL_DIRECTION_UP)
//                    position = divided + offset + 1;
//                    Log.d(TAG, "<up...position: " + position);
//                
//            
//        

//        if(scrollDirection == SCROLL_DIRECTION_DOWN)
//            position = divided + offset;
//        else if(scrollDirection == SCROLL_DIRECTION_UP)
//            position = divided + offset + 1;
        

        int childSize = views.getChildCount();
        for (int i = 0; i < childSize; i++) 
            TextView itemView = (TextView) views.getChildAt(i);
            if (null == itemView) 
                return;
            
            if (position == i) 
                itemView.setTextColor(Color.parseColor("#0288ce"));
             else 
                itemView.setTextColor(Color.parseColor("#bbbbbb"));
            
        
    

    /**
     * 获取选中区域的边界
     */
    int[] selectedAreaBorder;

    private int[] obtainSelectedAreaBorder() 
        if (null == selectedAreaBorder) 
            selectedAreaBorder = new int[2];
            selectedAreaBorder[0] = itemHeight * offset;
            selectedAreaBorder[1] = itemHeight * (offset + 1);
        
        return selectedAreaBorder;
    


    private int scrollDirection = -1;
    private static final int SCROLL_DIRECTION_UP = 0;
    private static final int SCROLL_DIRECTION_DOWN = 1;

    Paint paint;
    int viewWidth;

    @Override
    public void setBackgroundDrawable(Drawable background) 

        if (viewWidth == 0) 
            viewWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();
            Log.d(TAG, "viewWidth: " + viewWidth);
        

        if (null == paint) 
            paint = new Paint();
            paint.setColor(Color.parseColor("#83cde6"));
            paint.setStrokeWidth(dip2px(1f));
        

        background = new Drawable() 
            @Override
            public void draw(Canvas canvas) 
                canvas.drawLine(viewWidth * 1 / 6, obtainSelectedAreaBorder()[0], viewWidth * 5 / 6, obtainSelectedAreaBorder()[0], paint);
                canvas.drawLine(viewWidth * 1 / 6, obtainSelectedAreaBorder()[1], viewWidth * 5 / 6, obtainSelectedAreaBorder()[1], paint);
            

            @Override
            public void setAlpha(int alpha) 

            

            @Override
            public void setColorFilter(ColorFilter cf) 

            

            @Override
            public int getOpacity() 
                return 0;
            
        ;


        super.setBackgroundDrawable(background);

    

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) 
        super.onSizeChanged(w, h, oldw, oldh);
        Log.d(TAG, "w: " + w + ", h: " + h + ", oldw: " + oldw + ", oldh: " + oldh);
        viewWidth = w;
        setBackgroundDrawable(null);
    

    /**
     * 选中回调
     */
    private void onSeletedCallBack() 
        if (null != onWheelViewListener) 
            onWheelViewListener.onSelected(selectedIndex, items.get(selectedIndex));
        

    

    public void setSeletion(int position) 
        final int p = position;
        selectedIndex = p + offset;
        this.post(new Runnable() 
            @Override
            public void run() 
                WheelView.this.smoothScrollTo(0, p * itemHeight);
            
        );

    

    public String getSeletedItem() 
        return items.get(selectedIndex);
    

    public int getSeletedIndex() 
        return selectedIndex - offset;
    


    @Override
    public void fling(int velocityY) 
        super.fling(velocityY / 3);
    

    @Override
    public boolean onTouchEvent(MotionEvent ev) 
        if (ev.getAction() == MotionEvent.ACTION_UP) 

            startScrollerTask();
        
        return super.onTouchEvent(ev);
    

    private OnWheelViewListener onWheelViewListener;

    public OnWheelViewListener getOnWheelViewListener() 
        return onWheelViewListener;
    

    public void setOnWheelViewListener(OnWheelViewListener onWheelViewListener) 
        this.onWheelViewListener = onWheelViewListener;
    

    private int dip2px(float dpValue) 
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    

    private int getViewMeasuredHeight(View view) 
        int width = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        view.measure(width, expandSpec);
        return view.getMeasuredHeight();
    



完整源码下载





以上是关于Android开机向导setupwizard,设置系统语言,WiFi向导的主要内容,如果未能解决你的问题,请参考以下文章

Android开机向导setupwizard,设置系统语言,WiFi向导

Android 开机动画结束后进入开机向导前黑屏

Android不显示开机向导和开机气泡

如何在 MSI 安装完成后运行脚本?使用 VS2010 + 安装向导创建的 MSI

急求大神!!索尼z3恢复出厂设置后开机向导卡在谷歌登录界面怎么办?

Android之手机向导以及设置中心模块的开发