Android 在部分华为手机上出现乱码的问题

Android APP 在部分华为手机上出现了乱码问题,找了好久了终于找到原因了

前后台post请求体编码和解码时一致的 URL;UTF-8

但是还是出现了乱码,原因如下:

Content-Type:application/x-www-form-urlencoded; charset=UTF-8application/x-www-form-urlencoded; charset=utf-8


Content-Type:application/x-www-form-urlencoded含义是表示客户端提交给服务器文本内容的编码方式 是URL编码,

即除了标准字符外,每字节以双字节16进制前加个“%”表示,当然还有其他编码方式,如:CONTENT-TYPE:multipart/form-data 。


Content-Type 内容重复了,格式不对,服务器识别不了,所有当发送post请求时请求体里面有中文时服务器解码不正确,所以乱码了

具体问题如下(使用了Volley请求)

1.Volley post请求是请求头会自动加上content-type

详细代码如下:

public static RequestQueuenewRequestQueue(Context context, HttpStack stack) {

       File cacheDir = new File(context.getCacheDir(), "volley");

       String userAgent = "volley/0";

 

       try {

           String network = context.getPackageName();

           PackageInfo queue = context.getPackageManager().getPackageInfo(network,0);

           userAgent = network + "/" + queue.versionCode;

       } catch (NameNotFoundException var6) {

           ;

       }

 

       if(stack == null) {

           if(VERSION.SDK_INT>= 9) {

                stack = newHurlStack();

           } else {

                stack = newHttpClientStack(AndroidHttpClient.newInstance(userAgent));

           }

       }

 

       BasicNetwork network1 = new BasicNetwork((HttpStack)stack);

       RequestQueue queue1 = new RequestQueue(new DiskBasedCache(cacheDir),network1);

       queue1.start();

       return queue1;

}

 

HurlStack类中

publicHttpResponse performRequest(Request<?> request, Map<String, String>additionalHeaders) throws IOException, AuthFailureError {

        String url = request.getUrl();

        HashMap map = new HashMap();

        map.putAll(request.getHeaders());

        map.putAll(additionalHeaders);

        if(this.mUrlRewriter != null) {

            String parsedUrl =this.mUrlRewriter.rewriteUrl(url);

            if(parsedUrl == null) {

                throw new IOException("URLblocked by rewriter: " + url);

            }

 

            url = parsedUrl;

        }

 

        URL parsedUrl1 = new URL(url);

        HttpURLConnection connection =this.openConnection(parsedUrl1, request);

//volley使用的是HttpURLConnection

        Iterator responseCode =map.keySet().iterator();

 

        while(responseCode.hasNext()) {

            String protocolVersion =(String)responseCode.next();

           connection.addRequestProperty(protocolVersion,(String)map.get(protocolVersion));

        }

 

        setConnectionParametersForRequest(connection, request);//注意这个方法

        ProtocolVersion protocolVersion1 = newProtocolVersion("HTTP", 1, 1);

        int responseCode1 =connection.getResponseCode();

        if(responseCode1 == -1) {

            throw new IOException("Couldnot retrieve response code from HttpUrlConnection.");

        } else {

            BasicStatusLine responseStatus =new BasicStatusLine(protocolVersion1, connection.getResponseCode(),connection.getResponseMessage());

            BasicHttpResponse response = newBasicHttpResponse(responseStatus);

           response.setEntity(entityFromConnection(connection));

            Iterator var12 =connection.getHeaderFields().entrySet().iterator();

 

            while(var12.hasNext()) {

                Entry header =(Entry)var12.next();

                if(header.getKey() != null) {

                    BasicHeader h = newBasicHeader((String)header.getKey(), (String)((List)header.getValue()).get(0));

                    response.addHeader(h);

                }

            }

 

            return response;

        }

    }

 

下面的添加content-type请求头参数的方法

static voidsetConnectionParametersForRequest(HttpURLConnection connection,Request<?> request) throws IOException, AuthFailureError {

        switch(request.getMethod()) {

        case -1:

            byte[] postBody =request.getPostBody();

            if(postBody != null) {

                connection.setDoOutput(true);

                connection.setRequestMethod("POST");

               connection.addRequestProperty("Content-Type", request.getPostBodyContentType());

                DataOutputStream out = newDataOutputStream(connection.getOutputStream());

                out.write(postBody);

                out.close();

            }

            break;

        case 0:

            connection.setRequestMethod("GET");

            break;

        case 1:

            connection.setRequestMethod("POST");

            addBodyIfExists(connection,request);

            break;

        case 2:

           connection.setRequestMethod("PUT");

            addBodyIfExists(connection,request);

            break;

        case 3:

           connection.setRequestMethod("DELETE");

            break;

        default:

            throw newIllegalStateException("Unknown method type.");

        }

 

    }

 

