Android: launch a custom Preference from a PreferenceActivity

前端 未结 4 853
逝去的感伤
逝去的感伤 2020-12-08 23:57

I would like to be able launch a 2nd Preference screen from my PreferenceActivity. And in the 2nd Preference screen I\'d like to use a predefined layout from xml. So, I ha

相关标签:
4条回答
  • 2020-12-09 00:03

    You might want something similar to what I did to upload a photo from the gallery or camera.

    package com.atClass.lmt;
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.preference.PreferenceActivity;
    import android.preference.Preference;
    import android.preference.Preference.OnPreferenceClickListener;
    import android.provider.MediaStore;
    import android.util.Log;
    
    
    public class Prefs extends PreferenceActivity{
        //public static final int FLAG_ACTIVITY_CLEAR_TOP = 1;
        private static final int MEDIA_IMAGE_REQUEST_CODE = 1;
        private static final int CAMERA_IMAGE_REQUEST_CODE = 2;
        public static Uri cImageUri;
    
        public static Context cContext;
        public static Activity cActivity;
    
        @Override
        protected void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.settings);
    
            this.cContext = (Context)this;
            this.cActivity = (Activity)this;
    
            Preference customPref = (Preference) findPreference("user_display_picture");
            customPref.setOnPreferenceClickListener(
                    new OnPreferenceClickListener() {
                        public boolean onPreferenceClick(Preference preference) {
                            return imageUploadDialog();
                        }
                    });
        }
    
        protected void onStop(){
            super.onStop();
            MapTools.createMapView(false);
            Lmt.serviceBinder.serviceThread("loginDevice");
        }
    
        public boolean imageUploadDialog(){
            final CharSequence[] items = {"Take picture now","Upload from gallery"};
            AlertDialog.Builder lAlertDialog = new AlertDialog.Builder(cContext);
            lAlertDialog.setTitle("Upload action");
            lAlertDialog.setCancelable(true);
            lAlertDialog.setItems(items,
                    new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialogInterface, int i){
                    //Toast.makeText(getApplicationContext(), "Selected item: " +i,  Toast.LENGTH_SHORT).show();
                    if (i == 0){
                        attachCameraImage();
                    }
                    if (i == 1){
                        attachGalleryImage();
                    }
                }
            });
            lAlertDialog.setIcon(R.drawable.click_to_url);
            lAlertDialog.show();
            return true;
        }
    
        public void attachGalleryImage(){
            Intent getImageFromGalleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
            startActivityForResult(getImageFromGalleryIntent, MEDIA_IMAGE_REQUEST_CODE);
        }
    
        public void attachCameraImage(){
            String fileName = "testphoto.jpg";
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.TITLE, fileName);
            values.put(MediaStore.Images.Media.DESCRIPTION,"Image capture by camera");
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
            cImageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, cImageUri);
            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
            startActivityForResult(intent, CAMERA_IMAGE_REQUEST_CODE);
        }
    
        protected final void onActivityResult(final int requestCode, final int resultCode, final Intent i) {
            Log.d(Global.TAG,"--> Received callback with:" + resultCode);
            super.onActivityResult(requestCode, resultCode, i);
            if(resultCode == RESULT_OK) {
                Log.d(Global.TAG,"--> Result OK with:" + requestCode);
                switch(requestCode) {
                case MEDIA_IMAGE_REQUEST_CODE:
                    Log.d(Global.TAG,"--> MEDIA_IMAGE_REQUEST_CODE");
                    Gui.GuiProgressDialog.showLoadingSpinner(cActivity);
                    cImageUri = i.getData();
                    if (cImageUri == null){Log.d(Global.TAG,"--> ImageURI is null!");}
                    Lmt.serviceBinder.serviceThread("uploadMemberPicture");
                    break;
                case CAMERA_IMAGE_REQUEST_CODE:
                    Log.d(Global.TAG,"--> CAMERA_IMAGE_REQUEST_CODE");
                    //cImageUri = i.getData();
                    if (cImageUri == null){Log.d(Global.TAG,"--> ImageURI is null!");}
                    Lmt.serviceBinder.serviceThread("uploadMemberPicture");
                    break;
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-09 00:05

    alibi's solution - of defining an intent within a <PreferenceScreen> entry - worked for me, after much trial-and-error of the targetPackage and targetClass fields.

    targetPackage needs to be the full path to the package name of my application (that is, the package= entry in the AndroidManifest.xml file). targetClass needs to be the full path to the Activity - INCLUDING the package name, even if the Activity is in the same package as the Application.

    The AndroidManifest.xml file for the Application also (of course) needs an entry for the Activity. I didn't define an <intent-filter> for this entry, presumably because the action is MAIN (this was true whether the Activity was in the same or a different package than the Application).

    Example: the Application's package is com.thissocialworld. The Activity I'd like to kick off from the PreferencesScreen is in a package called com.coolcommon and the Activity class is com.thissocialworld.SpecialPreferences. The entry within the <PreferenceScreen> looks like this:

    <intent android:action="android.intent.action.MAIN"
     android:targetPackage="com.thissocialworld"
     android:targetClass="com.thissocialworld.SpecialPreferences"/>
    

    I may try changing action.MAIN to action.PREFERENCES if it seems to be necessary to get access to the PreferencesManager.

    (PS my first post here, I couldn't figure out how to post this as a comment to the discussion started by alibi.)

    0 讨论(0)
  • 2020-12-09 00:09

    You can use a custom activity for this. Just design the activity and include it as a PreferenceScreen in your preferences.

    <PreferenceScreen  android:summary="@string/pref_summary" android:title="@string/title_summary">
      <intent android:action="android.intent.action.MAIN"
         android:targetPackage="targetPackage"
         android:targetClass="targetClass"/>
    </PreferenceScreen>
    

    Don't forget to register your activity in the manifest!

    0 讨论(0)
  • 2020-12-09 00:24

    One solution would be to extend a DialogPreference which allows the setting of a custom layout for the preference dialog. This way you have a preference listed and when you tap it, you get a dialog with your custom settings UI.

     <com.xyz.MyPreference 
               android:dialogLayout="@layout/yourlayout"
               android:dialogTitle="Dialog Title"
                android:dialogMessage="Dialog summary"
                android:key="preference_key"
                android:title="Preference Title"
                android:summary="Preference summary"
                android:defaultValue="Default Value" /> 
    

    And the class

    class MyPreference extends DialogPreference {
    // along with constructors, you will want to override
        @Override
        protected void onBindDialogView(View view) {
            super.onBindDialogView(view);
            // view is your layout expanded and added to the dialog
                // find and hang on to your views here, add click listeners etc
                // basically things you would do in onCreate
            mTextView = (TextView)view.findViewById(R.Id.mytextview);
            }
    
            @Override
            protected void onDialogClosed(boolean positiveResult) {
               super.onDialogClosed(positiveResult);
    
                if (positiveResult) {
                    // deal with persisting your values here
                }
            }
    }
    

    Obviously there are some other details, but this is the basic idea.

    0 讨论(0)
提交回复
热议问题