Android: launch a custom Preference from a PreferenceActivity

守給你的承諾、 提交于 2019-11-28 06:35:43

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.

SR Austin

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.)

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;
            }
        }
    }
}

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!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!