private staticvoid addBodyIfExists(HttpURLConnection connection, Request<?> request)throws IOException, AuthFailureError {

        byte[] body = request.getBody();

        if(body != null) {

            connection.setDoOutput(true);

            connection.addRequestProperty("Content-Type",request.getBodyContentType());

            DataOutputStream out = newDataOutputStream(connection.getOutputStream());

            out.write(body);

            out.close();

        }

 

    }

默认的请求和自己设置为post请求都会添加一个content-type

protectedString getParamsEncoding() {

        return "UTF-8";

    }

 

    public String getBodyContentType() {

        return"application/x-www-form-urlencoded; charset=" +this.getParamsEncoding();

    }

content-type的值为application/x-www-form-urlencoded; charset=UTF-8

 

2.android 在部分华为手机上乱码

Volley VERSION.SDK_INT>= 9 时使用的是 HttpURLConnection

HttpURLConnection添加请求头参数的代码如下

public synchronized voidaddRequestProperty(String var1, String var2) {

       if(!this.connected && !this.connecting) {

           if(var1 == null) {

                throw newNullPointerException("key is null");

           } else {

               if(this.isExternalMessageHeaderAllowed(var1, var2)) {

                    this.requests.add(var1, var2);

                    if(!var1.equalsIgnoreCase("Content-Type")){

                       this.userHeaders.add(var1, var2);

                    }

                }

 

           }

       } else {

           throw new IllegalStateException("Already connected");

       }

}

// this.requests.add(var1, var2); 这段代码是加入content-type 的代码

private MessageHeader requests; //requests为MessageHeader 的实例

MessageHeader 是通过数组来存储key和value的

publicsynchronized void add(String var1, String var2) {

        this.grow();

        this.keys[this.nkeys] = var1;

        this.values[this.nkeys] = var2;

        ++this.nkeys;

    }

private voidgrow() {

        if(this.keys == null || this.nkeys>= this.keys.length) {

            String[] var1 = new String[this.nkeys + 4];

            String[] var2 = new String[this.nkeys + 4];

            if(this.keys != null) {

                System.arraycopy(this.keys, 0,var1, 0, this.nkeys);

            }

 

            if(this.values != null) {

                System.arraycopy(this.values,0, var2, 0, this.nkeys);

            }

 

            this.keys = var1;

            this.values = var2;

        }

    }

正常情况下加两次content-type 会在请求头里面重新两次content-type

如下:

Content-Type:application/x-www-form-urlencoded; charset=UTF-8

Content-Type: application/x-www-form-urlencoded;charset=utf-8

但是在部分华为手机上会奇葩的自动拼接到一起

Content-Type:application/x-www-form-urlencoded; charset=UTF-8application/x-www-form-urlencoded; charset=utf-8

看到上面的奇葩逗号没,格式不对了,服务器无法识别这种格式的请求体了编码方式了,最后出现乱码了。

 

具体是为什么Content-Type字段的值在部分华为的手机上为什么会拼接到一起,还没有找到原因,求大神们指导一下
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要启动华为手机上的AccessibilityService,需要进行以下步骤: 1. 在AndroidManifest.xml文件中添加AccessibilityService的声明。 ``` <service android:name=".MyAccessibilityService" android:label="@string/accessibility_service_label" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config" /> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> </service> ``` 2. 创建一个AccessibilityService的配置文件,命名为accessibility_service_config.xml,并将其放置在res/xml目录下。配置文件中设置你的AccessibilityService的一些属性。 例如: ``` <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeAllMask" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="true" android:description="@string/accessibility_service_description" android:notificationTimeout="100" android:packageNames="com.example.package1,com.example.package2" android:settingsActivity="com.example.package1.SettingsActivity" /> ``` 3. 在你的Activity中,使用Intent启动AccessibilityService。例如: ``` Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); startActivity(intent); ``` 这会打开系统的Accessibility Settings界面,用户可以在其中启用你的AccessibilityService。 请注意,不同的手机厂商可能会有不同的操作方式。以上步骤适用于一般的Android手机,如果你遇到了问题,可以查看华为手机的官方文档,或者在华为手机的开发者社区寻求帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值